因为程序从kafka里某一个topic读取的数据量过大,所以想看看这topic一天共有多少数据量,到底是不是读取的api有问题。
登录到该topic某一个paritition所在的机器上,进入到kafka-logs目录下该topic-partition的子目录。子目录中存储的数据文件如下
-rw-r--r-- 1 root root 906048 12月 22 10:57 00000000000013128029.index
-rw-r--r-- 1 root root 1073741161 12月 22 10:57 00000000000013128029.log
-rw-r--r-- 1 root root 1360104 12月 25 21:00 00000000000013622079.index
-rw-r--r-- 1 root root 1073737654 12月 25 21:00 00000000000013622079.log
-rw-r--r-- 1 root root 10485760 12月 28 15:49 00000000000014923211.index
-rw-r--r-- 1 root root 993289158 12月 28 15:50 00000000000014923211.log
每一个index和log文件是一对,当log文件大到一定阀值后,就会生成一对新的index和log文件,文件名上的数字,就是这对log文件开始存储的offset。
以 00000000000013622079.log 为例,这个文件的创建时间就是其第一条数据的接收时间,修改时间就是最后一条数据接收时间
stat 00000000000014923211.log
File: `00000000000014923211.log'
Size: 993355992 Blocks: 2731904 IO Block: 4096 regular file
Device: 810h/2064d Inode: 1073756571 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2016-12-25 21:00:30.775876656 +0800
Modify: 2016-12-28 15:50:37.844860136 +0800
Change: 2016-12-28 15:50:37.844860136 +0800
而它下一个文件 00000000000014923211.log 名字上的offset,就是其最后一个数据的offset+1。
所以,在2016-12-25 21:00:30到2016-12-28 15:50:37这段时间内,该partition共收到数据14923211-13622079=1301132条。
那对于最后一个还没有被旋转的文件,又需要怎么看呢?
index文件是对log文件的索引,里面存储了对应log文件里的数据条数和其对应的文件偏移量的映射关系。文件是二进制的,可以用hexdump -C查看。
同样以 00000000000013622079.index 为例
00000000 00 00 00 04 00 00 11 6d 00 00 00 0b 00 00 21 90 |.......m......!.|
00000010 00 00 00 0f 00 00 44 dc 00 00 00 13 00 00 7c 5d |......D.......|]|
...
0014c0d0 00 13 da 77 3f ff a0 db 00 13 da 7f 3f ff b1 be |...w?.......?...|
0014c0e0 00 13 da 83 3f ff e1 31 |....?..1|
0014c0e8
index数据结构是:4Bytes的offset相对偏移,4Bytes的物理文件偏移。index并不是对每一个数据都记录的文件偏移,这样比较节省空间。
上述输出结果翻译可得
4,4461
11,8592
15,17628
...
1301111,1073717467
1301119,1073721790
1301123,1073733937
第一行代表该文件的第4条数据,就是该partition内offset为(13622079+4)的这条数据,可以从该log文件的4461位置开始读。
最后一行的offset为1301123,与该文件内总数据条数1301132差不多。
所以,用同样的方法查看最后一个index文件,就可以知道当前该partition的最大offset是多少了。
补充一点,
kafka api在试图读取某一个时间开始的数据时,是先通过log文件的最后修改时间定位到某一个log文件,然后再在该log文件里进一步查找。
我之前迁移过一个kafka broker,导致某一个partition内log文件的修改时间都是很新的日期,kafka api读取是就会报offsetOutOfRange的错误。
解决方法:手动修改文件的modify time...
touch -d "20161209 17:00:00" 00000000000005284459.log