写点什么

Kafka 性能调优实战:同等资源配置性能提升 20 几倍的秘诀

用户头像
极客good
关注
发布于: 刚刚

1、抛出问题




笔者最近在折腾数据异构体系,在实现 MySQL 增量数据同步到 MQ(Kafka、RocketMQ),本文的故事就从这里开始。


众所周知,为了提


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


高写入端的并发性能,通常会采用多线程并发机制,提高写入端的性能,接下来基于 MySQL 增量同步到 Kafka 为例,阐述一下第一版的架构方案。



真实的数据同步架构设计复杂性远比上面复杂,上图旨在阐述 Kafka 的使用特点:


为了提高性能,通常会引入多线程,故组内同事直接采用多线程,通过创建多个线程,每一个线程单独创建一个 KafkaProducer 对象,然后 binlog 解析器后,按照分区键进行负载均衡。


但发现,性能非常低下,为什么呢?该如何处理呢?


2、多线程在 Kafka 这里为啥不好使了




当发现性能比较慢,然后又按照 Kafka性能优化指南进行调优,对 linger.ms,batch.size 等参数进行调优,但发现毫无用处,这是为啥呢?



Kafka 的高吞吐率设计的核心要点之一是批处理,即 kafka 在消息发送端引入了一个双端队列,应用程序通过 KafkaProducer 的 send 方法时,会将消息先放入到双端队列,然后 kafka 使用一个异步线程从队列中成批发送消息。


为了确保 sender 线程能一次发送较多数据,kafka 在客户端引入了一个参数 linger.ms,默认为 200ms,即小心进入到缓存区后不会立即被 send 线程发送,而是等待一定时间,这样能提高 send 线程的发送效率,提高吞吐率。


再回到上述到场景,将视角切换到单个线程,在单个线程内,应用方调用 KafkaProducer 后,消息会在缓存区中等待 200ms,但由于是数据同步场景,消息发送使用的是同步发送,这样就会导致不管 send 线程等多久,永远只会有一条消息被发送,每条消息发送还要无缘无故的增加 200ms 的延迟,tps 怎能上去?


第一个优化点:还是基于多线程发送,当多线程共同持有一个 KafkaProducer 对象,这样在同一时间会有更多数据到达 KafkaProducer 的缓存区,Sender 线程就可以实现一次发送多条消息,实现批量发送到效果,从而提升 Kafka 的吞吐率,实现高 TPS,其效果如下图所示:



关键点:对于单个线程,由于要保证消息都顺序性,使用的是同步发送模式。


3、“大杀器”异步发送也能保证顺序




众所周知,在数据异构的架构体系中,通常需要将分库分表的 mysql 数据库中的数据同步到 es,从而实现跨库 join 等复杂查询功能。


数据同步为了确保数据的最终一致性,通常必须保证顺序。但其维度可以为表级别、数据行级别,通常只需要保证同一行数据的不同事件(新增、更新、删除)等事件必须顺序执行,所以在上述的架构中采用的是同步发送。


有没有可能使用异步发送,但同时满足顺序语义呢?


答案当然是可以的,**其设计思路为:将消息分批处理,该批次内部消息并发执行,各个批次顺序执行。**示意图如下:

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
Kafka性能调优实战:同等资源配置性能提升20几倍的秘诀