在 Kafka 中,topic 和 partition 的数据保存在 log.dirs
配置的目录中,我们一般会配置多个不同磁盘的目录来提升 I/O 速率。
我们可以 log.dirs
配置中增添新的目录,服务重启之后,Kafka 会将新的 partition 数据写到新的目录。但是 Kafka 不会自动迁移已存在的 partition 数据目录到新的目录。它也不会自动在多个目录下平衡 partition 数据。
下文讨论扩容后迁移数据的方法:
方法 1 :直接删除存在的数据目录然后配置新的数据目录位置
这种方法让 Kafka 从集群的其他成员复制分区数据。
这会从头开始复制分区数据,所有 partition 会在目录位置之间均匀分配。
复制时间取决于数据规模。如果数据量很大,副本要花很长时间才能加入 ISR 。同时会对网络/集群产生较大负载。另外还有其他的问题,如 ISR 改变、客户端报错。因此这种方法仅适用于小集群(GB 级别的数据规模)。
⚠️ kafka 的 broker-id 保存在 log.dir/meta.properties 文件中,如果没有配置 broker.id
, kafka 默认就会生成新的 broker-id 。为了避免这个问题,记得保存 meta.properties 文件。
方法 2 :移动 partition 目录到新的数据目录(不复制 checkpoint 文件)
和方法 1 类似,但是此时 kafka 只复制被移动的 partition 。
方法 3 :移动 partition 目录和切分 checkpoine 文件
每一个数据目录包含三个 checkpoint 文件,分别是:** replication-offset-checkpoint**, recovery-point-offset-checkpoint 和 cleaner-offset-checkpoint 。这些文件包含该目录中可用分区的最后提交的偏移量,日志结束检查点和清理检查点详细信息。每个文件包含版本号、记录数量,每行一条记录。
我们需要把这些文件复制到新目录并修改。调整新旧目录中的记录。如果有大量分区,这个过程就会很乏味。但这是处理大规模数据最好的方法。通过这种方法,副本将快速加入 ISR 。集群/网络上的负载会更少。
checkpoint 文件
Kafka broker 在每个 log 目录下维护两个 offset checkpoint 文件:
replication-offset-checkpoint recovery-point-offset-checkpoint
这些文件有相同的格式:
- 第一行是版本号
- 第二行是 topic-partiiton 条目的数量
- 剩余的每一行包含每个 partition 的 Replication Offset/Recovery Point Offset
举例
[root@CDC-FD-KAF-A001 kafka-logs]# cat replication-offset-checkpoint
0
13
uplog_es 14 98619311
uplog_es 23 98614875
uplog_dangcdn 17 6076915
__consumer_offsets 42 0
uplog_alibaba 12 1682815
uplog_unknown 4 3082170
uplog_migu 1 1
__consumer_offsets 2 0
uplog_baidu 7 281750596
uplog_unknown 31 3083317
__consumer_offsets 45 0
uplog_unknown 22 3085195
uplog_es 5 98619501