kafka 集群重要配置
2025-01-22 08:19:30    2.5k 字   
This post is also available in English and alternative languages.

参数类型划分根据kafka官方文档Apache Kafka - configuartion

注意:如果同时设置了topic级别和全局Broker级别的参数,topic级别参数会覆盖broker参数。


1. boker配置

1.1. log.dirs

kafka保存日志数据的目录;如果有多个用逗号分隔(/home/kafka1,/home/kafka2,/home/kafka3);

官网上的原文是:The directories in which the log data is kept. If not set, the value in log.dir is used。
可能会有些歧义,log data并不是常规意义上的log,而是producer发送到topic的消息数据,broker会将消息留存到磁盘。

如果有条件的话你最好保证这些目录挂载到不同的物理磁盘上,这样做有两个好处:

  • 提升读写性能:比起单块磁盘,多块物理磁盘同时读写数据有更高的吞吐量。
  • 故障转移

1.2. auto.create.topics.enable

是否允许自动创建topic;生产环境、预生产环境建议设置成false。
默认是true,即默认是开启状态。


1.3. message.max.bytes

限制单条消息数据的大小,默认值是1MB;如果producer发送的单条消息数据超过此设置,broker会拒收并返回错误。

如果开启了压缩配置,该参数则表示限制压缩后的消息数据的大小。

此参数与性能直接相关;设置的越大,网络连接、请求线程需要花更多的时间处理请求,还会增加磁盘写入块的大小,从而影响IO。

需要注意:broker中此参数的配置需要与consumer(消费者)中的fetch.message.max.bytes配置进行协调;
如果fetch.message.max.bytesmessage.max.bytes小,那consumer(消费者)无法读取到比较大的消息数据,从而导致消费者被阻塞。


1.4. unclean.leader.election.enable

是否允许Unclean Leader选举;

partition(分区)通过多副本保障高可用,但这些分区副本中只有一个Leader Replica(partition主副本)能对外提供服务;Follower Replica(partition从副本)只是与Leader Replica(partition主副本)同步数据。

当某台机器挂掉后,Leader Replica(partition主副本)无法对外提供服务时,kafka需要在剩下的Follower Replica(partition从副本)中选举出新leader;

并不是所有Follower Replica(partition从副本)都有资格参与竞争Leader的,只有同步数据较多的那些Follower Replica(partition从副本)才有资格竞选,那些数据同步较少的Follower Replica(partition从副本)没有资格做这些事。

在 post_link 编程/后端/component/kafka/kafka_基本概念与术语 kafka_基本概念与术语#ISR(in sync replica) %} 中知道,同步数据较多的Follower Replica(partition从副本)都被kafka维护在了ISR集合中;而同步数据较少的Follower Replica(partition从副本)被维护在OSR集合中;

  • 此参数设置成flase

    只允许ISR集合中的Follower Replica(partition从副本)竞选Leader,坚决不让OSR集合中的的Follower Replica(partition从副本)竞选;
    极端情况下,如果ISR集合中没有其他Follower Replica(partition从副本)了,就选举不出Leader Replica(partition主副本),导致此partition(分区)不可用;

  • 此参数设置成true

    允许从ISR和OSR两个集合中的Follower Replica(partition从副本)竞选Leader;如果选举出的Leader Replica(partition主副本)是OSR集合中的,那就有数据丢失的风险。


1.5. auto.leader.rebalance.enable

Enables auto leader balancing. A background thread checks the distribution of partition leaders at regular intervals, configurable by leader.imbalance.check.interval.seconds. If the leader imbalance exceeds leader.imbalance.per.broker.percentage, leader rebalance to the preferred leader for partitions is triggered.

Apache Kafka - configuration#auto.leader.rebalance.enable

是否允许自动定期检查并进行partition(分区)副本Leader的重选举,默认是true。

需要注意的是,重选举并不是无脑触发的;

创建topic以后,partition(分区)数量可能是自动分配或者后续动态调整,kafka会自动把各个partition(分区)的Leader Replica(partition主副本)均匀分散在各个机器上,这样可以保证每台机器的读写吞吐量都是均匀;

如果某些broker宕机,通过正常的partition(分区)选举以后,Leader Replica(partition主副本)会集中在其他少部分几台broker上, 这会导致少数几台broker的读写请求压力升高,集群负载不均衡;

即便宕机的broker重启之后重新加入集群,其中的partition(分区)也都是Follower Replica(partition从副本),读写请求量很低;

