简历写了会Kafka,面试官90%会让你讲acks参数对消息持久化的影响

永盈会yyh88

写在前面

谈谈acks参数对消息持久性的影响?

这个acks参数是使用kafka时非常核心和关键的参数,它决定了很多东西。

因此无论是面试还是实际项目,都值得查看Kafka的acks参数及其背后原理的分析。

(1)如何确保机器停机时数据不会丢失?

如果您想了解此acks参数的含义,您必须首先了解kafka的高可用性体系结构。

例如,下图显示对于每个主题,我们可以将其设置为包含多个分区,每个分区负责存储此主题部分的数据。

然后是Kafka的Broker集群,每台机器都存储一些Partition,它还存储了Topic数据的一部分,从而在Broker集群上实现了Topic数据分布式存储。

f7d07b4f59fc47098e12e575710f9471

但有一个问题。如果Kafka Broker出现故障,那么存储在其上的数据是否会丢失?

没错,这是一个大问题。分布式系统的数据丢失问题是他必须解决的第一件事。一旦任何机器停机,将导致数据丢失。

(2)多重冗余副本的高可用性机制

所以如果你分析任何分布式系统的原理,比如zookeeper,kafka,redis集群,elasticsearch,hdfs等,实际上,他有自己的内部多拷贝冗余机制,多拷贝几乎冗余它是一个函数这是任何优秀的分布式系统通常都需要的。

在kafka集群中,每个分区都有多个副本,其中一个称为领导者,另一个称为跟随者,如下所示。

581e4fd99cf047368bd1b57af5eb18f7

如上图所示,假设主题分为三个分区,Partition0,Partiton1和Partition2。此时,每个分区都有两个副本。

例如,Partition0有一个Leader副本,另一个副本是Follower,Leader和Follower分布在不同的机器上。

这种多拷贝冗余机制可以保证任何一台机器都可以挂起而不会导致数据完全丢失,因为至少在另一台机器上仍然存在副本。

(3)如何在多个副本之间同步数据?

然后我们来看看如何在多个副本之间同步数据。事实上,任何Partition,只有Leader提供外部阅读和写作服务

也就是说,如果有客户端将数据写入分区,则通常是分区的写入副本。

在Leader副本收到数据后,Follower副本将继续向他发送请求以尝试提取最新数据,将其拉到本地,然后写入磁盘。如下图所示:

bf118eb507fd4c7d8a422e159788c31c

(4)ISR究竟是什么意思?

现在您已了解Partiton的多副本同步数据的机制,您可以看到ISR是什么。

ISR的全名是“In-Sync Replicas”,它是一个保持同步的副本。他的意思是追随者始终与领导同步。

你可以考虑一下。如果一个拥有追随者的经纪人遇到像JVM FullGC这样的问题,并且无法及时从领导者那里获取同步数据,那么追随者的数据是否远远落后于领导者?

所以这一次,这意味着追随者不再与领导者同步。但只要Follower保持与Leader同步数据,就可以保证它们处于同步关系中。

所以每个分区都有一个ISR。此ISR中必须有一个Leader,因为Leader确定数据是最新的,然后与Leader同步的Followers也在ISR中。

(5)acks参数的含义

在布置了这么多东西之后,我终于可以进入主题来谈谈acks参数的含义。

如果您不了解以前的复制机制,同步机制和ISR机制,则无法完全理解acks参数的含义。这个参数实际上决定了很多重要的事情。

首先,acks参数在KafkaProducer中设置,它是生产者客户端。

换句话说,当您向kafka写入数据时,可以设置此acks参数。那么这个参数实际上有三个可以设置的常用值:0,1和all。

即使分区领导在磁盘上,数据是否在磁盘上,我也不关心他,我认为消息发送成功。

如果您使用此设置,则必须注意您可能发送的消息仍然是中途。结果,分区消息丢失。

d60d17229990432c9cdb76f9fa35fea7

第二个选项是设置acks=1,这意味着只要分区消息。

此设置实际上是kafka的默认设置,请关注它!这是默认设置

换句话说,默认情况下,如果您不关心acks参数,只要分区领导者成功写入,它就会成功。

但是这里存在一个问题,如果分区消息丢失,因为客户端已经认为传输成功了。

5197472c40a34ee2b0274b251b1d2a1f

最后一种情况是设置acks=all,这意味着成功写入了分区消息。

如果分区领导刚刚收到消息,但是跟随者没有收到消息,那么领导者崩溃了,那么客户端会发现消息没有成功发送,他会再次尝试发送消息。

此时,分区2的追随者可能成为领导者。此时,只有最新的Follower被转换为ISR列表中的Leader,因此只要新Leader收到消息,就会成功。

f1338deeced54b6fa23a834555d8aa25

(6)最后的想法

acks=all表示数据不会丢失吗?

当然不是。如果你的分区只有一个副本,一个是领导者而没有追随者,你认为acks=all是有用的吗?

当然它没用,因为ISR中有一个领导者,当他收到消息时,他也会丢失数据。

因此,这个acks=all必须与至少2个ISR列表副本一起使用,至少与领导者和追随者一起使用。

过去,必须在收到超过2份副本后才能收到数据。此时,机器的任何副本都不会导致数据丢失。

所以我希望每个人都能很好地理解这篇文章,这对每个人出去接受采访或在工作中使用kafka都是一个很好的帮助。