Kafka Offset Storage

 

1.概述

  目前,Kafka 官网最新版[0.10.1.1],已默认将消费的 offset 迁入到了 Kafka 一个名为 __consumer_offsets 的Topic中。其实,早在 0.8.2.2 版本,已支持存入消费的 offset 到Topic中,只是那时候默认是将消费的 offset 存放在 Zookeeper 集群中。那现在,官方默认将消费的offset存储在 Kafka 的Topic中,同时,也保留了存储在 Zookeeper 的接口,通过 offsets.storage 属性来进行设置。

2.内容

  其实,官方这样推荐,也是有其道理的。之前版本,Kafka其实存在一个比较大的隐患,就是利用 Zookeeper 来存储记录每个消费者/组的消费进度。虽然,在使用过程当中,JVM帮助我们完成了自一些优化,但是消费者需要频繁的去与 Zookeeper 进行交互,而利用ZKClient的API操作Zookeeper频繁的Write其本身就是一个比较低效的Action,对于后期水平扩展也是一个比较头疼的问题。如果期间 Zookeeper 集群发生变化,那 Kafka 集群的吞吐量也跟着受影响。

  在此之后,官方其实很早就提出了迁移到 Kafka 的概念,只是,之前是一直默认存储在 Zookeeper集群中,需要手动的设置,如果,对 Kafka 的使用不是很熟悉的话,一般我们就接受了默认的存储(即:存在 ZK 中)。在新版 Kafka 以及之后的版本,Kafka 消费的offset都会默认存放在 Kafka 集群中的一个叫 __consumer_offsets 的topic中。

  当然,其实她实现的原理也让我们很熟悉,利用 Kafka 自身的 Topic,以消费的Group,Topic,以及Partition做为组合 Key。所有的消费offset都提交写入到上述的Topic中。因为这部分消息是非常重要,以至于是不能容忍丢数据的,所以消息的 acking 级别设置为了 -1,生产者等到所有的 ISR 都收到消息后才会得到 ack(数据安全性极好,当然,其速度会有所影响)。所以 Kafka 又在内存中维护了一个关于 Group,Topic 和 Partition 的三元组来维护最新的 offset 信息,消费者获取最新的offset的时候会直接从内存中获取。

3.实现

  那我们如何实现获取这部分消费的 offset,我们可以在内存中定义一个Map集合,来维护消费中所捕捉到 offset,如下所示:

protected static Map<GroupTopicPartition, OffsetAndMetadata> offsetMap = new ConcurrentHashMap<>();

  然后,我们通过一个监听线程来更新内存中的Map,代码如下所示:

