谁是性能杀手?Kafka多Topic下启用SSL时延增大问题分析
问题背景
项目中将Kafka接口进行RESTful封装,在使用RESTful接口进行性能测试时,发现Topic数增多后,开启SSL与非SSL进行测试,发现开启SSL后性能下降得厉害。例如600个Topic总数每个Topic3分区3副本的场景下,使用1200个线程只发送10个Topic,开启SSL的TPS只有3100,但是不开启SSL性能达到11000。
其中测试客户端会启动多个线程,每个线程采用同步发送的方式调用RESTful API发送,即每次发送成功一条后才发送下一条。 客户端会根据发送线程在Topic数之间进行均分,例如1200个线程发送10个Topic,则每个Topic同时有120个线程进行发送。
定位与分析过程
1.SSL性能下降
1.定位分析
开启SSL是会导致性能下降的, 主要来自于CPU的耗时与JVM的具体实现,参见Kafka官网的解释:

从我们之前测试的结果来看,高可靠场景SSL性能下降并没有太厉害(从2.3W TPS下降到2.1W TPS)。应该是触发了某些其他问题。通过JStack查看启动SSL下的堆栈,发现存在一些发送线程被Block住:


这个堆栈里面做的事情,是来自于java.security.SecureRandom要产生随机数,采用”SHA1PRNG”算法。在sun/oracle的jdk里,这个随机算法的的实现在底层依赖到操作系统提供的随机数据,默认用的是/dev/random,在读取时,/dev/random设备会返回小于熵池噪声总数的随机字节。/dev/random可生成高随机性的公钥或一次性密码本。若熵池空了,对/dev/random的读操作将会被阻塞,直到收集到了足够的环境噪声为止。这个问题在网上也查到,主要是JDK提供的SecureRandom函数存在1个全局的锁,在熵源不足且SSL线程多的时候很容易碰到这个问题,具体见:
https://github.com/netty/netty/issues/3639
http://bugs.java.com/view_bug.do?bug_id=6521844
2.解决措施
措施一:更新JDK
目前这个问题是在OpenJDK 1.8中解决了,可以通过升级JDK到使用OpenJDK,但是这个方案不太好替换,并且OpenJDK和原来有什么不兼容还不清楚。
措施二:采用非阻塞的熵源: /dev/urandom
通过设置-Djava.security.egd=file:/dev/./urandom宏,随机数时选择/dev/urandom,它会重复地使用熵池中的数据以产生伪随机数据避免阻塞,不过随机安全性会降低。
2.Topic多情况下性能下降
1.定位分析
发现在Topic600个情况下,非SSL与SSL的时延其实差距并没有原先发现的问题那么大,以下是我们用SDK接口测试的时延数据:
600个 Topic总量下,400个线程同时发送10个Topic,非SSL与SSL时延对比:

可以看出时延差距在20%之内,主要的时延增加来自于Topic增多导致的。
为什么Topic增多会导致时延增多?针对这个问题通过在程序进行打点测试,以下是在不同的Topic数量情况下,针对10个Topic,总发送5000条消息的场景下,非SSL时延对比:

其中总时延 = 消息的待发送队列等待时延 + 服务端处理平均时延 + 网络发送与响应时延。
从上面的表格可以看出基本上每个处理环节上都增加了时延4~5倍。为什么会出现这种情况?分析如下可能点:
1、磁盘的写速度变慢
2、Server由于Topic多需要过滤信息变慢
3、复制处理在多Topic下变慢。即使无数据,多Topic下复制线程也会一直发送空请求
4、Topic多资源占用大
通过逐一分析、排除与测试,主要原因还是在第三点:服务端在复制处理在Topic数量多的情况下变慢导致的。
例如10个Topic的时候,如果用10个复制线程(目前性能测试就是配置10)用于副本复制,则每个复制线程会分配到1个Topic;而当Topic有600个的时候,如果还是10个复制线程用于副本复制,则每个复制线程会分配到60个Topic。 如果此时只发送前10个Topic的时候,很有可能只有1个复制线程在工作,其他的复制线程由于分配到的Topic没有数据,基本处于空闲状态。
2.解决措施
既然复制线程变慢,我们可以通过继续增加复制线程的方式提高性能,在600个Topic场景只发送10个Topic场景下,我们把复制线程提升到60个,这样10个Topic能尽可能分配到不同的复制线程中,提高了复制的速度。以下是实际测试结果:

