【Kafka系列 04】Kafka 性能调优,怎么做?

这篇具有很好参考价值的文章主要介绍了【Kafka系列 04】Kafka 性能调优,怎么做?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 调优目标

通常来说,调优是为了满足系统常见的非功能性需求。在众多的非功能性需求中,性能绝对是我们最关心的那一个。不同的系统对性能有不同的诉求,比如对于数据库用户而言,性能意味着请求的响应时间,用户总是希望查询或更新请求能够被更快地处理完并返回。

对 Kafka 而言,性能一般是指吞吐量延时

吞吐量,即TPS,是指 Broker 端进程或 Client 端应用程序每秒能处理的字节数或消息数,这个值自然是越大越好。

延时,与类似响应时间,它表示从 Producer 端发送消息到 Broker 端持久化完成之间的时间间隔。这个指标也可以代表端到端的延时(End-to-End,E2E),也就是从 Producer 发送消息到 Consumer 成功消费该消息的总时长。和 TPS 相反,我们通常希望延时越短越好。

总之,高吞吐量、低延时是调优 Kafka 集群的主要目标。

2. 优化漏斗

优化漏斗是一个调优过程中的分层漏斗,我们可以在每一层上执行相应的优化调整。总体来说,层级越靠上,其调优的效果越明显,整体优化效果是自上而下衰减的,如下图所示:

kafka调优,kafka,kafka,分布式

 第 1 层:应用程序层。它是指优化 Kafka 客户端应用程序代码。这一层的优化效果最为明显,通常也是比较简单的。

第 2 层:框架层。它指的是合理设置 Kafka 集群的各种参数。毕竟,直接修改 Kafka 源码进行调优并不容易,但根据实际场景恰当地配置关键参数的值,还是很容易实现的。

第 3 层:JVM 层。Kafka Broker 进程是普通的 JVM 进程,各种对 JVM 的优化在这里也是适用的。优化这一层的效果虽然比不上前两层,但有时也能带来巨大的改善效果。

第 4 层:操作系统层。对操作系统层的优化很重要,但效果往往不如想象得那么好。与应用程序层的优化效果相比,它是有很大差距的。

3. 基础性调优

3.1 操作系统调优

  • 禁掉 atime 更新。在挂载(Mount)文件系统时禁掉 atime 更新。atime 的全称是 access time,记录的是文件最后被访问的时间。记录 atime 需要操作系统访问 inode 资源,而禁掉 atime 可以避免 inode 访问时间的写入操作,减少文件系统的写操作数。可以执行 mount -o noatime 命令进行设置。
  • 文件系统。建议至少选择 ext4 或 XFS。尤其是 XFS 文件系统,它具有高性能、高伸缩性等特点,特别适用于生产服务器。
  • swap空间设置。建议将 swappiness 设置成一个很小的值,比如 1~10 之间,以防止 Linux 的 OOM Killer 开启随意杀掉进程。你可以执行 sudo sysctl vm.swappiness=N 来临时设置该值,如果要永久生效,可以修改 /etc/sysctl.conf 文件,增加 vm.swappiness=N,然后重启机器即可。
  • ulimit -n 和 vm.max_map_count。前者如果设置得太小,你会碰到 Too Many File Open 这类的错误,而后者的值如果太小,在一个主题数超多的 Broker 机器上,你会碰到 OutOfMemoryError:Map failed 的严重错误,因此,建议在生产环境中适当调大此值,比如将其设置为 655360。具体设置方法是修改 /etc/sysctl.conf 文件,增加 vm.max_map_count=655360,保存之后,执行 sysctl -p 命令使它生效。
  • 操作系统页缓存大小。给 Kafka 预留的页缓存越大越好,最小值至少要容纳一个日志段的大小,也就是 Broker 端参数 log.segment.bytes 的值。该参数的默认值是 1GB。预留出一个日志段大小,至少能保证 Kafka 可以将整个日志段全部放入页缓存,这样,消费者程序在消费时能直接命中页缓存,从而避免昂贵的物理磁盘 I/O 操作。

3.2 JVM 层调优

  • 设置堆大小。建议将你的 JVM 堆大小设置成 6~8GB。如果想精确调整的话,建议可以查看 GC log,特别是关注 Full GC 之后堆上存活对象的总大小,然后把堆大小设置为该值的 1.5~2 倍。如果你发现 Full GC 没有被执行过,手动运行 jmap -histo:live < pid > 就能人为触发 Full GC。
  • GC 收集器的选择。强烈建议使用 G1 收集器,主要原因是方便省事,至少比 CMS 收集器的优化难度小得多。

3.3 Brocker 端调优

Broker 端的调优原则:尽力保持客户端版本和 Broker 端版本一致。版本不一致会令 Kafka 丧失很多性能收益,比如 Zero Copy。下面用一张图来说明一下。

kafka调优,kafka,kafka,分布式

