kafka本地镜像写入成功编排服务写入失败报错Message contents does not match its CRC

背景

在开发重构pubsubv2的过程中测试发现连接本地kafka镜像写入正常,而连接我们测试服务器的devops里镜像失败。报错信息:

kafka: Failed to produce message to topic Asys.i.bench.D_Asys.i.bench.D: Message contents does not match its CRC.

追查过程

  1. 这个错误曾经我遇到过,问题是因为client在设置config的时候没有吧kafka的version设置正确。所以一开始就针对版本设置进行多次更改,均无效果。
  2. 觉得可能是编排的镜像跟本地镜像有所不同,所以把编排镜像拉到本地启动并请求,发现可以写入成功。更奇怪,同样的镜像启动本地却可以正常写入,远程就不行了。
  3. 怀疑是网络问题。但是ping过延迟只有几毫秒,而且是所有写请求全部错误,不应是网络延迟导致。
  4. 求助同事后找到解决方案。

问题原因

本地写入成功而远程测试机写入不成功的原因是在镜像启动时的参数不同。我编排的kafka镜像启动环境变量设置如下:

KAFKA_PORT='23310'
KAFKA_ADVERTISED_HOST_NAME='KSSCS40000H31904120007'
KAFKA_ZOOKEEPER_CONNECT='KSSCS40000H31904120007:23010'
KAFKA_BROKER_ID='1'
KAFKA_LOG_DIRS='/kafka'
KAFKA_AUTO_CREATE_TOPICS_ENABLE='false'
KAFKA_LOG_CLEANUP_POLICY='compact'
KAFKA_LOG_CLEANER_MIN_COMPACTION_LAG_MS='604800000'
KAFKA_HEAP_OPTS='-Xms6g -Xmx6g -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80'
JMX_PORT='23311'
KAFKA_JMX_OPTS='-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.rmi.port=23311'

其中引起问题的是 KAFKA_LOG_CLEANUP_POLICY=‘compact’ 这个环境变量。 在kafka默认的配置中 KAFKA_LOG_CLEANUP_POLICY=‘delete’ 而我本地启动时用的就是默认配置。
发送代码片段是这么写的:

kafkaTopic := getKafkaTopicName(sub.TopicName, sub.Name)
for _, message := range messages {
   if !publishFilter(sub, message) {
      continue
   }
   value, err := proto.Marshal(message)
   if err != nil {
      continue
   }
   msg := &sarama.ProducerMessage{Topic: kafkaTopic, Value: sarama.StringEncoder(string(value))}
   select {
   case producer.Input() <- msg:
      counterPublishMsgOfSubcription.With(prometheus.Labels{topicLabelName: sub.TopicName, subscriptionLabelName: sub.Name}).Inc()
   case <-ctx.Done():
      break
   }
}

发送不成功的原因在于

  msg := &sarama.ProducerMessage{Topic: kafkaTopic, Value: sarama.StringEncoder(string(value))}

中ProducerMessage没有填写Key这个字段。
由于我们发送message是采用随机的形式而不是key的hash形式所以认为这个字段可以不用填写,一是不知道填写什么,二是觉得也没有用到。 恰恰是这个没有用到就是踩到的坑。
KAFKA_LOG_CLEANUP_POLICY=‘compact’ 时kafka的删除策略采用的是按key保留来做压缩。因此如果写入的message没有Key这个字段就会报错(这个报错信息跟原因不太一致,网上也有相关讨论说CRC报错并不一定与描述相符)。

解决方法

知道问题所在后发送代码相应改成

	msg := &sarama.ProducerMessage{Topic: kafkaTopic, Value: sarama.StringEncoder(string(value)), Key: sarama.StringEncoder(message.Id)}

然后发送成功,问题解决。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值