Kafka Broker可靠性

Broker有3个配置参数会影响Kafka消息存储的可靠性。这3个参数可以应用在Broker级别,控制所有主题的行为,也可以应用在主题级别,用于控制个别主题的行为。

1.复制系数

主题级别的配置参数是replication.factor,而Broker级别可以通过default.replication.factor来配置自动创建的主题。即使在主题创建之后,也可以通过新增或移除副本来改变复制参数。

如果复制系数为N,那么在N-1个Broker失效的情况下,仍能从主题读取数据或者向主题写入数据。所以,更高的复制系数会带来更高的可用性、可靠性和更少的故障。但是,复制系数N需要至少N个Broker,而且会有N个数据副本,即会占用N倍的磁盘空间。在集群可用性和存储硬件成本之间做出权衡,一般设置复制系数为3。

副本的分布也很重要。默认情况下,Kafka会确保分区的每个副本放在不同的Broker上。但是,如果不同的Broker位于同一个机架,一旦机架的交换机发生故障,分区就会不可用,这时复制系数设置为多少都不管用。为了避免机架级故障,应该把Broker分布在多个不同的机架上,并使用broker.rack参数来为每个Broker分配所在机架的名字。如果配置了机架名字,Kafka会保证分区的副本被分配在多个机架的不同Broker上,从而获得更高的可用性。

2.不完全的leader选举

unclean.leader.election.enable只能在broker级别进行配置,默认值为true。

当一个分区leader不可用时,一个同步副本会被选为新leader。如果在选举过程中没有丢失数据,即生产者提交的数据同时存在于所有同步副本上,那么这个选举就是完全的。

但是如果在分区leader不可用时,其他副本都是不同步的,怎么办?考虑下边两个场景:

  • 分区有3个副本,其中两个跟随副本不可用(比如由2个Broker发生崩溃)。这个时候,如果生产者继续往leader写入数据,所有消息都会得到确认并提交。现在假设分区leader也不可用了,这个时候如果之前的一个跟随者重新启动,它就成为了分区的唯一不同步副本。
  • 分区有3个副本,因为网络问题导致两个跟随副本复制消息滞后,所以,尽管它们还在复制消息,但已经不同步的。leader作为唯一的同步副本继续接受消息。此时,如果leader变为不可用,另外两个副本就再也无法变成同步的了。

当出现以上两种情况时,我们面临两难的选择:

  • 如果不同步的副本不能被提升为新leader,那么分区在旧leader(最后一个同步副本)恢复之前是不可用的。有时候这种情况会持续数个小时,比如更换内存芯片。
  • 如果不同步的副本可以被提升为新leader,那么在这个副本变为不同步后写入旧leader的消息会全部丢失,导致数据不一致。假设在副本0和副本1不可用时,offset为100-200的数据被写入副本2(leader)。现在副本2变为不可用,而副本0重新变为可用。副本0只包含offset为0-100的消息,不包含100-200的消息。如果我们允许副本0成为新leader,生产者可以继续写入数据,消费者可以继续读数据。于是,新首领就有了offset为100-200的新消息。这样,部分消费者会读到offset为100-200的旧消息(副本2上的消息),部分消费者会读到offset为100-200的新消息(副本0上的消息),还有部分消费者会读到二者混和的消息(部分副本2的旧消息和部分副本0的新消息)。另外,副本2可能会重新变为可用的,并成为副本0的跟随者,此时,副本2会把比副本0旧的消息全部删除,而这些消息对于所有消费者来说都是不可用的。这样就会出现数据不一致和数据丢失的风险。

对数据一致性和数据质量要求很高的系统,可用把unclean.leader.election.enable设置为false,如银行系统处理支付流水时宁愿等待数小时也不能处理错误的数据。对可用性要求很高的系统里,比如实时分析系统,一般会启用不完全的leader选举。

3.最少同步副本

在主题级别和broker上,这个参数都是min.insync.replicas,这个参数指定了最少多少个同步副本收到消息,消息才是已提交状态。

如果要确保已提交的数据被写入不止一个副本,就需要把最少同步副本数量设置为大一点的值,对于一个包含3个副本的主题,如果min.insync.replicas设置为2,那么至少要存在2个同步副本才能向分区写入消息,否则生产者向broker发送消息,会收到NotEnoughReplicasException异常。当只剩一个同步副本时,消费者仍然可以继续读取已有的数据,但是生产者不能再向broker写入新数据,此时,Broker变为只读的了,这是为了避免发生不完全选举时数据的写入和读取发生非预期的行为。为了从只读状态中恢复,必须让两个不可用分区中的一个重新变成可用的(比如重新Broker,网络重新联通),并等待它变为同步的。

猜你喜欢

转载自blog.csdn.net/Wengzhengcun/article/details/83929778