kafka 跨机房数据同步需求
南京 kafka 集群有 200+ kafka topic 数据需要镜像同步到重庆集群,源 kafka 现状如下:
- (源)南京 kafka 版本:0.10.1.1
- kafka topic partition 个数全部都为 1
- 个别 topic 数据量很大,每天 1 亿条左右,峰值每秒 6w+ message/sec.
- 平均单条消息数据大小: 1KB 左右
kafka-mirror-maker
使用 kafka mirrormaker 可以满足此需求,mirrormaker 是 kafka 官方提供的工具: $KAFAK_HOME/bin/kafka-mirror-maker.sh,在目标 kafka 集群创建好同名 topic,根据使用说明,配置 consumer procuder 配置,topic 信息等,就可以启动 mirror 了。
mirror-maker 的原理大概是启动 consumer 消费南京的 topic message,发送到重庆的 kafka 集群。数据流向:南京 kafka -> mirrormaker -> 重庆 kafka ,其中 mirrormaker 部署在重庆集群。
MirrorMaker 同步数据
> bin/kafka-mirror-maker.sh
--consumer.config consumer-1.properties --consumer.config
--producer.config producer.properties --whitelist my-topic
需要 mirror 的 topic 可以使用 java-style 正则表达式,两个 topic A ,B 可以写成 --whitelist 'A|B'
,如果要 mirror 所有的 topic 可以使用 --whitelist '*'
mirror 速度跟不上的问题
- 数据量大的 topic 消费跟不上,lag 很大,怀疑是单 partition 的问题,而对方反馈,在源集群内,单线程消费是跟得上的。
- 部分数据量不大的 topic lag 也始终存在,超过 1000。
- 调优了 consumer producer 的相关参数,优化效果平平
单 partition 到底有没有问题
对方反馈,集群内,单线程消费大 topic 速度是够的,能达到 6w+ message/sec,试图举证单分区没问题。其中的差异在于 kafka mirrormaker 是走了公网传输,先消费再 push 到目标 kafka 集群。为了验证是否是单 partition 的问题,做了如下测试:
- 跨集群环境下,使用 kafka-console-consumer 单 consumer 消费对方的大 topic
- 跨集群环境下,使用 kafka-console-consumer 单 consumer 消费对方同样的大 topic(10 个分区)
测试结果如下,也验证了 kafka mirrormaker 跨集群环境下,多 parititon 的必要性
- 单 partition 情况下,通过公网传输,消费速度不超过 1500 message/sec,lag 差距巨大;
- 同样的 topic 10 个 partition 下,通过公网传输,消费速度基本可以跟上生产速度,速度可达 1w+ message/sec,lag 差距不大了。
单分区优化前:
image.png
单分区优化后峰值:
image.png
为什么需要多 partition
(kafka topic parititon 为 1) = (数据只在一个 broker 上读写) = (消费端只能单线程消费),增加 parititon,数据可以水平扩展,topic 数据落在均衡的落在不同的 broker 上,生产和消费都是多对多,并行的关系,性能肯定优于单 partition。多对多的读写性能肯定优于单点的点对点读写。
这里有一份 kafka 性能测试报告,很明显的看出,多 partition 在性能上的优势,不管是 produer 写,还是消费者消费,性能都是成倍增长。
实验条件:3 个 Broker,1 个 Topic,3 个磁盘,throughput=1000w,num-records=5000w ,3 个客户端,即三个消费者
测试项目:分别测试消费者为 1, 3 时的吞吐量
当消费者个数有1增为3时,吞吐量由 324MB/s 增加到 1324MB/s。Consumer 消费消息时以 Partition 为分配单位,当只有 1 个 Consumer 时,该 Consumer 需要同时从 3 个 Partition 拉取消息,该 Consumer 所在机器的 I/O 成为整个消费过程的瓶颈,而当 Consumer 个数增加至3个时,多个 Consumer 同时从集群拉取消息,充分利用了集群的吞吐率。对于同一个组内的消费者只允许一个消费者消费一个 partition,不同组之间可以消费相同的 partition。
当然由此也可以看出 kafka 的性能还是很强悍的,万兆网卡的集群内,即使是单 partition 平均写入速度可达 10w records/sec。单线程 consumer 消费速度可达 34w records/sec。也解释了对方说的单 partition 性能能满足的问题。
增加了 partition 数,lag 依然存在
通过 parititon 数,mirromaker 速度基本能跟上源集群,但是 lag 依然存在,处于一个不太可接受的值,超过 2w,部分数据量不大的 topic lag 值也超过 1000。
原因在于 kafka mirrormaker 的参数 --offset.commit.interval.ms,消费 offset 提交间隔,默认使用率 60s,60s 对于生产速度快的 topic 来说很长。
研究了一下这个参数,kafka consumer 配置里面有 old 和 new 之分,其中有个参数 auto.commit.interval.ms 的默认值有变更,旧的 60s 变为 5s,这样能侧面说明新的consumer 是觉得老的这个 60s 的默认配置不够合理,调整到 5s,一个比较合理的值。
3.3.1 Old Consumer Configs
3.3.2 New Consumer Configs
如下图,kafka mirrormaker 默认是使用 new consumer 见下图,但是 commit.interval.ms 配置还是沿用了 old consumer 的默认配置 60s。
image.png
最终结论:
- kafka mirrormaker 大 topic 必须多分区,单分区, 无论怎么调参,速度不超过 2000 message/sec。增加分区 10 个甚至更多,速度可以提升至 20000 message/sec.
- 调小 offset commit 时间间隔,--offset.commit.interval.ms 5000(默认是1分钟),可以减小 lag 差距。
- consumer producer 相关的调优参数,例如 batch size 等可以先使用默认值,遇到瓶颈再调优。
网友评论