图中蓝色的 Producer、Consumer 和 Broker 的版本是相同的,它们之间的通信可以享受 Zero Copy 的快速通道;相反,一个低版本的 Consumer 程序想要与 Producer、Broker 交互的话,就只能依靠 JVM 堆中转一下,丢掉了快捷通道,就只能走慢速通道了。因此,在优化 Broker 这一层时,你只要保持服务器端和客户端版本的一致,就能获得很多性能收益了。

3.4 应用层调优

  • 不要频繁地创建 Producer 和 Consumer 对象实例。构造这些对象的开销很大,尽量复用它们。
  • 用完及时关闭。这些对象底层会创建很多物理资源,如 Socket 连接、ByteBuffer 缓冲区等。不及时关闭的话,势必造成资源泄露。
  • 合理利用多线程来改善性能。Kafka 的 Java Producer 是线程安全的,你可以放心地在多个线程中共享同一个实例;而 Java Consumer 虽不是线程安全的,但我们有很多多线程的方案来改善性能。

4. 性能指标调优

4.1 调优吞吐量

kafka调优,kafka,kafka,分布式
在 Broker 端,参数 num.replica.fetchers 表示的是 Follower 副本用多少个线程来拉取消息,默认使用 1 个线程。如果你的 Broker 端 CPU 资源很充足,不妨适当调大该参数值,加快 Follower 副本的同步速度。因为在实际生产环境中,配置了 acks=all 的 Producer 程序吞吐量被拖累的首要因素,就是副本同步性能。增加这个值后,你通常可以看到 Producer 端程序的吞吐量增加。

在 Producer 端,要改善吞吐量,通常的标配是增加消息批次的大小以及批次缓存时间,即 batch.size 和 linger.ms。它们的默认值都偏小,特别是默认的 16KB 的消息批次大小一般都不适用于生产环境。假设你的消息体大小是 1KB,默认一个消息批次也就大约 16 条消息,显然太小了。

除了这两个,你最好把压缩算法也配置上,以减少网络 I/O 传输量,从而间接提升吞吐量。当前,和 Kafka 适配最好的两个压缩算法是 LZ4 和 zstd,不妨一试。

同时,由于我们的优化目标是吞吐量,最好不要设置 acks=all 以及开启重试。前者引入的副本同步时间通常都是吞吐量的瓶颈,而后者在执行过程中也会拉低 Producer 应用的吞吐量。

最后,如果你在多个线程中共享一个 Producer 实例,就可能会碰到缓冲区不够用的情形。倘若频繁地遭遇 TimeoutException:Failed to allocate memory within the configured max blocking time 这样的异常,那么你就必须显式地增加 buffer.memory 参数值,确保缓冲区总是有空间可以申请的。

在 Consumer 端,提升吞吐量的手段是有限的,你可以利用多线程方案增加整体吞吐量,也可以增加 fetch.min.bytes 参数值。默认是 1 字节,表示只要 Kafka Broker 端积攒了 1 字节的数据,就可以返回给 Consumer 端。

4.2 调优延时

kafka调优,kafka,kafka,分布式

在 Broker 端,可以增加 num.replica.fetchers 值以加快 Follower 副本的拉取速度,减少整个消息处理的延时。

在 Producer 端,消息尽快地被发送出去,所以必须设置 linger.ms=0,同时不要启用压缩。因为压缩操作本身要消耗 CPU 时间,会增加消息发送的延时。另外,最好不要设置 acks=all。我们刚刚在前面说过,Follower 副本同步往往是降低 Producer 端吞吐量和增加延时的首要原因。

在 Consumer 端,保持 fetch.min.bytes=1 即可,也就是说,只要 Broker 端有能返回的数据,立即令其返回给 Consumer,缩短 Consumer 消费延时。

5. 小结

分享一个性能调优的真实小案例。

曾经,我碰到过一个线上环境的问题:该集群上 Consumer 程序一直表现良好,但是某一天,它的性能突然下降,表现为吞吐量显著降低。我在查看磁盘读 I/O 使用率时,发现其明显上升,但之前该 Consumer Lag 很低,消息读取应该都能直接命中页缓存。此时磁盘读突然飙升,我就怀疑有其他程序写入了页缓存。后来经过排查,我发现果然有一个测试 Console Consumer 程序启动,“污染”了部分页缓存,导致主业务 Consumer 读取消息不得不走物理磁盘,因此吞吐量下降。找到了真实原因,解决起来就简单多了。

最后,总结下如何调优Kafka。文章来源地址https://www.toymoban.com/news/detail-839473.html

  • 调优目标:高吞吐量、低延时。
  • 优化漏斗:自上而下分为应用程序层、框架层、JVM 层和操作系统层。层级越靠上,调优的效果越明显。
  • 操作系统层调优的4个关键:挂载文件系统时禁掉 atime 更新;选择 ext4 或 XFS 文件系统;swap 空间的设置;页缓存大小。
  • JVM 层调优的2个关键:堆设置和 GC 收集器。
  • Brocker 端调优的关键:保持服务器端和客户端版本一致。
  • 应用层调优:不要频繁地创建 Producer 和 Consumer 对象实例;用完及时关闭;合理利用多线程来改善性能。
  • 调优吞吐量和延时,参照 2 个参数列表。