private static synchronized void startOffsetListener(ConsumerConnector consumerConnector) {
Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
topicCountMap.put(consumerOffsetTopic, new Integer(1));
KafkaStream<byte[], byte[]> offsetMsgStream = consumerConnector.createMessageStreams(topicCountMap).get(consumerOffsetTopic).get(0); ConsumerIterator<byte[], byte[]> it = offsetMsgStream.iterator();
while (true) {
MessageAndMetadata<byte[], byte[]> offsetMsg = it.next();
if (ByteBuffer.wrap(offsetMsg.key()).getShort() < 2) {
try {
GroupTopicPartition commitKey = readMessageKey(ByteBuffer.wrap(offsetMsg.key()));
if (offsetMsg.message() == null) {
continue;
}
OffsetAndMetadata commitValue = readMessageValue(ByteBuffer.wrap(offsetMsg.message()));
offsetMap.put(commitKey, commitValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

  在拿到这部分更新后的offset数据,我们可以通过 RPC 将这部分数据共享出去,让客户端获取这部分数据并可视化。RPC 接口如下所示:

namespace java org.smartloli.kafka.eagle.ipc

service KafkaOffsetServer{
string query(1:string group,2:string topic,3:i32 partition),
string getOffset(),
string sql(1:string sql),
string getConsumer(),
string getActiverConsumer()
}

  这里,如果我们不想写接口来操作 offset,可以通过 SQL 来操作消费的 offset 数组,使用方式如下所示:

  • 引入依赖JAR
<dependency>
<groupId>org.smartloli</groupId>
<artifactId>jsql-client</artifactId>
<version>1.0.0</version>
</dependency>
  • 使用接口
JSqlUtils.query(tabSchema, tableName, dataSets, sql);

  tabSchema:表结构;tableName:表名;dataSets:数据集;sql:操作的SQL语句。

4.预览

  消费者预览如下图所示:

  正在消费的关系图如下所示:

  消费详细 offset 如下所示:

  消费和生产的速率图,如下所示:

5.总结

  这里,说明一下,当 offset 存入到 Kafka 的topic中后,消费线程ID信息并没有记录,不过,我们通过阅读Kafka消费线程ID的组成规则后,可以手动生成,其消费线程ID由:Group+ConsumerLocalAddress+Timespan+UUID(8bit)+PartitionId,由于消费者在其他节点,我们暂时无法确定ConsumerLocalAddress。最后,欢迎大家使用 Kafka 集群监控 ——[ Kafka Eagle ],[ 操作手册 ]。

Kafka Offset 1的更多相关文章

  1. Kafka Offset相关命令总结

    Kafka Offset相关命令总结 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查询topic的offset的范围 1>.查询某个topic的offset的最小值 [ ...

  2. kafka集群监控工具之三--kafka Offset Monitor

    1.介绍 一般情况下,功能简单的kafka项目  使用运维命令+kafka Offset Monitor 就足够用了. 2.使用2.1 部署 github下载jar包 KafkaOffsetMonit ...

  3. Kafka Offset Storage

    1.概述 目前,Kafka 官网最新版[0.10.1.1],已默认将消费的 offset 迁入到了 Kafka 一个名为 __consumer_offsets 的Topic中.其实,早在 0.8.2. ...

  4. kafka offset 设置

    from kafka import KafkaConsumer from kafka import TopicPartition from kafka.structs import OffsetAnd ...

  5. 关于 Kafka offset

    查询topic的offset的范围 用下面命令可以查询到topic:Mytopic broker:SparkMaster:9092的offset的最小值: bin/kafka-run-class.sh ...

  6. Spark createDirectStream 维护 Kafka offset(Scala)

    createDirectStream方式需要自己维护offset,使程序可以实现中断后从中断处继续消费数据. KafkaManager.scala import kafka.common.TopicA ...

  7. kafka offset的存储问题

    注意:从kafka-0.9版本及以后,kafka的消费者组和offset信息就不存zookeeper了,而是存到broker服务器上,所以,如果你为某个消费者指定了一个消费者组名称(group.id) ...

  8. using kafkacat reset kafka offset

    1. install kafkacat Ubuntu apt-get install kafkacat CentOS install deepenency yum install librdkafka ...

  9. kafka offset存储

    存储方式 方式 方式来源 存储位置 自动提交 kafka kafka 异步提交 kafka kafka checkpoint spark streaming hdfs hbase存储 程序开发 hba ...

随机推荐

  1. Let's do our own full blown HTTP server with Netty--转载

    原文地址:http://adolgarev.blogspot.com/2013/12/lets-do-our-own-full-blown-http-server.html Sometimes ser ...

  2. Android Studio设置图片背景及主题设置

    因为Android Studio是基于IDEA的,所以IDEA里面能用的插件Android Studio也能用,这次图片背景是依赖IDEA下的一个插件,名为BackgroundImage的插件,用户可 ...

  3. mysql数据库各存储引擎比較

    mysql数据库差别于其它数据库的最重要的一个特点是其插件式的表存储引擎,存储引擎是基于表的.而不是数据库 InnoDB存储引擎:        支持事务,其设计目标主要面向在线事务处理(OLTP)的 ...

  4. [Nuxt] Setup a "Hello World" Server-Rendered Vue.js Application with the Vue-CLI and Nuxt

    Install: npm install -g vue-cli Init project: vue init nuxt/starter . Run: npm run dev Create a inde ...

  5. 两个常见Qt编译错误的解决

    作者:朱金灿 来源:http://blog.csdn.net/clever101 如果在电脑上安装了两个Qt版本,在编译一个工程时有可能出现如下的编译错误: ERROR: failed to refr ...

  6. sqlplus中怎么将你全部的操作和结果记录保存到你指定的文件里

    [在sqlplus的操作中,非常多时候我们都想把自己的写的sql语句和改动日志或者结果信息做记录] [首先]肯定要正常连接到oralce数据库. [然后] 你用你指定的用户登录到oralce数据库之后 ...

  7. Java算法--串的简单处理

    题目例如以下: 串的处理 在实际的开发工作中.对字符串的处理是最常见的编程任务. 本题目即是要求程序对用户输入的串进行处理.详细规则例如以下: 1. 把每个单词的首字母变为大写. 2. 把数字与字母之 ...

  8. Linux文件编辑命令具体整理

    刚接触Linux,前几天申请了个免费体验的阿里云server,选择的是Ubuntu系统.配置jdk环境变量的时候须要编辑文件. vi命令编辑文件,百度了一下,非常多回答不是非常全面,因此编辑文件话了一 ...

  9. 标准模板库(STL) map —— 初始化问题

    map 容器没有:.reverse成员: map 是关联式容器,会根据元素的键值自动排序: map 容器不是连续的线性空间: 标准 STL 使用 RB-tree 为底层机制 ⇒ 自动排序(关于键值): ...

  10. 【u005】封锁阳光大学

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹 ...