关于kafka中的timestamp与offset的对应关系

关于kafka中的timestamp与offset的对应关系

@(KAFKA)[storm, kafka, 大数据]

  • 关于kafka中的timestamp与offset的对应关系
    • 获取单个分区的情况
    • 同时从所有分区获取消息的情况
    • 结论
      • 如何指定时间
      • 出现UpdateOffsetException时的处理方法
    • 相关源码略读
      • 1入口
      • 2处理逻辑
        • 1建立offset与timestamp的对应关系并保存到数据中
        • 2找到最近的最后一个满足 timestamp target_timestamp 的 index
        • 3找到满足该条件的offset数组
      • 3注意事项

获取单个分区的情况

kafka通过offset记录每条日志的偏移量,详见《Kafka文件存储机制那些事》。但是当用户想读取之前的信息时,他是不可能知道这些消息对应的offset的,用户只能指定时间,比如说我从昨天的12点开始读取消息。

这就有个问题了,怎么样将用户定义的时间转化为集群内部的offset呢?

先简单重温一下kafka的物理存储机制:每个topic分成多个分区,而一个分区对应磁盘中的一个目录,目录中会有多个文件,比如:

 00000000000000000000.index  00000000000000000000.log  00000000000001145974.index  00000000000001145974.log

可以看出来,每个segment file其实有2部分,一个index文件,一个log文件。文件名是这个文件内的第一个消息的offset。log文件记录的是实际的消息内容。而index对log文件作了索引,当需要查看某个消息时,如果指定offset,很容易就定位到log文件中的具体位置。详见上面说的文章。

但正如刚才所说,用户不知道offset,而只知道时间,所以就需要转换了。

kafka用了一个很直观很简单的方法:将文件名中的offset与文件的最后修改时间放入一个map中,然后再查找。详细步骤如下:
(1)将文件名及文件的最后时间放入一个map中,时间使用的是13位的unix时间戳
(2)当用户指定一个时间t0时,在map中找到最后一个时间t1早于t0的时间,然后返回这个文件名,即这个文件的第一个offset。
(3)这里只返回了一个分区的offset,而事实上需要返回所有分区的offset,所以对所有分区采取上述步骤。
(4)使用取到的消息,开始消费消息。

举个例子:

w-r--r-- 1 hadoop hadoop 1073181076  8?? 11 10:20 00000000000066427499.log
-rw-r--r-- 1 hadoop hadoop      14832  8?? 11 10:20 00000000000066427499.index
-rw-r--r-- 1 hadoop hadoop 1073187364  8?? 11 10:40 00000000000067642947.log
-rw-r--r-- 1 hadoop hadoop      14872  8?? 11 10:40 00000000000067642947.index
-rw-r--r-- 1 hadoop hadoop 1073486959  8?? 11 11:04 00000000000068857698.log
-rw-r--r-- 1 hadoop hadoop      14928  8?? 11 11:04 00000000000068857698.index
-rw-r--r-- 1 hadoop hadoop 1073511817  8?? 11 11:25 00000000000070069880.log
-rw-r--r-- 1 hadoop hadoop      14920  8?? 11 11:25 00000000000070069880.index
-rw-r--r-- 1 hadoop hadoop   10485760  8?? 11 11:28 00000000000071279203.index
-rw-r--r-- 1 hadoop hadoop  148277228  8?? 11 1

你可能感兴趣的:(X.1大数据)