持续创作,加速成长!这是我参与「掘金日新计划 · 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天。 - 怕数据丢失?可以重新回放处理一次,让下游消费者再次消费。