一、了解Kafka中的相关概念
MQ作为消息中间件,对于我们来说,已经并不陌生了,那么,由于Kafka它在众多的MQ间是非常火热的,那么必然也是我们需要着重关注的中间件之一了,为了更加清晰的了解Kafka,我们先从Kafka的体系结构入手,看看大体上都包含哪些东西。具体请见下图所示:
image.png
其中有一些我们很熟悉的,比如:Producer、Consumer;当然,也有一些陌生的概念,例如:Broker,下面我们就一一说明一下:
【Producer】消费者,即:向Kafka中发送消息的消息生产端;
【Consumer】消费者,即:从Kafka中获取消息的消息消费端,此处有一点大家需要注意,消费端是采用拉取数据的方式来获得消息的;
【Kafka Broker】我们可以将其当做一个Kafka服务实例,或者按照常见的部署方式,即:一台Kafka服务器安装一个Kafka Broker;
【ZooKeeper集群】此处作为存储和管理kafka集群元数据,或者辅助Controller选举操作等。
此处需要说明的一点就是,Kafka是希望将原有ZooKeeper负责的内容纳入自己的管辖区域,所以,在Kafka在2.8.0
版本的时候,就已经引入了KRaft,而在3.3.1
版本是,KRaft就已经可以成为一个真正产品来代替zk;不过因为目前线上很多使用的Kafka集群依然是配合着ZooKeeper集群来使用,所以在上图中,我们依然画出了ZooKeeper集群。
image.png
二、Topic主题
试想一下,当我们要尝试发送
/消费
消息的时候需要注意什么呢?这有啥需要注意的,发送不就得了!结果,我们发现了一个非常重大的问题,大家都往Kafka
中发送消息,所有的消息都混合在了一起,就类似所有快递公司的快递员(Producer端
)把快递都扔到了一个大仓库里,结果,去取快递的小伙伴们(Consumer端
)面对堆积如山且混乱不堪的“快递山”——疯了。。。
image.png
那怎么办呢?这个好办,我们将原来的这个大屋子按照不同快递公司进行分割。这样,你是哪个快递公司的快递,就把快递放到对应的屋子里就可以了。那么,这个在Kafka中就叫做Topic,也就是我们常说的主题,不过在Kafka中,Topic主题只是一个逻辑概念,并“不是真实”存在的。此时有的同学就该不耐烦了——“不存在?!那你在这儿跟我叨叨半天……”不要着急,要想更进一步了解,我们还需要再了解一个概念,Partition分区
。
image.png
三、Partition分区
什么是Partition呢?我们还是以刚才的大仓库为例,随着国民收入的愈发增加以及网上购物的兴起,大家网上购买商品的比重大大超过了线下实体店的购买量,那么随着而来的就是快递包裹也成指数增长,为了解决这个问题,怎么办呢?答案貌似很简单,再建造几个仓库不就可以了。对的,就是这样的,这就是我们所说的Partition分区。
image.png
从上面再建造多个仓库的方式,除了可以平摊请求量并提升处理速度之外,我们再考虑一个问题,如果你要给另一个人写封信,这封信非常非常的重要,你怕对法收不到信,怎么办?我们可以将这封信复制成多份,然后发出去,即使信邮寄丢了,没关系,我们还有其他“副本”呢!这其实就是我们Partition的另外一个作用,尽量提高消息的容灾能力。
那么,我们了解了以上概念之后,我们就将视野放到Kafka身上,在Kafka中为Partition引入了副本(Replica
)的概念,它采取的是“一主多从”的配置关系,即:主和从存储的数据都是相同的。那么,为了更加提升容灾能力,不同的副本会保存到不同的Kafka Broker节点上,这样,即使某个Broker宕机掉了,在其他Broker上依然保持着可服务的副本。
image.png
既然副本分为主副本和从副本,那么他们的职责如下所示:
【主副本/Leader副本】负责处理集群的读写请求操作。
【从副本/Follower副本】只负责同Leader副本的数据同步。
四、ISR&LEO&HW
上面我们介绍完了副本,我们来顺便了解一下五个关键缩写词:
【AR(Assigned Replicas)】分区中的所有副本。
【ISR(In-Sync Replicase)】所有与leader副本保持正常程度同步的副本(包括leader副本在内)的集合。
【OSR(Out-of-Sync Replicase)】与leader副本同步滞后过多的副本(不包括leader副本)的集合。
【LEO(Log End Offset)】它标识当前日志文件中下一条待写入消息的offset。
【HW(High Watermark)】高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。
从上面对于5
个缩写词的介绍,大家可以猜到 AR = ISR + OSR,而如果原有的Leader副本挂掉了,需要选主,则只会从ISR列表中进行选择,而不会去OSR
中选择。
而对于LEO
和HW
,我们看下图所示:
image.png
LEO所指向的位置,就是新来消息所待插入的位置;而对于HW来说,取partition中对应的
ISR
中最小的LEO(log-end-offset)作为HW;Consumer最多只能消费到HW所在的位置,每个副本都有HW,Leader
和Follower
各自负责更新自己的HW的状态。
对于Leader新写入的消息,Consumer不能立刻消费,Leader会等待该消息被所有ISR中的副本同步后更新HW,此时消息才能被Consumer所消费。这样就能保证如果Leader所在的broker失效,该消息仍然可以从新选举的Leader中获取。具体逻辑如下图所示:
image.png
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」