一、连接与引导
bootstrap.servers
(必填) :最少写两个地址,提升容错;格式必须为host:port,host:port
。client.id
:给每个实例取个可读名,方便服务端日志定位。- DNS 策略 :
client.dns.lookup
默认为use_all_dns_ips
;云上/SLB 场景可结合resolve_canonical_bootstrap_servers_only
。
元数据可用性
metadata.max.age.ms
/metadata.max.idle.ms
:控制主动刷新与空闲主题的元数据缓存时间。metadata.recovery.strategy
:默认rebootstrap
,当"已知 broker 全不可用"时,自动回退到bootstrap.servers
重新引导;配合metadata.recovery.rebootstrap.trigger.ms
控制触发时机。
二、可靠性与有序性
acks
:all
最强(默认),要求所有 ISR 确认。enable.idempotence
:默认true
,保证"每条消息写一次"。retries
:默认极大(Int.Max
)。与delivery.timeout.ms
一起构成"最终交付上限"。delivery.timeout.ms
:从send()
返回起到成功/失败的时间上限 (≥request.timeout.ms + linger.ms
)。max.in.flight.requests.per.connection
:默认 5。若 幂等关闭 且 允许重试 且 >1 ,可能乱序;幂等开启时必须 ≤5。
实践建议 :在生产保持
acks=all + enable.idempotence=true + max.in.flight=5
;将delivery.timeout.ms
设为request.timeout.ms
的 2--4 倍以吸收抖动。
三、吞吐与延迟的平衡
linger.ms
:默认 5ms(4.0 新默认)。给批处理攒时间,能显著提高吞吐且通常不劣化 P99。batch.size
:默认 16KiB,上不封顶(取决于可用内存)。单批次上限。buffer.memory
:总缓冲池;过小会频繁阻塞在max.block.ms
。compression.type
:zstd
/lz4
常用。批越大压缩比越好;可配合*.level
精调。max.request.size
:限制单请求体积;同时留意 broker 侧message.max.bytes
/topic 侧max.message.bytes
。
低延迟倾向 :
linger.ms=0~2
、batch.size
中等、compression
轻量或关闭。
高吞吐倾向 :linger.ms=5~50
、batch.size=32~128KiB
、compression=zstd
。
四、分区策略与负载均衡
-
默认分区器:
- 有 key → 哈希到固定分区;
- 无 key → 粘性分区 (sticky),同一分区攒到
batch.size
才切换,提升局部批量率。
-
轮询分区器 :
RoundRobinPartitioner
(新批次开始有已知不均衡问题,见 KAFKA-9965)。 -
自适应分区 :
partitioner.adaptive.partitioning.enable=true
(默认),会"偏爱"快 broker;冷热点明显时很实用。 -
可用性超时 :
partitioner.availability.timeout.ms
非 0 时,长时间不可服务的分区会被临时回避。
五、超时与退避
- 请求超时 :
request.timeout.ms
(默认 30s)。 - 重试退避 :
retry.backoff.ms / .max.ms
指数回退并有 ±20% 抖动。 - 连接退避 :
reconnect.backoff.ms / .max.ms
控制重连节奏。 - 握手超时 :
socket.connection.setup.timeout.ms / .max.ms
控制建连与指数回退上限。
六、安全:SSL / SASL / OAuth
- 传输协议 :
security.protocol
(PLAINTEXT/SSL/SASL_PLAINTEXT/SASL_SSL)。 - TLS :
ssl.enabled.protocols
(默认TLSv1.2,TLSv1.3
)、ssl.keystore.*
、ssl.truststore.*
、ssl.endpoint.identification.algorithm=https
(主机名校验)。 - SASL :
sasl.mechanism
(GSSAPI/SCRAM/OAUTHBEARER...)、sasl.jaas.config
、sasl.login.*
。 - OAuth/OIDC :
sasl.oauthbearer.token.endpoint.url
、jwks.endpoint.url
、expected.audience/issuer
、jwks
刷新与重试退避等。
小贴士:开启 mTLS 时,优先使用 PEM + PKCS#8;留意证书轮转与信任链一致性。
七、事务与 EOS(Exactly-Once Semantics)
transactional.id
:声明后自动隐含幂等;跨会话保持语义。transaction.timeout.ms
:事务最长存活时间;大于 brokertransaction.max.timeout.ms
会被拒。- 一般生产建议 ≥3 台 broker ;开发可调低 broker 的
transaction.state.log.replication.factor
。
八、监控与可观测性
enable.metrics.push
:允许按集群订阅推送客户端指标(默认开)。metrics.recording.level
:INFO/DEBUG/TRACE;生产通常 INFO。metric.reporters
/metrics.sample.window.ms
:按需要接入监控系统。
九、实战配方
1)低延迟 Online 写入
properties
acks=all
enable.idempotence=true
linger.ms=1
batch.size=32768
compression.type=lz4
request.timeout.ms=15000
delivery.timeout.ms=30000
max.in.flight.requests.per.connection=5
2)高吞吐离线导入
properties
acks=all
enable.idempotence=true
linger.ms=20
batch.size=131072
compression.type=zstd
buffer.memory=67108864
request.timeout.ms=60000
delivery.timeout.ms=180000
3)严格有序与去重(幂等强化)
properties
acks=all
enable.idempotence=true
max.in.flight.requests.per.connection=1
retries=2147483647
linger.ms=5
4)OAuth2/OIDC 接入(示例)
properties
security.protocol=SASL_SSL
sasl.mechanism=OAUTHBEARER
sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required;
sasl.oauthbearer.token.endpoint.url=https://idp.example.com/oauth2/token
sasl.oauthbearer.jwks.endpoint.url=https://idp.example.com/.well-known/jwks.json
sasl.oauthbearer.expected.issuer=https://idp.example.com/
sasl.oauthbearer.expected.audience=my-kafka
十、常见坑位与排查清单
- 乱序 :幂等关闭 +
max.in.flight>1
+retries>0
→ 可能乱序。 - 交付超时 :
delivery.timeout.ms < request.timeout.ms + linger.ms
→ 提前失败。 - 批过大 :
batch.size
/max.request.size
过大 + 压缩占用 →buffer.memory
被顶满 ,send()
阻塞。 - 大小上限不一致 :Broker 侧
message.max.bytes
/ topic 侧max.message.bytes
小于客户端max.request.size
。 - TLS 主机名校验失败 :未配置
ssl.endpoint.identification.algorithm
或证书 SAN 不含目标域名。 - 引导失败 :
bootstrap.servers
仅填了一个、DNS 变更未覆盖、或metadata.recovery.strategy=none
。
十一、最小可运行示例(Java)
java
Properties p = new Properties();
p.put("bootstrap.servers", "kafka-1:9092,kafka-2:9092");
p.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
p.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// 稳健默认
p.put("acks", "all");
p.put("enable.idempotence", "true");
p.put("linger.ms", "5");
p.put("batch.size", "32768");
p.put("max.in.flight.requests.per.connection", "5");
p.put("delivery.timeout.ms", "60000");
try (KafkaProducer<String, String> producer = new KafkaProducer<>(p)) {
ProducerRecord<String, String> rec = new ProducerRecord<>("demo", "k", "v");
producer.send(rec).get(); // 同步等待,便于示例与错误处理
}