Kafka Broker 配置详解:必要配置、动态更新与源码级实践指南
【免费下载链接】KafkaApache Kafka - A distributed event streaming platform项目地址: https://gitcode.com/GitHub_Trending/kafka4/kafka
本指南基于 Apache Kafka 官方文档 broker-configs.md,系统讲解 broker 的核心必要配置(node.id、log.dirs、process.roles等)、三类动态更新模式(read-only/per-broker/cluster-wide),以及使用kafka-configs.sh在线修改 SSL 密钥库、默认主题配置、日志清理器、线程池与连接配额的方法。读完本文,你将掌握从静态server.properties配置到零停机动态调优的完整 broker 运维能力,并理解其底层实现原理。
一、Broker 的必要配置(Essential Configurations)
在新版本 Kafka(KRaft 模式)中,以下 5 个配置项是 broker 启动所必需的:
| 配置项 | 作用 |
|---|---|
node.id | 当前节点的唯一标识(替代旧版broker.id),必须是非负整数 |
log.dirs | 存储日志文件的目录列表,可逗号分隔多个目录 |
process.roles | 节点的角色,取值为broker、controller或其组合,设置后即进入 KRaft 模式 |
controller.quorum.bootstrap.servers | 用于连接控制器集群(KRaft quorum)的端点列表 |
controller.listener.names | 控制器使用的 listener 名称列表(KRaft 模式下必填) |
仓库中的两个参考配置文件可以直观说明这些必要配置的实际形态:
- config/server.properties(组合节点,同时承担 broker 与 controller 角色):
process.roles=broker,controller node.id=1 controller.quorum.bootstrap.servers=localhost:9093 listeners=PLAINTEXT://:9092,CONTROLLER://:9093 inter.broker.listener.name=PLAINTEXT advertised.listeners=PLAINTEXT://localhost:9092,CONTROLLER://localhost:9093 controller.listener.names=CONTROLLER log.dirs=/tmp/kraft-combined-logs- config/broker.properties(纯 broker 节点,controller 由独立集群承担):
process.roles=broker node.id=2 controller.quorum.bootstrap.servers=localhost:9093 listeners=PLAINTEXT://localhost:9092 inter.broker.listener.name=PLAINTEXT advertised.listeners=PLAINTEXT://localhost:9092 controller.listener.names=CONTROLLER log.dirs=/tmp/kraft-broker-logs从源码看必要配置的定义
这些必要配置的底层定义位于 KRaft 配置类 raft/src/main/java/org/apache/kafka/raft/KRaftConfigs.java,可以看到:
process.roles定义为LIST类型、无默认值,仅允许取值broker、controller,且不允许组合重复;node.id定义为INT类型、无默认值,要求>= 0;controller.listener.names定义为LIST类型、无默认值,要求取值为非空且不重复。
这意味着三个配置一旦缺失,broker 将直接拒绝启动(ConfigException),而不是回退到某个默认值——这正是它们被列为"必要配置"的根本原因。
而broker.id已被标记为弃用:在 core/src/main/scala/kafka/server/KafkaConfig.scala 的fromProps方法中,若检测到broker.id会打印警告,提示它将在 Apache Kafka 5.0 中移除,请改用node.id。
二、完整 Broker 配置的权威来源
所有 broker 配置项及其默认值的完整参考,由 Scala 类kafka.server.KafkaConfig生成。该类位于 core/src/main/scala/kafka/server/KafkaConfig.scala,其main方法会将AbstractKafkaConfig.CONFIG_DEF中的全部配置项连同动态更新模式渲染成 HTML 文档(brokerconfigs_<config>锚点),并叠加 broker 配额等动态配置,供官方文档内嵌展示。
从源码结构看,KafkaConfig继承自org.apache.kafka.server.config.AbstractKafkaConfig,并维护了一个@volatile currentConfig引用与DynamicBrokerConfig实例,这为后续要讲的动态配置热更新提供了基础设施——新配置到达后通过updateCurrentConfig原子替换当前配置快照,而无需重启进程。
三、Broker 配置的动态更新模式
从 Kafka 1.1 版本起,部分 broker 配置可以不重启 broker 而直接在线更新。每一类配置都有明确的更新模式(见官方 Broker Configs 文档中的 "Dynamic Update Mode" 列):
read-only:必须重启 broker 才能生效,不可动态更新;per-broker:可以对单个 broker动态更新,主要用于针对性测试;cluster-wide:可以作为集群级默认值动态更新,也可在测试场景下按 per-broker 值更新。
动态更新能力的分类实现在 server/src/main/java/org/apache/kafka/server/config/DynamicBrokerConfig.java 中,其dynamicConfigUpdateModes()方法将ALL_DYNAMIC_CONFIGS集合中的每个配置名映射为"per-broker"或"cluster-wide";同时nonDynamicConfigs()会筛出只读配置,validateConfigs()会对非法动态更新(例如把只读配置当作动态配置提交、安全配置未加 listener 前缀)抛出ConfigException拒绝。
动态配置的四个层级与优先级
一个配置若在多个层级同时定义,生效优先级从高到低为:
- Dynamic per-broker 配置(存储在 metadata log 中)
- Dynamic cluster-wide 默认配置(存储在 metadata log 中)
- 静态 broker 配置(来自
server.properties) - Kafka 内置默认值(见 Broker Configs 表)
也就是说,动态配置优先级最高,静态文件最低,Kafka 默认值垫底。
四、使用 kafka-configs.sh 管理动态配置
kafka-configs.sh是操作动态配置的官方命令行工具(入口脚本 bin/kafka-configs.sh,最终调用org.apache.kafka.tools.ConfigCommand)。以下示例均以 broker id 0、bootstrap 地址localhost:9092为例。
1. 为单个 broker 添加配置(per-broker)
将 broker 0 的日志清理线程数改为 2:
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-name 0 --alter --add-config log.cleaner.threads=22. 查看单个 broker 的当前动态配置
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-name 0 --describe3. 删除某个配置覆盖
删除 broker 0 的log.cleaner.threads覆盖,使其回退到静态配置或默认值:
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-name 0 --alter --delete-config log.cleaner.threads4. 动态调整 broker 上的日志级别
将 broker 0 上指定 logger(此处为ClientQuotaManager$ThrottledChannelReaper)的日志级别改为 DEBUG:
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 --broker-logger 0 --add-config org.apache.kafka.server.quota.ClientQuotaManager\$ThrottledChannelReaper=DEBUG --alter注意:
$需要转义为\$,避免被 shell 解释为变量。
5. 设置集群级默认配置(cluster-wide)
某些配置可以设置为集群级默认值,让整个集群的 broker 保持一致,所有 broker 都会处理该默认值更新。例如在所有 broker 上将日志清理线程数设为 2:
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-default --alter --add-config log.cleaner.threads=26. 查看当前集群级默认配置
$ bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-default --describe所有可在集群级配置的项,也都可以按 per-broker 配置(例如用于测试)。注意,DynamicBrokerConfig.validateConfigs()会拒绝把只能 per-broker 更新的配置(如 listener 安全配置)提交到--entity-default层级,并提示"broker id must be specified"。
五、动态更新已有 Listener 的 SSL Keystore
生产环境中,broker 常配置较短有效期的 SSL keystore 以降低证书泄露风险。Kafka 支持不重启 broker地动态更新 keystore,配置名必须以 listener 前缀listener.name.{listenerName}.开头,确保只更新指定 listener 的 keystore。以下配置可以在一次 alter 请求中按 per-broker 级别更新:
ssl.keystore.typessl.keystore.locationssl.keystore.passwordssl.key.password
关键约束(来自官方文档语义):
- 若该 listener 是inter-broker listener,只有当新 keystore 被该 listener 配置的 truststore 信任时,更新才被允许;
- 对于其他 listener,broker 不会对 keystore 做信任校验;
- 证书必须由与旧证书相同的 CA签发,避免客户端认证失败。
六、动态更新已有 Listener 的 SSL Truststore
broker 的 truststore 同样可以不重启地动态更新,用于添加或移除证书。更新后的 truststore 会用于新建立的客户端连接的认证。配置名同样必须以listener.name.{listenerName}.前缀限定目标 listener,以下配置可在一次 alter 请求中按 per-broker 级别更新:
ssl.truststore.typessl.truststore.locationssl.truststore.password
关键约束:
- 若该 listener 是inter-broker listener,只有当该 listener 现有的 keystore 被新 truststore信任时,更新才被允许;
- 对于其他 listener,broker 在更新前不做信任校验;
- 若从新 truststore 中移除了用于签发客户端证书的 CA 证书,会导致客户端认证失败——请谨慎操作。
从源码看,SSL 相关的 keystore/truststore 配置全部位于DynamicListenerConfig.RECONFIGURABLE_CONFIGS集合(见 DynamicBrokerConfig.java),并被归入PER_BROKER_CONFIGS,同时securityConfigsWithoutListenerPrefix()强制要求这些安全配置必须携带 listener 前缀才能动态更新,否则直接报错。
七、动态更新默认 Topic 配置
broker 使用的默认主题配置可以不用重启就完成更新。这些配置只作用于没有对应 topic 级覆盖的主题,可以按 cluster-wide 默认级别更新、作用于所有 broker。可更新的配置包括:
| 类别 | 配置项 |
|---|---|
| 日志分段 | log.segment.bytes |
| 滚动策略 | log.roll.ms、log.roll.hours、log.roll.jitter.ms、log.roll.jitter.hours |
| 索引 | log.index.size.max.bytes、log.index.interval.bytes |
| 刷盘 | log.flush.interval.messages、log.flush.interval.ms |
| 保留策略 | log.retention.bytes、log.retention.ms、log.retention.minutes、log.retention.hours |
| 清理器 | log.cleaner.delete.retention.ms、log.cleaner.min.compaction.lag.ms、log.cleaner.max.compaction.lag.ms、log.cleaner.min.cleanable.ratio |
| 清理策略 | log.cleanup.policy、log.segment.delete.delay.ms |
| 可用性 | unclean.leader.election.enable、min.insync.replicas |
| 消息与压缩 | max.message.bytes、compression.type |
| 其他 | log.preallocate、log.message.timestamp.type |
从源码结构看,这一组配置在 DynamicBrokerConfig.java 的DynamicLogConfig.RECONFIGURABLE_CONFIGS中登记,其来源是ServerTopicConfigSynonyms.TOPIC_CONFIG_SYNONYMS——即 broker 级配置名与 topic 级配置名的同义映射表,从而保证"broker 默认值"与"topic 覆盖"两套体系无缝衔接。
八、动态更新 Log Cleaner 配置
Log cleaner(日志清理器)相关配置可以按cluster-wide 默认级别动态更新、作用于所有 broker,改动将在下一轮日志清理迭代时生效。可同时更新一个或多个以下配置:
log.cleaner.threadslog.cleaner.io.max.bytes.per.secondlog.cleaner.dedupe.buffer.sizelog.cleaner.io.buffer.sizelog.cleaner.io.buffer.load.factorlog.cleaner.backoff.ms
九、动态更新线程池配置
broker 使用的多个线程池大小可以按cluster-wide 默认级别动态更新。为了保证更新被优雅处理,更新值被限制在当前值的1/2到2 倍范围内(即currentSize / 2到currentSize * 2)。可更新的配置包括:
num.network.threadsnum.io.threadsnum.replica.fetchersnum.recovery.threads.per.data.dirlog.cleaner.threadsbackground.threadsremote.log.reader.threadsremote.log.manager.copier.thread.pool.sizeremote.log.manager.expiration.thread.pool.sizeremote.log.manager.follower.thread.pool.size
该范围限制在源码中有精确实现:server/src/main/java/org/apache/kafka/server/DynamicThreadPool.java 的validateReconfiguration()方法会逐一校验:
- 新值必须
>= 1; - 新值不能小于当前值的一半(
newValue < oldValue / 2则抛ConfigException); - 新值不能大于当前值的两倍(
newValue > oldValue * 2则抛ConfigException)。
其中num.io.threads、num.replica.fetchers、num.recovery.threads.per.data.dir、background.threads登记在DynamicThreadPool.RECONFIGURABLE_CONFIGS,num.network.threads则在DynamicListenerConfig.RECONFIGURABLE_CONFIGS中,且三者(num.network.threads、max.connections、max.connection.creation.rate)被标记为CLUSTER_LEVEL_LISTENER_CONFIGS,即只能按集群级默认值更新。
十、动态更新连接配额(Connection Quota)
broker 对某个 IP/主机允许的最大连接数可以按cluster-wide 默认级别动态更新,新限制对新建连接立即生效,且已有连接数会计入新配额。可更新的配置:
max.connections.per.ipmax.connections.per.ip.overrides
十一、动态添加与移除 Listener
Listener 可以在线添加或移除,无需重启:
- 新增 listener 时,其安全配置必须以
listener.name.{listenerName}.前缀作为 listener 配置提供; - 若新 listener 使用 SASL,必须通过带 listener 与机制前缀的 JAAS 配置属性
sasl.jaas.config提供 JAAS 配置(详见 Kafka broker 的 JAAS 配置文档); - 除新 listener 的全部安全配置外,以下配置可按per-broker 级别动态更新:
listenersadvertised.listenerslistener.security.protocol.map
兼容性注意点(针对 1.1.x 版本的约束):
- 在 Kafka 1.1.x 中,inter-broker listener 使用的 listener 不能动态更新;
- 要更换 inter-broker listener,可以先在所有 broker 上不重启地添加新 listener,然后通过滚动重启来更新
inter.broker.listener.name; - inter-broker listener 必须始终通过静态 broker 配置
inter.broker.listener.name或security.inter.broker.protocol来指定,不能动态修改。
十二、实践要点总结
- 先静态、后动态:
node.id、process.roles、controller.quorum.bootstrap.servers、controller.listener.names、inter.broker.listener.name等属于只读/启动级配置,必须写在server.properties中;可在线调整的配置优先使用kafka-configs.sh完成。 - 明确更新层级:per-broker 只影响单节点,cluster-wide 影响整个集群;配置生效优先级为「动态 per-broker > 动态 cluster-wide 默认 > 静态文件 > Kafka 默认值」。
- 注意安全校验:SSL keystore/truststore 更新必须带 listener 前缀,inter-broker listener 的更新受信任关系校验约束;线程池更新必须落在
[current/2, current*2]区间内,越界将被源码层的ConfigException拒绝。 - 借助工具验证:修改后使用
bin/kafka-configs.sh --bootstrap-server <addr> --entity-type brokers --entity-name <id> --describe复查当前动态配置,使用--entity-default --describe复查集群级默认值。 - 深入源码:完整配置表由 core/src/main/scala/kafka/server/KafkaConfig.scala 生成;动态更新的分类、校验与优先级实现在 DynamicBrokerConfig.java 与 DynamicThreadPool.java;KRaft 必要配置的定义在 KRaftConfigs.java。
【免费下载链接】KafkaApache Kafka - A distributed event streaming platform项目地址: https://gitcode.com/GitHub_Trending/kafka4/kafka
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考