持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
所有消息都会存储在日志文件内。
每个分区对应目录的格式:topic-name_partition-number(topic-分区号)
# 举个栗子:
# 有个 topic 叫 “TOPICA”
# 有 2 个分区,每个分区在一台机器上,2台机器上分别会有 2个目录:
“TOPICA-0”、“TOPICA-1”
日志文件不会无限增大,只要日志文件超过 1GB (log.segment.bytes 默认值),Kafka 就会创建新的段segment(包含 3个文件:.log、.index、.timeindex)
一个**日志段文件(log segment file)**组成如下:
- 文件日志
.log:实际存储数据,文件名代表起始offset - 索引
index:位移索引,为了快速查找offset - 索引
timeindex:时间戳索引,根据时间快速查找
问题
1)引入索引文件,如何基于二分查找快速定位数据?
先来了解下 索引文件.index 如何生成的?
- 参数
log.index.interval.bytes:默认 4KB,限定了在.log文件中写入多少数据,就往index里写一条索引。 .index文件:是稀疏格式,记录偏移位offset和 对应位置position。.index文件:是按照offset构建索引,按照 升序排序。
回归正题,那是如何定位数据呢?
了解了 .index 构成,这个问题就显而易见了:offset 升序排序,就能使用二分查找,时间复杂度 O(logN)。
举个栗子:.index文件有如下数据,现在搜索 offset = 58892 的数据
Offset | Position |
|---|---|
| 44576 | 141421 |
| 57976 | 142111 |
| 64352 | 143255 |
- 直接二分查找:
58892 > 44576 && 58892 < 64352,直接通过offset = 57976对应的position = 142111到对应的.log文件中查找 - 然后在
.log从那个位置开始查找,找到完整数据。
2)磁盘上的日志文件是按照什么策略定期清理腾出空间的?
不停地往里面写数据,系统磁盘空间迟早会塞满。所以
Kafka一定有一个数据清理的策略的。
Kafka Broker 会在后台启动线程异步进行日志清理,清理策略有:
log.retention.day:默认 7 天,每日会把 7天以前的数据清理掉,包括.log、.index、.timeindex文件log.retention.hours:默认 7 天换算成小时,设置保留多少小时
系统部署一般都都需要考虑这块:
- 核心数据:在
Kafka中,可以保留 7 天,甚至 15天。 - 怕数据丢失?可以重新回放处理一次,让下游消费者再次消费。