一 、broker级静态参数
1 log.dirs 数据保存路径
在线上生产环境中一定要为log.dirs配置多个路径,比如/home/kafka1,/home/kafka2,/home/kafka3这样。
如果有条件的话你最好保证这些目录挂载到不同的物理磁盘上。这样做有两个好处:
a)提升读写性能: 比起单块磁盘,多块物理磁盘同时读写数据有更高的吞吐量。
b) 能够实现故障转移: 坏掉的磁盘上的数据会自动地转移到其他正常的磁盘上,而且 Broker 还能正常工作
2 zookeeper.connect zooKeeper 相关的最重要的参数
如果你有两套 Kafka 集群,假设分别叫它们 kafka1 和 kafka2(chroot),那么两套集群的zookeeper.connect参数可以这样指定:zk1:2181,zk2:2181,zk3:2181/kafka1和zk1:2181,zk2:2181,zk3:2181/kafka2
3 Broker 连接相关参数:
3.1) listeners 告诉外部连接者要通过什么协议访问指定主机名和端口开放的 Kafka 服务。
CDH默认TCP协议, 只需要配置端口就好(默认 9092, 安全SSL9093), 主机briker id已经指定了
3.2) advertised.listeners : Advertised 的含义表示宣称的、公布的,就是说这组监听器是 Broker 用于对外发布的。
CDH默认未设置,建议在应用级别,不是group level设置。
4 TOPIC管理参数:
4.1)auto.create.topics.enable:是否允许自动创建 Topic。
最好设置成 false,即不允许自动创建 Topic。避免拼写错误导致一些奇怪的topic,统一运维创建。
4.2)unclean.leader.election.enable:是否允许 Unclean Leader 选举。
Kafka 有多个副本, 当lead挂掉了,只有保存数据较多的副本才有资格做leader,落后进度太多的副本没资格做这件事。
当保存数据较多的副本都挂掉了。那是否让落后的副本做leader,此参数起作用。
如果true,则没有leader, false导致数据较少的副本为leader,可能导致数据丢失。建议设置为false(社区来来回回修改过好几次默认值)
4.3)auto.leader.rebalance.enable:是否允许定期进行 Leader 选举
它的值为 true 表示允许 Kafka 定期地对一些 Topic 分区进行 Leader 重选举,当然这个重选举不是无脑进行的,它要满足一定的条件才会发生。严格来说它与上一个参数中 Leader 选举的最大不同在于,它不是选 Leader,而是换 Leader!比如 Leader A 一直表现得很好,但若auto.leader.rebalance.enable=true,那么有可能一段时间后 Leader A 就要被强行卸任换成 Leader B。你要知道换一次 Leader 代价很高的,原本向 A 发送请求的所有客户端都要切换成向 B 发送请求,而且这种换 Leader 本质上没有任何性能收益,因此我建议你在生产环境中把这个参数设置成 false。
如下参数非核心,但是保证系统稳定性还是非常有用。
min.insync.replicas
确保 replication.factor > min.insync.replicas。如果两者相等,那么只要有一个副本挂机,整个分区就无法正常工作了。我们不仅要改善消息的持久性,防止数据丢失,还要在不降低可用性的基础上完成。推荐设置成 replication.factor = min.insync.replicas + 1。
5. 数据保留时间参数(全局)
5.1)log.retention.{hours|minutes|ms}:这是个“三兄弟”,都是控制一条消息数据被保存多长时间。从优先级上来说 ms 设置最高、minutes 次之、hours 最低。
5.2)log.retention.bytes:这是指定 Broker 为消息保存的总磁盘容量大小。
这个值默认是 -1,表明你想在这台 Broker 上保存多少数据都可以
一般做租户隔离才会设置具体值。
5.3)message.max.bytes:控制 Broker 能够接收的最大消息大小。
默认值大约1M, 设置大点没关系。
二、TOPIC级重要参数(topic优先于全局)
1 retention.ms:规定了该 Topic 消息被保存的时长。默认是 7 天
2 retention.bytes
为该 Topic 预留多大的磁盘空间。和全局参数作用相似,这个值通常在多租户的 Kafka 集群中会有用武之地。当前默认值是 -1,表示可以无限使用磁盘空间。
3 max.message.bytes。它决定了 Kafka Broker 能够正常接收该 Topic 的最大消息大小
4 设置TOPIC级别参数:一般创建或修改topic时设置
方式1:
bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic transaction --partitions 1 --replication-factor 1 --config retention.ms=15552000000 --config max.message.bytes=5242880
方式2:(推荐)
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name transaction --alter --add-config max.message.bytes=10485760
三、JVM参数设置
1 heap size:
一个通用的建议:将你的 JVM 堆大小设置成 6GB 吧,这是目前业界比较公认的一个合理值。我见过很多人就是使用默认的 Heap Size 来跑 Kafka,说实话默认的 1GB 有点小,毕竟 Kafka Broker 在与客户端进行交互时会在 JVM 堆上创建大量的 ByteBuffer 实例,Heap Size 不能太小。
KAFKA_HEAP_OPTS:指定堆大小。
KAFKA_JVM_PERFORMANCE_OPTS:指定 GC 参数
启动kafka前设置上述参数,如下:
$> 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.sh config/server.properties
2 GC:
2.1)Java 7,那么可以根据以下法则选择合适的垃圾回收器:
如果 Broker 所在机器的 CPU 资源非常充裕,建议使用 CMS 收集器。启用方法是指定-XX:+UseCurrentMarkSweepGC。
否则,使用吞吐量收集器。开启方法是指定-XX:+UseParallelGC。
2.2)使用 Java 8 了,那么就用默认的 G1 收集器就好了。在没有任何调优的情况下,G1 表现得要比 CMS 出色,主要体现在更少的 Full GC,需要调整的参数更少等,所以使用 G1 就好了。
四、操作系统参数:
1 文件描述限制
ulimit -n 1000000
2 文件系统类型
这里所说的文件系统指的是如 ext3、ext4 或 XFS 这样的日志型文件系统。根据官网的测试报告,XFS 的性能要强于 ext4,所以生产环境最好还是使用 XFS
3 Swappiness
网上很多文章都提到设置其为 0,将 swap 完全禁掉以防止 Kafka 进程使用 swap 空间。我个人反倒觉得还是不要设置成 0 比较好,我们可以设置成一个较小的值。为什么呢?因为一旦设置成 0,当物理内存耗尽时,操作系统会触发 OOM killer 这个组件,它会随机挑选一个进程然后 kill 掉,即根本不给用户任何的预警。但如果设置成一个比较小的值,当开始使用 swap 空间时,你至少能够观测到 Broker 性能开始出现急剧下降,从而给你进一步调优和诊断问题的时间。基于这个考虑,我个人建议将 swappniess 配置成一个接近 0 但不为 0 的值,比如 1。
4 提交时间
最后是提交时间或者说是 Flush 落盘时间。向 Kafka 发送数据并不是真要等数据被写入磁盘才会认为成功,而是只要数据被写入到操作系统的页缓存(Page Cache)上就可以了,随后操作系统根据 LRU 算法会定期将页缓存上的“脏”数据落盘到物理磁盘上。这个定期就是由提交时间来确定的,默认是 5 秒。一般情况下我们会认为这个时间太频繁了,可以适当地增加提交间隔来降低物理磁盘的写操作。当然你可能会有这样的疑问:如果在页缓存中的数据在写入到磁盘前机器宕机了,那岂不是数据就丢失了。的确,这种情况数据确实就丢失了,但鉴于 Kafka 在软件层面已经提供了多副本的冗余机制,因此这里稍微拉大提交间隔去换取性能还是一个合理的做法