Problem
我在Kubernetes有一个Kafka设置,有三个经纪人,根据https://github.com/Yolean/kubernetes-kafka指南设置 . 从Java客户端生成消息时出现以下错误消息 .
2018-06-06 11:15:44.103 ERROR 1 --- [ad | producer-1] o.s.k.support.LoggingProducerListener : Exception thrown when sending a message with key='null' and payload='[...redacted...]':
org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for topicname-0: 30001 ms has passed since last append
Detailed setup
侦听器设置为允许来自外部世界的SSL 生产环境 者/消费者:
advertised.host.name = null
advertised.listeners = OUTSIDE://kafka-0.mydomain.com:32400,PLAINTEXT://:9092
advertised.port = null
listener.security.protocol.map = PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL,OUTSIDE:SSL
listeners = OUTSIDE://:9094,PLAINTEXT://:9092
inter.broker.listener.name = PLAINTEXT
host.name =
port.name = 9092
OUTSIDE监听器正在监听kafka-0.mydomain.com,kafka-1.mydomain.com等 . 明文监听器正在侦听任何IP,因为它们是Kubernetes的集群本地 .
制片人设置:
kafka:
bootstrap-servers: kafka.mydomain.com:9092
properties:
security.protocol: SSL
producer:
batch-size: 16384
buffer-memory: 1048576 # 1MB
retries: 1
ssl:
key-password: redacted
keystore-location: file:/var/private/ssl/kafka.client.keystore.jks
keystore-password: redacted
truststore-location: file:/var/private/ssl/kafka.client.truststore.jks
truststore-password: redacted
另外,我在代码中将 linger.ms
设置为100,这迫使消息在100ms内传输 . 延迟时间设置为故意低,因为用例需要最少的延迟 .
Analysis
-
当代理移动到SSL时,错误开始出现 .
-
在服务器端,一切都按预期运行,日志中没有错误,我可以使用Kafka客户端工具手动连接到代理 .
-
错误间歇出现:有时它每秒发送30条消息,有时它根本不发送任何消息 . 它可能像几个小时的魅力,然后只是一段时间的垃圾邮件超时 .
-
客户端和服务器的时钟同步(UTC) .
-
生产环境 和服务器端的CPU始终保持在20%左右 .
会是什么呢?
1 回答
当 生产环境 者比经纪人更快时,通常会出现此问题,因为您的设置发生这种情况的原因似乎是SSL需要额外的CPU,这可能会减慢经纪人的速度 . 但无论如何检查以下内容:
检查您是否以相同的速度生成消息,根据您的说法,您似乎有尖峰 .
另一种可能性是集群中的其他kafka客户端( 生产环境 者或消费者)不一定使用相同的主题,这使得这种情况发生,因为经纪人过载(检查经纪人cpu / network) .
为了最大限度地减少导致此保留的原因,您应该将
buffer-memory
增加到32MB以上,认为32MB是默认设置,并且您将此设置为更低 . 你拥有的越低,缓冲区变满就越容易,如果发生这种情况,最多会阻塞max.block.ms
,并且request.timeout.ms
之后请求会超时 .您应该增加的另一个参数是
batch-size
,此参数以字节为单位,而不是消息数 . 还应该增加linger.ms,如果在用户请求时创建生成器消息,不要增加很多,一个好的选择可能是1-4毫秒 .当
batch.size
变满或需要超过linger.ms
时,将发送消息以获得比batch.size
更多的数据 . 大批量增加了正常情况下的吞吐量,但是如果延迟太低则没有帮助,因为在你有足够的数据来获取batch.size
之前你会发送 .还要在 生产环境 者日志上重新检查属性是否正确加载 .