红帽白皮书新鲜出炉!点击获取,让你的云战略更胜一筹! 了解详情
写点什么

谁是性能杀手?Kafka 多 Topic 下启用 SSL 时延增大问题分析

  • 2019-10-23
  • 本文字数:2138 字

    阅读完需:约 7 分钟

谁是性能杀手?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 接口


本文转载自公众号中间件小哥(ID:huawei_kevin)。


原文链接:


https://mp.weixin.qq.com/s/VJMHdEgTYsLK_2TGFrqyKA


2019-10-23 11:21820

评论

发布
暂无评论
发现更多内容

疫情之年 下半年区块链应用落地会加速么?

CECBC

区块链 场景应用落地

Executor看不懂?教你如何盘它

Edison

后端 线程池

从数据中台到AI中台,企业到底要建什么中台?

脑极体

ARTS Week8

丽子

learn go with tests 学习笔记(六)进程同步

半亩房顶

Go 语言

政策加持迎来区块链技术应用“红利期”

CECBC

关于微服务架构思考

Arthur

LeetCode题解:24. 两两交换链表中的节点,递归,JavaScript,详细注释

Lee Chen

大前端 LeetCode

RocketMQ源码解析-开篇

Edison

RocketMQ 中间件

MySQL事物-学习笔记

Edison

MySQL 数据库 数据库事务

2.1.2 类加载器的工作原理与自定义加载器 -《SSM深入解析与项目实战》

谙忆

learn go with tests 学习笔记(七)反射

半亩房顶

反射 Go 语言

《effective-go》 学习笔记

半亩房顶

Go 语言

nested exception is java.lang.IllegalStateException: refreshAfterWrite requires a LoadingCache异常解决

谙忆

话题讨论 | 特朗普正式封禁微信,iPhone 和微信二选一?

InfoQ写作社区官方

写作平台 话题讨论

数据采集能力受限?企业数字化运营如何迈出第1步

易观大数据

List 和 Map 的排序

一盐难进

Java

你为什么还在用存储过程?

架构师修行之路

数据库设计 架构设计

我是如何参与硅谷顶级开源项目并赚得2500美金

阿水

硅谷 Minio

以区块链为基础 通证经济是下一代互联网的数字经济

CECBC

区块链 落地应用

原来你是这样的B+树

Java技术宝典

B+树

DevOps 技术栈

柴锋

Linux DevOps 运维 敏捷 Shell

零代码/无代码 vs 低代码 如何分类?如何区别?到底有什么不同?分析超过20款零代码低代码产品

代码制造者

编程 低代码 行业资讯 零代码

用户体验(UX)设计≠用户界面(UI)设计

刘华Kenneth

敏捷 设计 UX 用户体验

“啰嗦”是成事唯一正确的方法

霍太稳@极客邦科技

团队管理 个人成长 团队协作 沟通

Python爬取微信公众号文章保存到数据库

wjchenge

500行代码写一个俄罗斯方块游戏

程序员生活志

消息疯狂堆积!RocketMQ出Bug了?

Edison

RocketMQ 中间件

踩坑记 | Flutter升级影响了NestedScrollView?

哈利迪

android

真正的勇士,会跨过六道裂谷,奔向云与AI的彼端

脑极体

# spring boot自定义线程池进行异步调用

一盐难进

Java

谁是性能杀手?Kafka多Topic下启用SSL时延增大问题分析_文化 & 方法_中间件小哥_InfoQ精选文章