这里写目录标题
一、基本概念
1. 主题 Topic
主题是一个逻辑上的概念,类似于文件系统中的一个文件夹,而消息就是该文件夹中的文件。一个主题可以有零、一个或多个生产者向其写入消息,也可以有零、一个或多个消费者订阅这些消息。主题中的消息可以根据需要随时读取 (与传统的消息传递系统不同,消息在使用后不会被删除。相反,你定义Kafka应该保留多长时间。)
2. 分区 Partition
主题是分区的,它还可以细分为多个分区,一个分区只属于单个主题;也就是说一个主题分布在位于不同Kafka代理上的许多“broker”上。数据的这种分布式放置允许客户机应用程序同时从多个代理读取和写入数据。当新消息发布到主题时,它实际上被附加到主题的一个分区中。具有相同消息键(例如,客户或车辆ID)的消息被写入相同的分区,Kafka保证给定主题分区的任何消费者都将始终读取该分区的消息。
如上图:主题有四个分区P1-P4。两个不同的生产者客户端通过网络将消息写入主题的分区,彼此独立地向主题发布新消息。具有相同键(在图中用颜色表示)的消息被写入相同的分区。注意,如果合适的话,两个生产者都可以写入同一个分区。
如上图:主题中有 4 个分区,消息被顺序追加到每个分区日志文件的尾部。Kafka中的分区可以分布在不同的服务器(broker)上,也就是说,一个主题可以横跨多个broker,以此来提供比单个broker更强大的性能。
每一条消息被发送到broker之前,会根据分区规则选择存储到哪个具体的分区。如果分区规则设定得合理,所有的消息都可以均匀地分配到不同的分区中。如果一个主题只对应一个文件,那么这个文件所在的机器 I/O 将会成为这个主题的性能瓶颈,而分区解决了这个问题。在创建主题的时候可以通过指定的参数来设置分区的个数,当然也可以在主题创建完成之后去修改分区的数量,通过增加分区的数量可以实现水平扩展。
3. 多副本 Replica
通过增加副本数量可以提升容灾能力。同一分区的不同副本中保存的是相同的消息(在同一时刻,副本之间并非完全一样),副本之间是“一主多从”的关系,其中leader副本负责处理读写请求,follower副本只负责与leader副本的消息同步。副本处于不同的broker中,当leader副本出现故障时,从follower副本中重新选举新的leader副本对外提供服务。Kafka通过多副本机制实现了故障的自动转移,当Kafka集群中某个broker失效时仍然能保证服务可用。
如上图:Kafka集群中有4个broker,某个主题中有3个分区,且副本因子(即副本个数)也为3,如此每个分区便有1个leader副本和2个follower副本。生产者和消费者只与leader副本进行交互,而follower副本只负责消息的同步,很多时候follower副本中的消息相对leader副本而言会有一定的滞后。
4. AR(Assigned Replicas)& ISR(In-Sync Replicas)& OSR(Out-of-Sync Replicas)
分区中的所有副本统称为AR。所有与leader副本保持一定程度同步的副本(包括leader副本在内)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。
与leader副本同步滞后过多的副本(不包括leader副本)组成OSR(Out-of-Sync Replicas),由此可见,AR=ISR+OSR。在正常情况下,所有的 follower 副本都应该与 leader 副本保持一定程度的同步,即 AR=ISR,OSR集合为空。
leader副本负责维护和跟踪ISR集合中所有follower副本的滞后状态,当follower副本落后太多或失效时,leader副本会把它从ISR集合中剔除。当leader副本发生故障时,只有在ISR集合中的副本才有资格被选举为新的leader,而在OSR集合中的副本则没有任何机会。
5. HW(High Watermark)& LEO(Log End Offset)
HW是High Watermark的缩写,俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。LEO是Log End Offset的缩写,它标识当前日志文件中下一条待写入消息的offset。LEO的大小相当于当前日志分区中最后一条消息的offset值加1
如下图:消费者只能拉取到offset在0至5之间的消息。
二、写入过程
- 假设某个分区的ISR集合中有3个副本,即一个leader副本和2个follower副本,此时分区的LEO和HW都为3,生产者准备写入3,4两条消息。如下图:2. 消息3和消息4从生产者发出之后会被先存入leader副本,如下图所示,leader的LEO在消息写入后变成了5(4+1=5),刚写入leader的时刻follower还没有拉取同步数据,对应的hw和leo没变还都是3;
- follower执行同步效率并不一致,在某一时刻,两个follower的状态不一样,如下图:某一时刻follower1完全跟上了leader副本而follower2只同步了消息3,如此leader副本的LEO为5,follower1的LEO为5,follower2的LEO为4,那么当前分区的HW取最小值4,此时消费者可以消费到offset为0至3之间的消息。
- 最终,所有的副本都成功写入了消息3和消息4,整个分区的HW和LEO都变为5,因此消费者可以消费到offset为4的消息了。
版权归原作者 thinking-fish 所有, 如有侵权,请联系我们删除。