到了这里,关于【Kafka系列 04】Kafka 性能调优,怎么做?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis从基础到进阶篇(四)----性能调优、分布式锁与缓存问题

    目录 一、Redis 集群演变 1.1 Replication+Sentinel*高可用 1.2 Proxy+Replication+Sentinel(仅仅了解) 1.3 Redis Cluster 集群 (重点) 1.3.1 Redis-cluster架构图 1.3.2 工作原理 1.3.3 主从切换 1.3.4 副本漂移 1.3.5 分片漂移 二、Redis版本历史(增加了解) 三、Redis 5.0 源码清单 (对源码感兴趣的,看一下

    2024年02月09日
    浏览(34)
  • 【大数据工具】Kafka伪分布式、分布式安装和Kafka-manager工具安装与使用

    Kafka 安装包下载地址:https://archive.apache.org/dist/kafka/ 1. Kafka 伪分布式安装 1. 上传并解压 Kafka 安装包 使用 FileZilla 或其他文件传输工具上传 Kafka 安装包: kafka_2.11-0.10.0.0.tgz 解压安装包 2. 编辑配置文件 3. 拷贝并修改配置文件 分别修改 server2.properties、server3.properties 4. 创建日志

    2024年02月14日
    浏览(34)
  • 【分布式应用】kafka集群、Filebeat+Kafka+ELK搭建

    主要原因是由于在高并发环境下,同步请求来不及处理,请求往往会发生阻塞。比如大量的请求并发访问数据库,导致行锁表锁,最后请求线程会堆积过多,从而触发 too many connection 错误,引发雪崩效应。 我们使用消息队列,通过异步处理请求,从而缓解系统的压力。消息队

    2024年02月16日
    浏览(28)
  • 分布式 - 消息队列Kafka:Kafka 消费者的消费位移

    01. Kafka 分区位移 对于Kafka中的分区而言,它的每条消息都有唯一的offset,用来表示消息在分区中对应的位置。偏移量从0开始,每个新消息的偏移量比前一个消息的偏移量大1。 每条消息在分区中的位置信息由一个叫位移(Offset)的数据来表征。分区位移总是从 0 开始,假设一

    2024年02月12日
    浏览(35)
  • 分布式消息服务kafka

    什么是消息中间件? 消息中间件是分布式系统中重要的组件,本质就是一个具有接收消息、存储消息、分发消息的队列,应用程序通过读写队列消息来通信。 例如:在淘宝购物时,订单系统处理完订单后,把订单消息发送到消息中间件中,由消息中间件将订单消息分发到下

    2024年02月01日
    浏览(35)
  • 分布式 - 消息队列Kafka:Kafka消费者的分区分配策略

    Kafka 消费者负载均衡策略? Kafka 消费者分区分配策略? 1. 环境准备 创建主题 test 有5个分区,准备 3 个消费者并进行消费,观察消费分配情况。然后再停止其中一个消费者,再次观察消费分配情况。 ① 创建主题 test,该主题有5个分区,2个副本: ② 创建3个消费者CustomConsu

    2024年02月13日
    浏览(32)
  • 分布式 - 消息队列Kafka:Kafka生产者发送消息的方式

    不管是把Kafka作为消息队列、消息总线还是数据存储平台,总是需要一个可以往Kafka写入数据的生产者、一个可以从Kafka读取数据的消费者,或者一个兼具两种角色的应用程序。 Kafka 生产者是指使用 Apache Kafka 消息系统的应用程序,它们负责将消息发送到 Kafka 集群中的一个或多

    2024年02月13日
    浏览(32)
  • 分布式 - 消息队列Kafka:Kafka生产者架构和配置参数

    生产者发送消息流程参考图1: 先从创建一个ProducerRecord对象开始,其中需要包含目标主题和要发送的内容。另外,还可以指定键、分区、时间戳或标头。在发送ProducerRecord对象时,生产者需要先把键和值对象序列化成字节数组,这样才能在网络上传输。 接下来,如果没有显式

    2024年02月13日
    浏览(35)
  • 分布式 - 消息队列Kafka:Kafka消费者和消费者组

    1. Kafka 消费者是什么? 消费者负责订阅Kafka中的主题,并且从订阅的主题上拉取消息。与其他一些消息中间件不同的是:在Kafka的消费理念中还有一层消费组的概念,每个消费者都有一个对应的消费组。当消息发布到主题后,只会被投递给订阅它的每个消费组中的一个消费者

    2024年02月13日
    浏览(33)
  • 分布式 - 消息队列Kafka:Kafka 消费者消息消费与参数配置

    01. 创建消费者 在读取消息之前,需要先创建一个KafkaConsumer对象。创建KafkaConsumer对象与创建KafkaProducer对象非常相似——把想要传给消费者的属性放在Properties对象里。 为简单起见,这里只提供4个必要的属性:bootstrap.servers、key.deserializer 和 value.deserializer。 ① bootstrap.servers 指

    2024年02月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包