- 下半部分主要是 Topic 级别参数、JVM 参数以及操作系统参数的设置
- 正确设置这些参数是搭建高性能 Kafka 集群的关键因素
- Topic 级别参数
- 如果同时设置了 Topic 级别参数和全局 Broker 参数
- 答案就是 Topic 级别参数会覆盖全局 Broker 参数的值,而每个 Topic 都能设置自己的参数值,这就是所谓的 Topic 级别参数
- 更适当的做法是允许不同部门的 Topic 根据自身业务需要,设置自己的留存时间
- 从保存消息方面来考量的话,下面这组参数是非常重要的:
- retention.ms:规定了该 Topic 消息被保存的时长。默认是 7 天,即该 Topic 只保存最近 7 天的消息。一旦设置了这个值,它会覆盖掉 Broker 端的全局参数值。
- retention.bytes:规定了要为该 Topic 预留多大的磁盘空间。和全局参数作用相似,这个值通常在多租户的 Kafka 集群中会有用武之地。当前默认值是 -1,表示可以无限使用磁盘空间。
- 如果从能处理的消息大小这个角度来看的话
- 有一个参数是必须要设置的,即max.message.bytes。它决定了 Kafka Broker 能够正常接收该 Topic 的最大消息大小
- 怎么设置 Topic 级别参数吧
- 创建 Topic 时进行设置
- Kafka 开放了kafka-topics命令供我们来创建 Topic 即可。
- 对于上面这样一条命令,请注意结尾处的--config设置,我们就是在 config 后面指定了想要设置的 Topic 级别参数
- 自带的命令kafka-configs来修改 Topic 级别参数
- JVM 参数
- Kafka 服务器端代码是用 Scala 语言编写的,但终归还是编译成 Class 文件在 JVM 上运行,使用Java 8
- JVM 端设置,堆大小这个参数至关重要
- 将你的 JVM 堆大小设置成 6GB 吧,这是目前业界比较公认的一个合理值
- 我见过很多人就是使用默认的 Heap Size 来跑 Kafka,说实话默认的 1GB 有点小
- JVM 端配置的另一个重要参数就是垃圾回收器的设置,也就是平时常说的 GC 设置
- 如果你依然在使用 Java 7,那么可以根据以下法则选择合适的垃圾回收器:
- 如果 Broker 所在机器的 CPU 资源非常充裕,建议使用 CMS 收集器。启用方法是指定-XX:+UseCurrentMarkSweepGC。
- 否则,使用吞吐量收集器。开启方法是指定-XX:+UseParallelGC。
- 当然了,如果你已经在使用 Java 8 了,那么就用默认的 G1 收集器就好了
- 我们确定好了要设置的 JVM 参数,我们该如何为 Kafka 进行设置呢
- KAFKA_HEAP_OPTS:指定堆大小。
- KAFKA_JVM_PERFORMANCE_OPTS:指定 GC 参数。
- 比如你可以这样启动 Kafka Broker,即在启动 Kafka Broker 之前,先设置上这两个环境变量:
- $> export KAFKA_HEAP_OPTS=--Xms6g --Xmx6g
- $> export KAFKA_JVM_PERFORMANCE_OPTS= -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true
- $> bin/kafka-server-start.shconfig/server.properties
- 操作系统参数
- 来聊聊 Kafka 集群通常都需要设置哪些操作系统参数
- 文件描述符限制
- 文件系统类型
- Swappiness
- 提交时间
- 首先是ulimit -n
- 通常情况下将它设置成一个超大的值是合理的做法,比如ulimit -n 1000000
- 其次是文件系统类型的选择
- 这里所说的文件系统指的是如 ext3、ext4 或 XFS 这样的日志型文件系统
- 根据官网的测试报告,XFS 的性能要强于 ext4,所以生产环境最好还是使用 XFS
- 第三是 swap 的调优
- 因为一旦设置成 0,当物理内存耗尽时,操作系统会触发 OOM killer 这个组件,它会随机挑选一个进程然后 kill 掉,即根本不给用户任何的预警
- 但如果设置成一个比较小的值,当开始使用 swap 空间时,你至少能够观测到 Broker 性能开始出现急剧下降,从而给你进一步调优和诊断问题的时间
- 基于这个考虑,我个人建议将 swappniess 配置成一个接近 0 但不为 0 的值,比如 1
- 最后是提交时间或者说是 Flush 落盘时间
- 这里稍微拉大提交间隔去换取性能还是一个合理的做法
- 向 Kafka 发送数据并不是真要等数据被写入磁盘才会认为成功
- 而是只要数据被写入到操作系统的页缓存(Page Cache)上就可以了
- 随后操作系统根据 LRU 算法会定期将页缓存上的“脏”数据落盘到物理磁盘上
- 这个定期就是由提交时间来确定的,默认是 5 秒
行者无疆,始于足下 行走,思考,在路上