3.5.5 缓存分区的偏移量

3.5.5 缓存分区的偏移量

消费者提交自己负责分区的偏移量,除了写入服务端(协调节点)内部主题某个分区的日志文件中,还要把这部分数据保存一份到当前服务端的内存中,这样分区的偏移量保存在了磁盘和内存两个地方。偏移量消息的键由消费组、主题、分区组成(GoupTopicPat1tion),消息的值是分区的偏移盘。查询分区的偏移量时给定GoupTop1cPat1hon,会返回分区对应的偏移盘,即分区当前的消费进度。

由于消费者会周期性地提交偏移量,同一个分区在每次提交时都会产生新的偏移盐。比如分区p。在第一次提交时偏移量为10,在第二次提交时偏移量为20。每次提交偏移盘写入日志文件都采用追加消息的方式。对于写入锺存而言,因为使用Map结构,所以相同分区的偏移量会被覆盖更新。相关代码如下:
在这里插入图片描述
缓存的作用是为了方便查询,而且会被重复查询,如果没有重复查询,就没有必要放入缓存。比如,不能把普通的消息内容作为缓存,因为普通消息量很大,而且消费者读取过一次之后一般不会再次读取。

如表3-3所示,服务端有两种作用域类型的缓存:“所有节点共享”“每个节点独享”。如果是共享数据,贝I]向任意一个服务端节点发送请求,都可以获取到一致的状态(比如主题的元数据),它的特点是和业务逻辑的任何组件都无关。如果是节点独享的数据,节点之间数据不一致,要保证读写请求连接的是同一个节点,才能读取到一致的数据。它的特点是和业务逻辑的某个组件有关,比如消费者提交的分区偏移量和消费组有关。
在这里插入图片描述

如图3-29所示,偏移盘请求和消费组有关,客户端只能连接指定的节点,所以是协调节点独享的缓存。而主题元数据(TopicMetadata)和消费组的协调者(GroupCoordinator)因为在每个服务端节点保存的数据都一样,可以请求任何一个节点,所以是所有节点共享的缓存。
在这里插入图片描述

我们来讨论一个问题:为什么分区偏移量消息的键由“消费组、主题、分区”组成,而分区方式
却只由消费组决定?下面我们来循序渐进地回答这个问题。

首先,要回答消息的键为什么有消费组,而没有消费者。虽然分区是由消费者提交的,但是偏移量消息的任tt不能存在消费者。假设键是GroupConsuJ11erTopicPart1hon,每个消费者提交的偏移量都有向己的标识。比如消费者1提交的偏移盘是G1-C1-T1P0:10,消费者2提交的偏移量是G1-C2-T1P1:20,保存到缓存的数据是[(G1C1T1P0,10),(G1αT1P1,20)]。再平衡后,TlPO分配笋消费者2,在缓存中就不会查询至l]G1CZT1P0的记录;如果TlPl分配给消费者l,也无法查到G1ζ1T1P1的记录。而以消费组存储时缓存的内容是[(G1T1问,10),(G1T1P1,20汀,这样不管是消费者l还是消费者2分配到TIPO,都可以从缓存中读取州TIPO的偏移盘。只要消费组所有消费者都提交了分区的消费进度,再平衡时无论怎么重新分配分区,任何一个消费者都可以查询到任意一个分区的最新消费进度。

另外,必须要有消费组的原因是,不同的消费组可能会订阅同一个主题。如果只有“主题、分区”作为分区偏移£l消息的键,就无法区分不同的消费组。而实际上,不同消费组,即使主题分区相同,它们的分区偏移盐也可能不同,所以偏移量消息的键需要有“消费组”。

其次,因为服务端要保存分区的偏移盐,所以消息值是偏移量,其他信息比如主题、分区都放在消息的健中。所以偏移量消息的键由“消费组、主题、分区”3部分组成。

最后,再来看看为什么分区方式只Fl=I消费组决定的,而不是偏移量消息的键?因为同一个消费组的分区偏移量消息都在同一个协调节点上,为消息进行分区的方式只能是消费组。如果分区方式也是“消费组、主题、分区”,那么只有这3个数据都相同时,内部主题的分区才相同。比如G1T1P0和G1T1P1因为分区不同,内部主题的分区也不同,提交偏移量时就不在同一个协调节点了。而这和前面的“相同消费组的消费者提交偏移量是在同一个协调节点”就发生了矛盾。

相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页