16 | 揭开神秘的“位移主题”面纱
16 | 揭开神秘的“位移主题”面纱
讲述:胡夕
时长12:58大小11.87M
小结
开放讨论
赞 22
提建议
精选留言(125)
- 注定非凡2019-11-031,诞生背景 A :老版本的Kafka会把位移信息保存在Zk中,当Consumer重启后,自动从Zk中读取位移信息。这种设计使Kafka Broker不需要保存位移数据,可减少Broker端需要持有的状态空间,有利于实现高伸缩性。 B :但zk不适用于高频的写操作,这令zk集群性能严重下降,在新版本中将消费者的位移数据作为一条条普通的Kafka消息,提交至内部主题(_consumer_offsets)中保存。实现高持久性和高频写操作。 2,特点: A :位移主题是一个普通主题,同样可以被手动创建,修改,删除。。 B :位移主题的消息格式是kafka定义的,不可以被手动修改,若修改格式不正确,kafka将会崩溃。 C :位移主题保存了三部分内容:Group ID,主题名,分区号。 3,创建: A :当Kafka集群中的第一个Consumer程序启动时,Kafka会自动创建位移主题。也可以手动创建 B :分区数依赖于Broker端的offsets.topic.num.partitions的取值,默认为50 C :副本数依赖于Broker端的offsets.topic.replication.factor的取值,默认为3 4,使用: A :当Kafka提交位移消息时会使用这个主题 B :位移提交得分方式有两种:手动和自动提交位移。 C :推荐使用手动提交位移,自动提交位移会存在问题:只有consumer一直启动设置,他就会无限期地向主题写入消息。 5,清理: A :Kafka使用Compact策略来删除位移主题中的过期消息,避免位移主题无限膨胀。 B :kafka提供专门的后台线程定期巡检待compcat的主题,查看是否存在满足条件的可删除数据。 6,注意事项: A :建议不要修改默认分区数,在kafka中有些许功能写死的是50个分区 B :建议不要使用自动提交模式,采用手动提交,避免消费者无限制的写入消息。 C :后台定期巡检线程叫Log Cleaner,若线上遇到位移主题无限膨胀占用过多磁盘,应该检查此线程的工作状态。展开共 5 条评论83
- 此方彼方Francis2020-02-14之前遇到过的一个问题跟大家分享一下,原因描述不正确的地方还请大佬指正: log cleaner线程挂掉还有可能导致消费端出现:Marking Coordinator Dead! 原因大概如下: log cleaner线程挂掉之后会导致磁盘上位移主题的文件越来越多(当然,大部分是过期数据,只是依旧存在),broker内存中会维护offsetMap,从名字上看这个map就是维护消费进度的,而这个map和位移主题的文件有关联,文件越来越多会导致offsetMap越来越大,甚至导致offsetMap构建失败(为什么会失败没有搞明白),offsetMap构建失败之后broker不会承认自己是coordinator。 消费者组找coordinator的逻辑很简单:abs(consumer_groupName.hashCode) % __consumer_offset.partition.num对应的partition所在的broker就是这个group的coordinate,一旦这个broker的offsetMap构建失败,那么这个broker就不承认自己是这个group的coordinate,这个group的消费就无法继续进行,会出现Marking Coordinator Dead错误。 此时需要删除过期的位移主题的文件(根据文件名很容易确定哪个是最新的),重启broker。重启过程中需要关注log cleaner是否会再次挂掉。 PS:上述问题在broker重启和正常运行中都有可能遇到。展开
作者回复: 是个很好的梳理思路~
共 6 条评论54 - Eco2020-01-15有个问题想请教一下,这个位移主题,Consumer是像消费其他主题的分区的内容一样去获取数据的话,那么这本身不也得有个位移,那这个位移又保存到哪里的呢?这样下去不就陷入了一个死循环了吗?要么就不是像正常的消费消息那样去从位移主题获取当前消费者对于某个主题的分区的位移?
作者回复: 好问题!其实Kafka并不太关注__consumer_offsets消费的情况,不过Coordinator的确会在JVM中把所有分区当前已提交的最新位移缓存起来,并且通过这个缓存来决定哪个consumer当前消费到了哪个位移。
共 6 条评论27 - 蛋炒番茄2019-07-09“自动提交位移有一个显著的优点,就是省事,你不用操心位移提交的事情,就能保证消息消费不会丢失”,对于这一点我表示疑问啊❓我记得你在之前的章节里面讲过自动提交不仅会增加消息可重复消费的可能,也可能导致部分消息丢失。比如说虽然消息拉取下来但是还没消费完就已经提交,此时服务挂了这样情况。共 5 条评论23
- mellow2019-07-09老师能讲一下,同一个group下的consumer启动之后是怎么去offset topic 拿到该group上次消费topic每个partition的最新offset呢?是根据key来定位offset topic的partition吗,然后拿到所有消息得到最新的offset吗
作者回复: 它会去寻找其Coordinator Leader副本对应的broker去拿。根据group.id找到对应Coordinator的分区数
共 5 条评论21 - 王藝明2019-10-14老师好! 为什么位移主题写入消息时,不直接替换掉原来的数据,像 HashMap 一样呢?而是要堆积起来,另起线程来维护位移主题
作者回复: 位移主题也是主题,也要遵循Kafka底层的日志设计思路,即append-only log
共 3 条评论17 - sharpdeep2020-03-26有个困惑: 位移主题用来记住位移,那么这个位移主题的位移由谁来记住呢?
作者回复: 位移主题的位移由Kafka内部的Coordinator自行管理
共 2 条评论13 - 🤡2019-08-12对GroupId 还有疑惑,假设一个Group下有 3 个Consumer , 那这三个Consumer 对应的groupid 应该是一样的。这样的话怎么做key做唯一区分呢
作者回复: 每个client都有自己的member id和client id用于区分彼此
共 3 条评论13 - 谦寻2019-07-15consumer端 日常业务发版呢,那每次发版需要重启consumer不是也会导致Rebalance,这个如何规避
作者回复: 可以考虑使用standalone consumer,否则group机制无法避免
共 2 条评论12 - HZ2020-02-24老师 有两点不太清楚 1. 位移主题里面,对于同一个consumer group的位移提交记录,是分布在50个partitions中吗? 2. 如果把位移主题当作kafka里面的一个普通主题,那么写入这个主题的数据可以保证不丢失吗? 写入是ack=all? 同时,broker端的min.insync.replicas的设置有影响吗?
作者回复: 1. 同一个group的位移记录只保存在一个partition上 2. 没错,写入就是acks=all的设置 3. min.insync.replicas对位移主题依然适用
共 4 条评论10 - 西边一抹残阳2020-01-04胡老师,消费者提交的位移消息,保存到位移主题分区是随机的吗?就是某一个消费者的提交第一个位移数据保存在位移主题的A分区里面,第二个位移数据保存在位移主题的B分区里面 还有消费者是怎样获取已消费的位移数据
作者回复: 不是随机的。通常来说,同一个group下的所有消费者提交的位移数据保存在位移主题的同一个分区下
9 - Coder42019-07-11老师好,前几年一直有个说法,说kafka不适合创建过多topic,请问现在的新版还有这个问题么?
作者回复: topic过多其实是指分区数过多。会有两个可能的问题:1. controller无法管理这么多分区;2. 分区数过多导致broker物理随机IO增加,减少吞吐量。 第一个问题社区算是修复了吧,目前单controller能够支持20w的分区数,况且社区也在考虑做多controller方案;第二个问题目前没有太多直接的修复举措,只能说具体问题具体分析吧
共 4 条评论8 - gogogo2019-07-09请问offset是以最新的为准,还是值最大的为准?
作者回复: 最新的
共 3 条评论8 - 张申傲2020-06-29说到Kafka的Compaction,就想到了Redis的AOF Rewrite,都是类似的机制8
- 永光2019-07-11位移主题,适用于高频写的操作,为什么ZooKeeper不适用于这种高频的写操作?zookeeper 也可以按照<Group ID,主题名,分区号 > 来写入呀?
作者回复: ZooKeeper本身只是一个分布式协调框架,znode中保存的数据多是那些不怎么频繁修改的元数据,本身不适合频繁更新。 是的,旧版本consumer就是这么使用ZooKeeper来保存位移的
共 4 条评论8 - LJK2019-09-23老师好,请教一个小白问题,一个位移主题是在第一个consumer启动时建立的,是说对于一个kafka集群只有一个位移主题么?另外我对kafka框架还是有点迷惑,kafka集群是不是没有NameNode这个概念啊?每一个leader partition就相当于一个NameNode?谢谢老师
作者回复: 每个Kafka集群都只有一个位移主题。Kafka没有NameNode的概念。如果硬搬Hadoop中的概念,我倒倾向于认为分区的leader副本是datanode,而namenode的作用在Kafka中由ZooKeeper承接
5 - 小鱼2019-07-31老师,你好,请问控制Kafka 使用Compact 策略来删除位移主题中的过期消息的参数是哪个?
作者回复: offsets.retention.minutes
5 - 南辕北辙2019-07-10老师,请教一下consumer 是如何从这个位移主题中拿到曾经属于自己组的offset呢
作者回复: 首先找到对应的Coordinator,Coordinator保存了这些数据,然后consumer向Coordinator发送请求去请求这些数据
共 3 条评论6 - WL2019-07-09请教老师三个问题: 1. 在consumer group中的一个consumer消费一条消息后,是往它拉取消息的那个broker写一条offset消息还是往所有它连接的broker都广播一条消息。 2. 一个broker中的位移主题保存的是他自己上面的主题和分区的位移还是整个集群的所有主题所有分区的位移都有保存。 3. 位移主题的50个分区分配在各个broker的方式是啥,轮询,hash,还是随机?展开
作者回复: 1. 你是指提交位移吗?如果是,它是向对应的Coordinator所在的broker发送一条位移写请求 2. 都有保存 3. 你基本上可以认为是轮训的
共 2 条评论5 - 燃烧的M豆2019-07-09老师如果超大规模集群超大规模消费者对这一个 50 个 partitions 的 topic 进行消费是不是会引起性能问题?topic 下的 partitions 设置有上线吗 面对超大规模并发除了提升 partitions 数量还有什么办法?谢谢
作者回复: partition数量在kafka中没有上限,只受os限制。除了提升partition,增加broker挂载的磁盘数也是一个方法
5