可以看到增加到60个fetch线程后,时延变为100ms左右。同时原来的环境下,通过增加复制线程(修改配置num.replica.fetchers=60),在原环境下1200个发送线程即使启动SSL,性能也能达到11000+。
性能提升措施总结
RESTful API是同步接口,但是内部使用的SDK接口是异步发送。根据高可靠场景下异步发送的能力能达到2W+ TPS来看,主要还是同步接口的并发压力上不去导致的,可以通过以下措施来改进:
1、增加请求等待时间linger.ms
通过在客户端增加参数linger.ms,使得每个请求回等待指定的时间后再发送,使得每个请求可以发送更多的数据,即增加合包率。
2、增加同步发送对同1个Topic的并发数量
3、减少Topic的分区数
因为目前RESTful API并没有用尽服务端的能力(1个分区的能力瓶颈还没达到),默认的3个分区是浪费资源,并且会导致合包率降低,如果采用1个分区,则同样的压力下,合包率能提升3倍,这样性能也能提升。这个措施还可以支持更多的Topic数。
4、增加复制线程
5、考虑提供异步发送SDK接口
谁是性能杀手?Kafka多Topic下启用SSL时延增大问题分析的更多相关文章
- Kafka中Topic级别配置
一.Kafka中topic级别配置 1.Topic级别配置 配置topic级别参数时,相同(参数)属性topic级别会覆盖全局的,否则默认为全局配置属性值. 创建topic参数可以设置一个或多个--c ...
- Kafka的Topic、Partition和Message
Kafka的Topic和Partition Topic Topic是Kafka数据写入操作的基本单元,可以指定副本 一个Topic包含一个或多个Partition,建Topic的时候可以手动指定Par ...
- 伪共享(false sharing),并发编程无声的性能杀手
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...
- (一)kafka修改topic分区的位置
(一)kafka修改topic分区的位置 环境:kafka_2.10-0.8.2.1 + JDK1.7.0_80 1. 查看分区topic的分区分布 $ le-kafka-topics.sh --de ...
- kafka删除topic的方法及我在kafka上边的一些经验
我在本地做kafka的producer调试,每隔一段时间后,所使用的topic管道就会堆积数据,而且我这边使用的是 kafka bin 下的consumer命令单独消费的,每次都是 --fro ...
- [Spark][kafka]kafka 的topic 创建和删除试验
kafka 的topic 创建和删除试验 zookeeper和kafka 的安装,参考: http://www.cnblogs.com/caoguo/p/5958608.html 参考上述URL后,在 ...
- 052 kafka对topic的增删改查操作
一:create 1.开始使用命令 2.创建 bin/kafka-topics.sh --create --topic beifeng --zookeeper linux-hadoop01.ibeif ...
- kafka 删除topic清空数据
原 kafka 删除topic清空数据 2018年11月20日 18:17:50 Ming! 阅读数:1391 版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...
- 【云和恩墨】性能优化:Linux环境下合理配置大内存页(HugePage)
原创 2016-09-12 熊军 [云和恩墨]性能优化:Linux环境下合理配置大内存页(HugePage) 熊军(老熊) 云和恩墨西区总经理 Oracle ACED,ACOUG核心会员 PC S ...
随机推荐
- navicate备份与还原数据库
参考:https://jingyan.baidu.com/article/574c521977dea06c8d9dc1b1.html 1.备份数据库 首先新建数据库 选中数据库下方的“备份”,右击“新 ...
- windows中彻底卸载mysql
1)停止MySQL服务 打开控制面板→管理工具→服务(找到MySQL) 2)卸掉mysql server 打开控制面板→程序与功能→找到mysql server然后卸载 3)将mysql目录下的安装文 ...
- Linux系统中使用lftp命令实现FTP上传下载
Linux 下常用的操作命令有 ftp. lftp 和 sftp,图形化界面非常好用的有 FileZilla.不过在服务器命令界面中,lftp使用比较方便,功能也比ftp更加强大.lftp的界面很像L ...
- MVC Remote属性验证
模型验证方式一: 1.需要添加引用: using System.Web.Mvc; 2.在模型属性上添加验证: [Remote("CheckIsHaveSerialNo", &quo ...
- 详解Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- Laya 分帧加载优化
Laya 分帧加载优化 @author ixenos Flash中的EnterFrame事件在Laya中等同于Laya.timer.frameLoop(1,...) Laya.timer.frameL ...
- 68. 使用thymeleaf报异常:Not Found, status=404【从零开始学Spring Boot】
[从零开始学习Spirng Boot-常见异常汇总] 我们按照正常的流程编码好了 controller访问访问方法/hello,对应的是/templates/hello.html文件,但是在页面中还是 ...
- 【三分+精度问题】G. Toxophily
https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/G [题意] 已知人的坐标在(0,0),靶的位置在(x,y),人以速度v射箭并且射 ...
- POJ 3620 Avoid The Lakes
http://poj.org/problem?id=3620 DFS 从任意一个lake出发 重置联通的lake 并且记录 更新ans #include <iostream> #inclu ...
- Contest Hunter #46 T1 磁力块 [花式暴力]
将所有石头按距离远近排序,将所有取到的时候扔进堆里维护最大磁力强度. 贪心,每次用强度最强的磁石尝试吸引地上的石头,扫完区间以后,这块石头就再也不会用到了. 在此基础上可以做些小优化,比如说优化未取石 ...