玉林社区   玉林天天茶座   新观点聊聊 Kafka: Consumer 源码解析之 R
返回列表
查看: 451|回复: 0

新观点聊聊 Kafka: Consumer 源码解析之 R

[复制链接]

1384

主题

1384

帖子

5270

积分

论坛元老

Rank: 8Rank: 8

积分
5270
发表于 2022-2-27 11:08:11 | 显示全部楼层 |阅读模式

马上注册玉林红豆网会员,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

R本质上是一种协议,规定了一个CG下的所有C如何达成一致,来分配订阅T的每个分区。[url=http:///www.wangsu.com/]IPv6[/url]的相关资讯可以到我们网站了解一下,从专业角度出发为您解答相关问题,给您优质的服务![align=center]

                               
登录/注册后可看大图
[/align]
一、前言
我们上一篇分析了C如何加入CG,其上一篇是一个很宏观的东西,主要讲CC怎么与GC通信。等等,老周,CC和GC是个啥玩意?这两个组件分别是C、KB的协调器,说白了就是我们设计模式中的门面模式,具体的内容可以看上一篇回顾下。今天这一篇主要讲上一篇C如何加入CG中的R机制,其上一篇讲了大概了,这一篇更深入的来说一说R机制的具体细节。


如果你是一个有一定经验的程序员,R机制我觉得可以作为一道面试题来考察,而且还是有一定难度的。但是也不需要妄自菲薄,跟着老周的这篇文章下来,相信你一定可以拿下它的。


但有些读者确觉得还是有一定难度,别着急,先看下下面K的拓扑结构,这个结构很清晰了吧,如果你对K的拓扑结构还不了解,那我建议你先别往下看了,先把K的拓扑结构搞清楚,或者先看老周前面的几篇文章再来继续阅读,我觉得效果会更好。





这一篇主要从以下几点来聊一聊R机制:



什么是R机制?
触发R机制的时机
G状态变更
旧版消费者客户端的问题
R机制的原理
B端重平衡场景

二、什么是R机制?
R本质上是一种协议,规定了一个CG下的所有C如何达成一致,来分配订阅T的每个分区。


当集群中有新成员加入,或者某些主题增加了分区之后,消费者是怎么进行重新分配消费的?这里就涉及到重平衡(R)的概念,下面我就给大家讲解一下什么是K重平衡机制。





从图中可以找到消费组模型的几个概念:



同一个消费组,一个分区只能被一个消费者订阅消费,但一个消费者可订阅多个分区,也就是说每条消息只会被同一个消费组的某一个消费者消费,确保不会被重复消费;
一个分区可被不同消费组订阅,这里有种特殊情况,假如每个消费组只有一个消费者,这样分区就会广播到所有消费者上,现广播模式消费。

要想现以上消费组模型,那么就要现当外部环境变化时,比如主题新增了分区,消费组有新成员加入等情况,现动态调整以维持以上模型,那么这个工作就会交给K重平衡(R)机制去处理。





从图中可看出,K重平衡是外部触发导致的,下面来看下触发K重平衡的时机有哪些。


、触发R机制的时机

有新的C加入CG
有C宕机下线。C并不一定需要真正下线,例如遇到长时间的GC、络延迟导致消费者长时间未向GC发送HR时,GC会认为C下线。
有C主动退出CG(发送LGR请求)。比如客户端调用了()方法取消对某些主题的订阅。
C消费超时,没有在指定时间内提交偏移量。
CG所对应的GC节点发生了变更。
CG所订阅的任一主题或者主题的分区数量发生变化。

四、G状态变更
41消费端
在C侧的门面CC,它继承了AC抽象类。在协调器AC中的内部类MS中我们可以看到协调器的四种状态,分别是未注册、重分配后没收到响应、重分配后收到响应但还没有收到分配、稳定状态。





上述消费端的四种状态的转换如下图所示:





42服务端
对于K服务端的GC则有五种状态E、PR、CR、S、D。他们的状态转换如下图所示:












一个消费者组最开始是E
重平衡开启后,会置于PR等待成员加入。
之后变更到CR等待分配方案
最后流转到S完成R
当有成员变动时,消费者组状态从S变为PR。

此时所有现存成员需要重新申请加入组
当所有组成员都退出组后,消费者组状态为E。


消费者组处于E状态,K会定期自动删除过期。

五、旧版消费者客户端的问题
CC与GC的概念是针对K090版本后的消费者客户端而言的,我们暂且把K090版本之前的消费者客户端称为旧版消费者客户端。旧版消费者客户端是使用Z的**(W)来现这些功能的。


每个消费组在Z中维护了一个路径,在此路径下使用临时节点记录隶属于此消费组的消费者的唯一标识S,S由消费者启动时创建。消费者的唯一标识由+主机+时间戳+UUID的部分信息构成,其中是旧版消费者客户端中的配置,相当于新版客户端中的。比如某个消费者的唯一标识为_-074527562-64775,那么其中为指定的,为计算机的主机,074527562代表时间戳,而64775表示UUID的部分信息。


下图与同级的还有两个节点:和



路径下记录了分区和消费者的对应关系
路径下记录了此消费组在分区中对应的消费位移




每个、主题和分区在Z中也都对应一个路径:



记录了、及分配在此上的主题分区列表;
记录了每个分区的副本、ISR集合等信息。
记录了当前副本、等信息。

每个消费者在启动时都会在和路径上注册一个**。当路径下的子节点发生变化时,表示消费组中的消费者发生了变化;当路径下的子节点发生变化时,表示出现了增减。这样通过Z所提供的W,每个消费者就可以监听消费组和K集群的状态了。


这种方式下每个消费者对Z的相关路径分别进行监听,当触发再均衡操作时,一个消费组下的所有消费者会同时进行再均衡操作,而消费者之间并不知道彼此操作的结果,这样可能导致K工作在一个不正确的状态。与此同时,这种严重依赖于Z集群的做法还有两个比较严重的问题。



羊群效应(HE):所谓的羊群效应是指Z中一个被监听的节点变化,大量的W通知被发送到客户端,导致在通知期间的其他操作延迟,也有可能发生类似死锁的情况。
脑裂问题(SB):消费者进行再均衡操作时每个消费者都与Z进行通信以判断消费者或变化的情况,由于Z本身的特性,可能导致在同一时刻各个消费者获取的状态不一致,这样会导致异常问题发生。

六、R机制的原理
K090版本后的消费者客户端对此进行了重新设计,将全部消费组分成多个子集,每个消费组的子集在服务端对应一个GC对其进行管理,GC是K服务端中用于管理消费组的组件。而消费者客户端中的CC组件负责与GC进行交互。



R完整流程需要CC共同完成
C端R步骤

加入组:对应JG请求
等待LC分配方案:对应SG请求


当组内成员加入组时,C向协调者发送JG请求。
每个C会上报自己订阅的
C收集到所有JG请求后,从这些成员中选择一个担任消费者组的L

通常第一个发送JG请求的自动成为L


LC的任务是收集所有成员的,根据信息制定具体的分配方案。
选出L后,协调者把所有信息封装到JGR中,发送给L。
LC做出统一分配方案,进入到SG请求。
LC向协调者发送SG,将分配方案发给协调者。
其他成员也会发出SG请求
协调者以SGR的方式将方案下发给所有成员








所有成员成功接收到分配方案,消费者组进入S状态,开始正常消费。

具体的源码分析,可以看我上一篇分析的C如何加入CG文章。


七、B端重平衡场景
71新成员加入
消费者组处于S之后有新成员加入





72组成员主动离开

主动离开:CI通过调用()方法通知协调者退出
该场景涉及第个请求:LG请求




7组成员崩溃离开

协调者需要等待一段时间才能感知
这个时间段由C端参数控制
K不会超过上述参数时间感知崩溃
处理流程相同




74R时组成员提交

R开启时,协调者会给予成员一段缓冲时间,要求每个成员在这段时间内速上报自己的。
再开启正常的JGSG请求




好了,R机制就先说这么多了,下一篇会来聊一聊如何避免重平衡。


本文转载自微信「老周聊架构」,可以通过以下二维码关注。转载本文请联系老周聊架构。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

收藏:1 | 帖子:8万



侵权举报:本页面所涉内容均为用户发表并上传,岭南都会网仅提供存储服务,岭南都会网不承担相应的法律责任;如存在侵权问题,请权利人与岭南都会网联系删除!