研磨消息中间件kafka之消息持久化及副本
本文主要介绍Kafka的消息持久化策略及副本机制。
Kafka消息持久化策略
首先简要说明一下Kafka持久化消息的优点:
- Kafka通过消息持久化解耦了消息的生产者和消费者,这也是采用队列的优势,使得生产者和消费者均只需要关心自己的逻辑,而不需要直接感知到彼此的存在。
- Kafka支持对消费过的消息进行“消息重演(Message Replay)”,而重演的基础就是实现消息持久化。
Kafka为了保证消息落盘的实时,确保消息不丢失,没有采用直接写内存,等写满后一次性刷盘的策略,而是将数据立即写入文件系统的日志中,写入成功后才将结果返回给客户端告知客户端–消息已经成功写入。这么做的目的是,一方面实时地保存了数据,另一方面又减少了对内存的消耗,将内存空间尽量留给页缓存使用,从而提升了整体的性能。
Kafka的副本机制
Kafka为了实现服务高可靠,采用了多副本机制。这么做的目的是为了解决分布式系统都会面临的高可靠保证的问题。
如果只保留一份数据,如果该节点down机,则节点中保存的消息日志就会丢失,从而造成难以估计的问题。因此Kafka采用目前应用较为广泛的一种解决策略:即采用冗余机制,通俗的说就是 “不要把鸡蛋放在一个篮子里。”
Kafka的冗余机制简单地说就是将消息日志备份多份,而这些备份的日志在Kafka的概念中成为“副本(replica)”,之所以采用副本机制,核心的目的就是为了防止数据丢失。
对于副本,又有两个角色,分别为:leader replica(领导者副本) 、 follower replica(跟随者副本) 。
只有leader角色的副本才对外提供服务,即只有leader副本才能够响应客户端发送的消息写入即消息消费的请求。而follower副本不对客户端提供服务,它只能被动获取leader副本的数据,保持与leader的消息同步。
当出现leader副本所在的broker发生down机,Kafka会在剩余的副本中选举新的leader继续提供服务,这也是Kafka与其他消息队列,如:RocketMQ的不同之处,也是它设计的精要及难点。
Kafka的leader选举依赖zookeeper进行。
解析leader和follower
上文中我们提到Kafka的副本包括 leader副本和follower副本,与MySQL的主从机制不同,在Kafka的leader-follower体系中,同一时刻只有leader对外提供服务,follower只是起到冗余数据备份的作用,它与leader保持数据同步,并追随leader的状态进行自身状态的变更。
当leader节点出现down机,集群会发生新的leader选举过程,在剩余的follower节点中选举一个作为新的leader角色并对外提供服务,从而保证集群的高可用性。
注意 :Kafka能够保证对于同一个分区(Partition,关于Partition会在后面的文章中讲解)下的多个replica一定不会分配在同一台broker上,通过这个规则,Kafka保证副本是有效且可靠的,实现了将鸡蛋存放在多个篮子中的目的。原理如图: