Kafka为什么只让leader进行读写?

Kafka为什么只让leader进行读写?

[TOC]

因为数据一致性 ,kafka 是保存副本 leader读写,follower 只备份 而 zookeeper是 leader 读写,follower负责读

zookeeper 与kafka保持数据一致性的不同点

zookeeper

​ zookeeper使用了ZAB(Zookeeper Atomic Broadcast)协议,保证了leader,follower的一致性,leader 负责数据的读写,而follower只负责数据的读,如果follower遇到写操作,会提交到leader;

​ 当leader宕机的话,使用 Fast Leader Election 快速选举出新的leader,节点在一开始都处于选举阶段,只要有一个节点得到超半数节点的票数,它就可以当选准 leader。

​ 其客户端根据链接的follower不同,可能读取到不同的数据。这是由于副本没有完全同步,存在时间差的原因。由于follower分担了读取数据的压力,zookeeper只要保留全局leader即可,不再进行细分。

如下所示:leader==>读写,follower==>只负责读;

Zookeeper工作方式

  • Zookeeper集群包含一个1个Leader,多个Follower
  • 所有的Follower都可提供读服务
  • 所有的写操作都会被forward到Leader
  • Client与Server通过NIO通信
  • 全局串行化所有的写操作
  • 保证同一客户端的指令被FIFO执行
  • 保证消息通知的FIFO

kafka

​ kafka 不同,只有leader 负责读写,follower只负责备份,如果leader宕机的话,Kafaka动态维护了一个同步状态的副本的集合(a set of in-sync replicas),简称ISR,ISR中有f+1个节点,就可以允许在f个节点down掉的情况下不会丢失消息并正常提供服。ISR的成员是动态的,如果一个节点被淘汰了,当它重新达到“同步中”的状态时,他可以重新加入ISR。因此如果leader宕了,直接从ISR中选择一个follower就行。

​ kafka在引入Replication之后,同一个Partition可能会有多个Replica,而这时需要在这些Replication之间选出一个Leader,Producer和Consumer只与这个Leader交互,其它Replica作为Follower从Leader中复制数据。因为需要保证同一个Partition的多个Replica之间的数据一致性(其中一个宕机后其它Replica必须要能继续服务并且即不能造成数据重复也不能造成数据丢失)。如果没有一个Leader,所有Replica都可同时读/写数据,那就需要保证多个Replica之间互相(N×N条通路)同步数据,数据的一致性和有序性非常难保证,大大增加了Replication实现的复杂性,同时也增加了出现异常的几率。而引入Leader后,只有Leader负责数据读写,Follower只向Leader顺序Fetch数据(N条通路),系统更加简单且高效。

Kafka:由于kafka的使用场景决定,其读取数据时更关注数据的一致性
​ 从leader读取和写入可以保证所有客户端都得到相同的数据,否则可能存在一些在ISR中注册的节点(replication-factor大于min.insync.replicas),因未来得及更新副本而无法提供的数据。相应的为了规避都从leader上读取带来的资源竞争,可以根据不同topic和不同partition设置不同的leader。

​ 如下所示:leader==>负责读写,follower 负责同步,只负责备份

Zab协议-广播模式

​ 客户端每发送一个更新请求,ZooKeeper都会生成一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序,这个唯一编号就是事务ID(ZXID),只有更新请求才算是事务请求。
为保证按照事务的ZXID先后顺序来处理,Leader服务器会分别为每个Follower服务器创建一个队列,并将事务的先后顺序放入队列中,并按照FIFO的策略进行消息发送。收到需要处理的事务后,Follower服务器会首先以事务日志的形式写入服务器的磁盘中,写入成功后会向Leader服务器发送ACK响应。当Leader服务器收到超过一半的Follower服务器的ACK响应后,会向所有Follower服务器广播Commit消息,收到Commit消息的Follower服务器也会完成对事务的提交。
如果接收到事务请求的是Follower服务器,它会将请求转发给Leader服务器处理。

相同点:

​ 在数据写入过程中,leader与follower都具有相同的先后关系,即数据先写入leader,而后按照一定的规则完成在follower上的最少副本数写入,即可返回调用客户端,该数据写入成功过。
kafka的最少副本数量有min.insync.replicas控制;zookeeper的最少副本数是半数以上节点。
此处的设置都是优先保证可用性,而牺牲一定的数据一致性。

具体的Kafka的leader选举机制

总结如下

所以设计目的为

1、数据一致性
2、高可用,副本