Kafka Replication

记录与翻译Kafka多副本的设计原理。

Kafka Replication

Kafka Replication

Kafka通过数据写入的多个副本来实现数据的持久化与高可用。

为了保证消息的成功投递,可以把消息投递的整个生命周期分为三部分:

生产消息:消息从Producer传递到Broker;

存储消息:消息写入到Broker的磁盘;

消费消息:消息从Broker传递到Comsumer。

存储消息是数据持久化范畴,而如何保证消息不丢是多副本设计的初衷。

设计目标

考虑到Kafka不同场景的应用,设计目标包括:

可配置的持久化策略:高吞吐量/低时延,低吞吐量/高时延(通过调整备份副本的个数);

自动的副本备份策略:自动调整备份,自动化的集群扩容能力。

强一致需要保证数据写入多个备份,从而导致写入时延的增加;弱一致不需要保证备份写入,会导致数据存在软状态,从而获得更好的性能。

解决问题

多副本场景下,存在两个关键问题:

副本分片策略:副本该如何保存与分配到不同的Broker;

消息广播策略:消息该如何广播到所有的副本。

Data Replication

多副本的数据复制可以分为同步复制异步复制

无论那种复制策略都需要考虑以下问题:

① 如何实现数据广播

② 如何权衡数据复制的份数

副本宕机的异常处理

副本宕机恢复数据的一致性如何保证。


常见的复制策略分为两种:主备复制选举复制

Primary-Backup Replication

主备复制的场景下,主节点在写入数据完成后会阻塞等待所有从节点的写入完成。

在从节点写入的过程中,如果发生故障(宕机、断网、超时)就需要主节点来协调管理可用的从节点列表

对于故障恢复后的从节点,需要从主节点拉取最新的数据才能重新加入集群。

如果副本数量为N,则主备策略最多可以容忍N-1个节点异常。

Quorum-Based Replication

选举复制的场景下,主节点在写入数据完成后会阻塞等待多数从节点的写入完成。

选举的特点在于不需要等待所有从节点的写入。

考虑到集群数量是预设的,由于半数以上的写入策略,从而最大的异常容忍度是可知的。

如果副本数量为2N+1,则选举策略最多可以容忍N个节点异常。


那么,两种策略如何权衡?

主要从时延性能可用性两方面考虑,

① 选举复制只需要写入大部分节点就可返回,因此选举复制的时延低;

② 主备复制可以容忍更多数量的异常节点;

③ 选举复制至少最多容忍半数的异常节点。

考虑到,副本数量会直接影响到磁盘的有效使用率,Kafka选择主备来尽量减少磁盘空间的浪费

Synchronous Replication

Kafka使用主备作为同步复制策略。

主节点维护一个同步副本的列表(In-Sync Replicas(ISR)),用于记录与主节点保持同步的从节点

为了维护多个副本的可用性,Kafka使用Zookeeper来保存Leader节点ISR


数据存储分为两部分:本地日志偏移量

其中,LEO(The Log End Offset)记录当前日志的最新偏移量,HW(High Watermark)记录最后一次Commited的偏移量。

LEO是用来标记日志同步的进度,而HW是用来标记Commited的进度。

Writes

Client通过Zookeeper获取目标分区最新的Leader节点。

1
2
3
       Zookeeper
/
Client ----> Broker-Partition(Leader) ----> Broker-Partition (Follower)

副本之间的通信采用Socket直连的方式来提高性能。

主节点在接收到数据后会优先写入本地磁盘(日志),然后同步写入多个副本。

主节点(Partition)的写入是有序的,但不同主节点之间写入的顺序是无序的。

消息的写入判断条件是ISR列表中所有从节点均写入完成

为了提高副本的写入效率,仅保证消息写入到副本节点的内存(不保证持久化到磁盘)。

通过提供可配置化的Flush策略来提供不同的应用场景:同步刷盘异步刷盘

Reads

读操作仅从Leader主节点读取数据,而主节点是根据Zookeeper来获取的。

Failure Scenarios

Follower Failure

从节点异常情况下,会被主节点从ISR列表中移除,直到从节点恢复。

从节点的恢复不仅需要机器恢复正常,也需要数据恢复到同步状态。

因此,ISR列表是Kafka实现主备自动切换的关键

Leader Failure

主节点异常的三种场景:

① 未写入本地日志(无影响);

② 写入本地日志,未写入从节点;

③ 写入本地日志,写入部分从节点;

由于第①种场景中没有持有化数据,因此不会存在主从切换数据不一致的问题。

为了实现主从切换后数据的一致性,被选举为Leader的节点一定拥有最新的数据,

Kafka的主备切换主节点的选举策略如下:

① Zookeeper中注册ISR信息,用来保证元数据的一致性;

② 基于Zookeeper的临时节点来选举主节点,用来保证Leader的唯一性;

③ 利用Zookeeper的Watcher功能实现自动的选举功能;

④ Leader需要保证ISR中节点的同步进度,即时移除超时等异常的从节点。

Asynchronous Replication

异步复制是数据写入主节点后直接返回给Client,通过异步的方式同步数据到从节点。

因此,异步复制不能保证数据的持久化,当发生主从切换时可能造成数据的不一致(重复消息、丢消息)。