|NO.Z.00082|——————————|BigDataEnd|——|Hadoop&kafka.V67|——|kafka.v67|稳定性|__consumer_offsets主题|
一、 _consumer_offsets主题
### --- zookeeper不适合大批量的频繁写入操作
~~~ Zookeeper不适合大批量的频繁写入操作。
~~~ Kafka 1.0.2将consumer的位移信息保存在Kafka内部的topic中,即__consumer_offsets主题,
~~~ 并且默认提供了kafka_consumer_groups.sh脚本供用户查看consumer信息。
### --- 创建topic “tp_test_01”
[root@hadoop01 ~]# kafka-topics.sh --zookeeper localhost:2181/myKafka \
--create --topic tp_test_01 --partitions 5 --replication-factor 1
[root@hadoop01 ~]# kafka-topics.sh --zookeeper localhost:2181/myKafka --list
tp_test_01
### --- 使用kafka-console-producer.sh脚本生产消息
~~~ 由于默认没有指定key,所以根据round-robin方式消息分布到不同的分区上 (本例中生产了100条消息)
[root@hadoop01 ~]# for i in `seq 100`; do echo "hello yanqi $i" >> messages.txt; done
[root@hadoop01 ~]# kafka-console-producer.sh --broker-list localhost:9092 \
--topic tp_test_01 < messages.txt
### --- 验证消息生产成功
~~~ 结果输出表明100条消息全部生产成功!
[root@hadoop01 ~]# kafka-console-producer.sh --broker-list localhost:9092 \
--topic tp_test_01 < messages.txt
~~~输出参数
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[root@hadoop01 ~]# kafka-run-class.sh kafka.tools.GetOffsetShell \
--broker-list localhost:9092 --topic tp_test_01 --time -1
~~~输出参数
tp_test_01:2:20
tp_test_01:4:20
tp_test_01:1:20
tp_test_01:3:20
tp_test_01:0:20
### --- 创建一个console consumer group
[root@hadoop01 ~]# kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic tp_test_01 --from-beginning
~~~输出参数
hello yanqi 1
~~~省略部分内容
hello yanqi 100
### --- 获取该consumer group的group id(后面需要根据该id查询它的位移信息)
~~~ # 输出: console-consumer-28879 (记住这个id!)
[root@hadoop01 ~]# kafka-consumer-groups.sh --bootstrap-server \
localhost:9092 --list
~~~输出参数
console-consumer-28879
### --- 查询__consumer_offsets topic所有内容
~~~ 注意:运行下面命令前先要在consumer.properties中设置exclude.internal.topics=false
[root@hadoop01 ~]# vim /opt/yanqi/servers/kafka/config/consumer.properties
exclude.internal.topics=false
[root@hadoop01 ~]# kafka-server-stop.sh
[root@hadoop01 ~]# zkServer.sh stop
[root@hadoop01 ~]# zkServer.sh start
[root@hadoop01 ~]# kafka-server-start.sh -daemon /opt/yanqi/servers/kafka/config/server.properties
~~~ # 默认情况下__consumer_offsets有50个分区,如果你的系统中consumer group也很多的话,
~~~ 那么这个命令的输出结果会很多。
[root@hadoop01 ~]# kafka-console-consumer.sh --topic __consumer_offsets \
--bootstrap-server localhost:9092 --formatter \
"kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" \
--consumer.config /opt/yanqi/servers/kafka/config/consumer.properties \
--from-beginning
~~~输出参数
[test-consumer-group,__consumer_offsets,0]::[OffsetMetadata[0,NO_METADATA],CommitTime 1632441252970,ExpirationTime 1632527652970]
[test-consumer-group,__consumer_offsets,44]::[OffsetMetadata[21,NO_METADATA],CommitTime 1632441252970,ExpirationTime 1632527652970]
[test-consumer-group,__consumer_offsets,39]::[OffsetMetadata[0,NO_METADATA],CommitTime 1632441252970,ExpirationTime 1632527652970]
二、计算指定consumer group在consumer_offsets topic中分区信息
### --- 计算指定consumer group在__consumer_offsets topic中分区信息
~~~ 这时候就用到了第5步获取的group.id(本例中是console-consumer-49366)。
~~~ Kafka会使用下面公式计算该group位移保存在__consumer_offsets的哪个分区上:
Math.abs(groupID.hashCode()) % numPartitions
三、创建编程代码
### --- 创建一个maven项目:demo-11-kafka-consumer
### --- 编程代码
package com.yanqi.kafka.consumer;
public class MyTest {
public static void main(String[] args) {
String str = "console-consumer-28879";
// __consumer_offsets的主题分区数量为50个
System.out.println(Math.abs(str.hashCode()) % 50);
}
}
### --- 编译执行
~~~ 对应的分区=Math.abs("console-consumer-28879".hashCode()) % 50 = 25,
~~~ 即__consumer_offsets的分区19保存了这个consumer group的位移信息。
D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=56389:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.10000——javaproject\NO.Z.00002.Hadoop\kafka_demo\demo-11-kafka-consumer\target\test-classes com.yanqi.kafka.consumer.MyTest
25
Process finished with exit code 0
四、获取指定consumer group的位移信息
[root@hadoop01 ~]# kafka-simple-consumer-shell.sh \
--topic __consumer_offsets --partition 25 \
--broker-list localhost:9092 --formatter \
"kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter"
~~~输出参数
[console-consumer-28879,tp_test_01,3]::[OffsetMetadata[20,NO_METADATA],CommitTime 1632438713273,ExpirationTime 1632525113273]
[console-consumer-28879,tp_test_01,4]::[OffsetMetadata[20,NO_METADATA],CommitTime 1632438713273,ExpirationTime 1632525113273]
[console-consumer-28879,tp_test_01,0]::[OffsetMetadata[20,NO_METADATA],CommitTime 1632438713273,ExpirationTime 1632525113273]
[console-consumer-28879,tp_test_01,1]::[OffsetMetadata[20,NO_METADATA],CommitTime 1632438713273,ExpirationTime 1632525113273]
[console-consumer-28879,tp_test_01,2]::[OffsetMetadata[20,NO_METADATA],CommitTime 1632438713273,ExpirationTime 1632525113273]
### --- 上述可见,该consumer group果然保存在分区11上,
~~~ 且位移信息都是对的(这里的位移信息是已消费的位移,严格来说不是第3步中的位移。
~~~ 由于我的consumer已经消费完了所有的消息,所以这里的位移与第3步中的位移相同)。
~~~ 另外,可以看到__consumer_offsets topic的每一日志项的格式都是:
~~~ [Group, Topic, Partition]::[OffsetMetadata[Offset, Metadata], CommitTime, ExpirationTime]。
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv013-kafka
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通