文章共计 1345 个字,阅读完成需要 4 分钟

Kafka通信网络加SSL后的性能损耗


发布于 2024-09-05 / 33 阅读 / 0 评论 / 0 点赞
kafka默认情况通信网络是plaintext模式的,但是为了通信安全,也支持SSL协议。加SSL后,对Kafka的性能是有一定损耗的。

为了安全起见,我们常常会将Kafka整体通信网络置于SSL协议上。

Kafka通信网络加SSL后,也带来了一定的性能损耗问题。下面我们细致分析下损耗的点,以及提出对应的降低损耗的方案。

1.Producer性能损耗分析

我们一般通过kafka-producer-perf-test.sh脚本来评估kafka的生产性能。

启动测试脚本后,通过jstack工具,可以看到producer线程的堆栈信息,如下图所示:

可以看到,在javax.net.ssl.SSLEngine.wrap方法后,就进入了jdk内置类的执行逻辑。

然后通过arthas工具,检查producer过程中各个阶段的耗时,如下图所示:

可以看到,在一次write方法过程中,耗时最大的是javax.net.ssl.SSLEngine.wrap,占比在70%左右。SSLEngine.wrap方法就是把写的内容进行加密,然后通过网络传输到Broker端。

生产数据时,需要对数据进行加密,调用的是SSLEngine的wrap方法,wrap耗时基本是flush的4倍左右。

实验发现,一次KafkaChannel.write过程耗时0.8ms,在wrap阶段就用了0.4ms,占用了40%的性能消耗。

2.Consumer性能损耗分析

我们一般通过kafka-consumer-perf-test.sh脚本来测试kakfa的消费性能。

同样,启动脚本后,通过jstack工具输出consumer线程的堆栈信息,如下图所示:

这里是main线程,因为consumer是单线程同步工作的。

然后,通过arthas工具,一次网络读过程各个阶段的耗时,如下图所示:

可以看到,耗时最大的是javax.net.ssl.SSLEngine.unwrap,占比在90%。SSLEngine.unwrap正是将从网络中读取的数据进行解密的过程。

实验发现,一次KafkaChannel.read操作,SSLEngine.unwarp解密过程大约占了70%的CPU时间。

3.调化策略

以上可以看出,正是增加了加解密的过程,导致了Kafka吞吐量的下降,或者说生产和消费性能的下降。

所以,调优主要也是在加解密阶段进行,主要有以下三个手段。

(1)生成ssl keystore和truststore时,使用最高效、密钥最低的算法。

研究发现,使用EC算法是最高效,密钥位数最低为256。

-keyalg EC -keysize 256

(2)在客户端和服务端都配置最高效的对称加密套件,配置更高版本的TLS1.3

增加以下三个配置:

ssl.protocol=TLSv1.3
ssl.enabled.protocols=TLSv1.3
ssl.cipher.suites=TLS_AES_128_GCM_SHA256

(3)升级JDK版本

实验发现,高版本的JDK对提升SSLEngine的处理能力有非常大的影响。目前测试了三个版本的OpenJDK,性能对比为:JDK17 > JDK11 > JDK8。JDK17相对JDK8来说,有40%左右的性能提升。

4.调优效果

加SSL与不加SSL对比,正常情况下,会有25%左右的性能损耗,在经过上述调优后,性能损耗可以控制在15%以内,好的时候可以到达8%。