从零学习Kafka:调优
迟通常是指消息从 Producer 端生产到 Consumer 端成功消费的总时长。这个值我们希望的越短越好我就是低延迟。可靠性从两个方面理解一是集群整体的稳定性也就是集群会不会出现不可用的情况这点毋庸置疑我们一定是希望稳定性越高越好的。另一方面是消息传输的稳定性也就是会不会丢消息在某些场景下我们可能会舍弃一部分消息传输的可靠性来换取高性能。调优分层明确了目标之后我们把调优的方法按照层级进行划分。我们分为 4 层总的来说越靠上的层级调优效果越好。应用程序层指的是我们客户端的代码即消息的生产和消费逻辑。这些逻辑的优化效果是非常可观的通常也比较简单。框架层在这一层我们通常会调整 Kafka 的各种参数相对也比较简单。JVM 层指的是 Broker 端的 JVM 调优针对 JVM 的调优也能收获不错的效果。操作系统层通常就是 Broker 端部署的操作系统环境的优化。接下来我们就看一下这 4 个层面分别可以做哪些优化。应用程序层我们先来看应用程序层这部分优化可以认为是最简单也是最有效的。但由于每个业务甚至每个开发者写出来的逻辑都不一样对应的优化方法也不一样。因此我无法给出一个“银弹”。不过有一些最基本的准则需要遵循。不要频繁创建 Producer 和 Consumer 实例。用完及时关闭Producer 和 Consumer 对象底层会使用很多物理资源不及时关闭的话可能会造成资源泄漏。合理使用多线程提升性能。框架层框架层可做的调优比较多最基本的就是保持客户端与 Broker 端的版本一致。相同版本的客户端和 Broker 端之间通信可以享受 Zero Copy 的性能收益。接着我们再分别看一下 Producer、Broker 和 Consumer 三部分还有哪些调优操作。Producer首先是生产者它的瓶颈通常在于 CPU 或网络 IO。调优主要从批量发送、压缩算法和确认机制这三方面入手。批量发送批量发送是调优吞吐量的关键主要是调整batch.size和linger.ms这两个参数。其实在前面的文章中我们也有提到过。如果想要高吞吐可以适当调大这两个参数的值。例如batch.size可以从默认的 16KB 调大到 512KB 或者 1MBlinger.ms可以调整到 10 到 100 毫秒。如果想要低延迟我们可以调小这两个参数最极端的方式是linger.ms设置为 0也就是数据不在 Producer 端停留直接发出去。压缩算法压缩可以节省网络 IO但会消耗 CPU 资源。这部分在从零学习Kafka生产者压缩一文中有详细的介绍。如果需要高吞吐推荐使用 lz4 或 zstd 算法。如果需要低延迟就不要开启压缩。确认机制主要调整acks参数。这是性能与可靠性的平衡。想要高性能可以设置acks1即 Leader 收到后就返回。想要高可靠可以设置acksall确保所有副本都同步到消息。Broker再来看 Broker 端的调整。首先是num.replica.fetchers参数它用来控制 Follwer 副本用多少个线程来拉取消息。不论是高吞吐还是低延迟的场景最好都把这个参数调大一点但不要超过 CPU 核数。然后是内存层面Kafka 强依赖操作系统的页缓存因此不要给 Broker 配置太大的 JVM 堆内存通常配置 6 到 10 GB 足够用剩下的留给页缓存。接着到磁盘层面log.dirs可以配置多个磁盘路径Kafka 会在这些路径间分布分区这样可以有效利用多块磁盘的并非 IO 来提升性能。最后到网络层面num.network.threads参数用来指定接收请求的线程数num.io.threads参数用来指定处理磁盘请求的线程数这两个参数都可以适当调大。Consumer最后我们来看消费者端的调优。消费者端有两个核心参数fetch.min.bytes和fetch.max.wait.ms。fetch.min.bytes代表单次抓取的最小数据量fetch.max.wait.ms代表如果数据量不够最长的等待时长。如果是高吞吐场景可以调大这两个参数。相反如果是低延迟场景可以调小这两个参数。我们通过一个表格来小结一下。场景核心参数适用业务高吞吐调大batch.size和linger.ms压缩算法使用 lz4 或 zstd日志收集类场景低延迟linger.ms设置为 0acks设置为 1实时监控告警高可靠acksall和min.insync.replicas至少是 2金融支付等场景至此框架层的调优方法就介绍完了我们继续顺着漏斗往下看。JVM 层Kafka 的 JVM 层的调优和其他服务的 JVM 调优没什么区别。除了我们刚刚提到的不要设置太大的堆内存之外就是要选择合适的垃圾回收器最好使用 G1 和 ZGC 这样更先进的垃圾回收器不光性能更好调优方法也会简单很多。操作系统层操作系统层的调优可能大部分同学不会接触到这里我们简单介绍几个方法。第一是在挂载文件系统时执行下面的命令禁用掉 atime 更新这一调整可以减少文件系统的写操作数。mount -o noatime第二是选择合适的文件系统可以是 ext4 或 XFS。当然如果有性能和可靠性更好的文件系统也可以尝试。总结最后我们来总结一下本文的内容我们首先明确了 Kafka 调优的目标即在高吞吐、低延迟、高可靠三点中找到平衡。接着对调优