操作系统调优

  1. 挂载(Mount)文件系统时禁掉 atime 更新

    atime 的全称是 access time,记录的是文件最后被访问的时间。记录 atime 需要操作系统访问 inode 资源,而禁掉 atime 可以避免 inode 访问时间的写入操作,减少文件系统的写操作数。你可以执行 mount -o noatime 命令进行设置。

  2. 文件系统选择

    • 至少选择ext4 或 XFS,尤其是 XFS 文件系统,它具有高性能、高伸缩性等特点,特别适用于生产服务器。

    • ZFS 多级缓存的机制能够帮助 Kafka 改善 I/O 性能

  3. swap 空间的设置

    建议将swappiness 设置成一个很小的值,比如 1~10 之间,以防止 Linux 的 OOM Killer 开启随意杀掉进程

    临时设置:sudo sysctl vm.swappiness=N

    永久设置:修改 /etc/sysctl.conf 文件,增加 vm.swappiness=N,然后重启机器

  4. ulimit -n

    如果设置得太小,你会碰到 Too Many File Open 这类的错误。设置方法

  5. vm.max_map_count

    如果太小,在一个主题数超多的 Broker 机器上,你会碰到 OutOfMemoryError:Map failed 的严重错误。建议设置:655360。

    设置方法:修改 /etc/sysctl.conf 文件,增加 vm.max_map_count=655360,保存之后,执行 sysctl -p 命令使它生效

  6. 操作系统页缓存大小

    给 Kafka 预留的页缓存越大越好,最小值至少要容纳一个日志段的大小,也就是 Broker 端参数 log.segment.bytes 的值。该参数的默认值是 1GB。预留出一个日志段大小,至少能保证 Kafka 可以将整个日志段全部放入页缓存,这样,消费者程序在消费时能直接命中页缓存,从而避免昂贵的物理磁盘 I/O 操作

JVM 层调优

  1. 设置堆大小

    默认将 JVM 堆大小设置成 6~8GB

    设置标准:查询broker的GC log,Full GC 之后堆上存活对象的总大小,然后把堆大小设置为该值的 1.5~2 倍。可手动运行 jmap -histo:live < pid > 就能人为触发 Full GC

  2. GC 收集器的选择

    G1 收集器,如果经常有Full GC,配置-XX:+PrintAdaptiveSizePolicy,查看到底是谁导致的 Full GC。

    **大对象(Large Object)**优化,如果集群中消息体较大(比如超过1MB),一般是指至少占用半个区域(Region)大小的对象。举个例子,如果你的区域尺寸是 2MB,那么超过 1MB 大小的对象就被视为是大对象。要解决这个问题,除了增加堆大小之外,你还可以适当地增加区域大小,设置方法是增加 JVM 启动参数 -XX:+G1HeapRegionSize=N。默认情况下,如果一个对象超过了 N/2,就会被视为大对象,从而直接被分配在大对象区。

Broker 端调优

  1. 即尽力保持客户端版本和 Broker 端版本一致

    Producer -> Broker -> Consumer三端kafka版本要保持一致。版本不一致会令 Kafka 丧失很多性能收益,比如 Zero Copy。

    Producer、Consumer 和 Broker 的版本是相同的,它们之间的通信可以享受 Zero Copy 的快速通道;相反,一个低版本的 Consumer 程序想要与 Producer、Broker 交互的话,就只能依靠 JVM 堆中转一下,丢掉了快捷通道,就只能走慢速通道了

  2. 配置调优

应用层调优

  1. 不要频繁地创建 Producer 和 Consumer 对象实例

  2. 用完及时关闭

    这些对象底层会创建很多物理资源,如 Socket 连接、ByteBuffer 缓冲区等。不及时关闭的话,势必造成资源泄露。

  3. 合理利用多线程来改善性能

    Kafka 的 Java Producer 是线程安全的,你可以放心地在多个线程中共享同一个实例

性能指标调优

1. 调优吞吐量

  • broker端

    • 适当增加num.replica.fetchers参数值,但不超过CPU核数

      表示的是 Follower 副本用多少个线程来拉取消息,默认使用 1 个线程。如果你的 Broker 端 CPU 资源很充足,不妨适当调大该参数值,加快 Follower 副本的同步速度。

      配置了 acks=all 的 Producer 程序吞吐量被拖累的首要因素,就是副本同步性能

    • 调优GC参数,避免频繁的Full GC

  • Producer

    • 适当增加batch.size的值,比如模式16K增加到512KB或1MB
    • 适当增量linger.ms值,比如10-100
    • 设置compression.type=lz4或zstd
    • 设置ack=0或1(消息等级高的主题不建议)
    • 设置retries=0(消息等级高的主题不建议)
    • 如果多线程共享Producer实例,增加buffer.memory的值
  • Consumer

    • 采用多Consumer进程,或线程同时消费
    • 增加fetch.min.bytes参数值,如大于1kb

2. 调优延时

  • broker端
    • 适当增加num.replica.fetchers参数值
  • Producer
    • 减少设置linger.ms,比如为0
    • 不启用消息压缩,compression.type=none
    • 设置ack=1
  • Consumer
    • 设置fetch.min.bytes=1