默认情况下,每隔300秒(参数:leader.imbalance.check.interval.seconds)kafka会检查一次集群中broker所承载的Leader Replica(partition主副本)分布/负载是否平衡;
如果一台broker上不平衡Leader Replica(partition主副本)的比例超过10%(参数:leader.imbalance.per.broker.percentage),就会触发partition(分区)副本Leader的重选举;

  • 题外话

    个人觉得,不应该只从切换leader会带来不小的性能消耗,就简单粗暴的认为将其设置成false就行了;

    如果某些broker宕机,通过正常的partition(分区)选举以后,Leader Replica(partition主副本)可能集中在其他少部分几台broker上, 这样会导致少数几台broker的读写请求压力升高;

    如果这些少部分broker所在机器扛不下转移而来的流量,又因为此参数是false没有进行partition(分区)副本Leader的重选举,结果导致雪崩式宕机;

    第三个参数auto.leader.rebalance.enable的影响貌似没什么人提,但其实对生产环境影响非常大。设置它的值为true表示允许Kafka定期地对一些Topic分区进行Leader重选举,当然这个重选举不是无脑进行的,它要满足一定的条件才会发生。
    严格来说它与上一个参数中Leader 选举的最大不同在于,它不是选Leader,而是换Leader!比如LeaderA一直表现得很好,但若auto.leader.rebalance.enable=true,那么有可能一段时间后LeaderA就要被强行卸任换成LeaderB。
    你要知道换一次Leader代价很高的,原本向A发送请求的所有客户端都要切换成向B发送请求,而且这种换Leader本质上没有任何性能收益,因此我建议你在生产环境中把这个参数设置成false。

    理想状态下,应该从集群环境、机器硬件并结合auto.leader.rebalance.enableleader.imbalance.check.interval.secondsleader.imbalance.per.broker.percentage等参数多维度综合考虑;


1.6. num.partitions

指定新创建的topic(主题)包含partition(分区)的数量。

如果创建topic时(手动/自动)没有给出partition(分区)的数量,这个数字将是topic(主题)下partition(分区)数目的默认值。

手动创建topic(主题)时如果指定partition(分区)数量,该参数则不会生效。


1.7. log.retention.{hour|minutes|ms}

设置producer发送到topic(主题)中消息数据留存在kafka中的时间;

默认使用log.retention.hour,默认值是168小时(一周);

log.retention.minuteslog.retention.ms与此参数作用一致;如果配置了log.retention.ms,kafka会优先使用最小值的那个参数。


1.8. log.retention.bytes

设置消息数据保存的总磁盘容量大小;此参数作用在每一个partition(分区)上;

默认值:-1,即在这台broker上保存多少数据都可以,至少在容量方面broker绝对为你开绿灯,不会做任何阻拦;

如果一个topic(主题)有8个partition(分区),log.retention.bytes被设为1G,那此topic(主题)最多可以保留8G数据。

如果同时指定了log.retention.{hour|minutes|ms}log.retention.bytes;只要任意一个条件满足,消息数据就会被删除。


2. topic配置

2.1. retention.ms

topic(主题)需要保留消息数据多长时间,以ms为单位;默认是7天,即:topic只保存最近7天的消息数据;


3. 操作系统配置

3.1. 文件描述符限制

文件描述符资源

通常情况下将它设置成一个超大的值是合理的做法,比如ulimit -n 1000000


3.2. 文件系统类型

这里所说的文件系统指的是如ext3、ext4 或 XFS 这样的日志型文件系统。根据官网的测试报告,XFS的性能要强于ext4,生产环境可以使用XFS;


3.3. Swappiness

一旦设置成0,当物理内存耗尽时,操作系统会触发OOM killer这个组件,它会随机挑选一个进程然后 kill 掉,即根本不给用户任何的预警;

但如果设置成一个比较小的值,当开始使用swap空间时,你至少能够观测到Broker性能开始出现急剧下降,从而给你进一步调优和诊断问题的时间。

可以将swappniess配置成一个接近0但不为0的值,比如1;


3.4. 提交时间

或者说是:Flush落盘时间。

向 Kafka 发送数据并不是真要等数据被写入磁盘才会认为成功,而是只要数据被写入到操作系统的页缓存(Page Cache)上就可以了,随后操作系统根据 LRU 算法会定期将页缓存上的’脏’数据落盘到物理磁盘上。

这个定期就是由提交时间来确定的,默认是5秒。一般情况下会认为这个时间太频繁了,可以适当地增加提交间隔来降低物理磁盘的写操作。

如果在页缓存中的数据在写入到磁盘前机器宕机了,那岂不是数据就丢失了;的确,这种情况数据确实就丢失了,但鉴于 Kafka 在软件层面已经提供了多副本的冗余机制,因此这里稍微拉大提交间隔去换取性能还是一个合理的做法。


4. Reference

  • 《Kafka 核心技术与实战 - 极客时间》