Kafka高可用性原理

一、Kafka副本基本概念

Kafka通过多副本机制实现故障自动转移,Kafka副本一些基本概念:

  • 副本是针对分区而言的,即副本是分区的副本
  • 一个分区有一个 leader 副本,多个 follower 副本,只有 leader副本对外提供服务,follower 副本只负责数据同步
  • 分区所有副本统称 AR,ISR 指与 leader副本保持同步状态的副本集合
  • LEO标识每个分区最后一条消息的下一个位置,ISR中最小的LEO为 HW,俗称高水位,消费者只能拉取到 HW 之前的消息

生产者发出的一条消息首先会被写入分区的 leader 副本,等到所有的 follower 副本都同步完之后才会被认为已提交,并更新 HW, 进而才会被消费者消费到

二、副本数据一致性问题

数据在主从复制的过程中难免会遇到某一节点宕机的情况,如何确保在类似特殊情况下依旧保持各副本数据的一致性,是分布式系统必须要解决的问题。为了解决这一问题,Kafka引入了 Leader Epoch 的概念

leader epoch 代表 leader 的纪元信息,初始值为0,每当 leader 变更一次, leader epoch 的值就会加1,相当于为 leader 增设了一个版本号。 当某一节点从宕机状态恢复时,会去查找该节点当前 leader epoch 的 LEO 作为截断依据

具体的同步流程如下:

初始A为leader,A有2条消息 m1 和 m2;
B为 follower,B有1条消息m1

假设A、B同时宕机,然后B第一个恢复过来成为新的 leader
Kafka高可用性原理_第1张图片

三、Kafka和Zookeeper数据同步机制比较

Zookeeper 采用 ZAB 一致性协议,总的来讲就是“少数服从多数”,只要一半以上的数据同步成功即为同步成功

“少数服从多数”有一个很大的优势,系统的延迟取决于最快的几个节点。但是它所能容忍的失败 follower比较少(一半以下),因此生产环境下为了保证较高的容错率,必须要有大量副本,而大量副本在大数据量下会导致性能的急剧下降。因此“少数服从多数”模型通常会被用作共享集群配置(如 Zookeeper),而很少用于主流的数据存储

Kafka写入消息时只有等到所有 ISR 集合中的副本都确认收到后才能被认为已提交,这种方式会使所需要的副本总数变小,复制带来的集群开销降低。

此外,在数据恢复上,Kafka不需要宕机节点必须从本地数据日志中进行恢复,Kafka 的同步方式允许宕机副本重新加入 ISR 集合,但在进入 ISR 之前必须保证自己能够重新同步完 leader 中的所有数据

四、Kafka为什么不支持读写分离

前面提到了,Kafka采用了主写主读的方式,副本仅仅提供了数据容错功能,为什么 Kafka 不采用读写分离的方式呢

首先,主写从读存在2个很明显的缺点:

  1. 数据一致性问题。数据从主节点同步到从接到必然会有一个延时,在该时间段内如果去读从节点的数据,读到的值不是最新的,从而会产生数据不一致的问题
  2. 延时问题。数据从主节点同步到从节点必然存在延时的问题,对于延时敏感的应用而言,主写从读不太适用

读写分离的主要作用是分摊负载,而 Kafka 本身就能很好的做到负载均衡, Kafka 会自动将主从节点均匀的分布在 broker 上,因此 Kafka 可以通过主写主读实现主写从读实现不了的负载均衡

总的来说,Kafka 只支持主写主读有几个优点:

  1. 简化代码的实现逻辑,减少出错的可能
  2. 将负载均衡细化均摊,与主写从读相比,不仅负载效能更好,而且对用户可控
  3. 没有延时的影响
  4. 在副本稳定的情况下,不会出现数据不一致的情况

五、如何提高Kafka的可靠性

可以通过合理设置以下设置来提高Kafka的可靠性:

  • 副本数量:一般设置为3即可满足绝大多数场景的可靠性要求,对于可靠性要求极高的场景,可以适当增大这个值
  • acks:设置为-1保证数据 leader 和 follower 均同步完成并写入本地日志
  • retries:有些发送异常属于可重试异常,对于高可靠性场景,需要将该值设置为大于1
  • enable.auto.commit:默认为true自动提交位移,可能会造成重复消费和消息丢失。对于可靠性要求高的场景应该设置为手动提交
  • min.insync.replicas:指定ISR集合中的最小副本数,如果不满足条件就会抛出 NotEnoughReplicasException 或 NotEnoughReplicasAfterAppendException异常。在副本数为3时,可以设置该参数为2

你可能感兴趣的:(Kafka,kafka,java,分布式)