Kafka 实践
问题描述
配置
Kafka-client 2.x, Spring-Kafka
默认配置
Kafka 三个partition, 使用KafkaListener按group消费。
现象
某天突然发现两个partition出现了Lag堆积,并且一直没有下降。看业务日志有相同消息在不断重复消费。
分析
看日志发现一直在刷,某个partition的任务超过了max.poll.intervals.ms, reassign other partition.
OffsetAndMetadata{offset=3107, metadata=''}} failed: Commit cannot be completed since the group has already rebalanced and assigned the partitions to another member. This means that the time between subsequent calls to poll() was longer than the configured max.poll.interval.ms, which typically implies that the poll loop is spending too much time message processing. You can address this either by increasing the session timeout or by reducing the maximum size of batches returned in poll() with max.poll.records.
思考应该是消息后续的任务执行时间太长了,导致超过了默认时间,kafka server认为任务失败,不断指定新的partition去做,而之前在规定时间外做完的已经不可以提交offset了。
修复
做异步,使用线程池,将consumer收到的消息打到线程池去做,放进去之后即可立刻提交offset。
hotfix之后lag很快消费掉了,恢复正常。
优化
在consumer中最好加入partition, offset 信息到日志中,有助排查问题。
可以在消费时计算Lag信息,提供异常报警。
使用线程池异步在重启时有风险,可能会丢失数据。最好还是加长max.poll.intervals.ms。
对于关键业务统计耗时,并且设置max.poll.intervals.ms时留有余力。
KafkaListener默认一次消费一条 也可以指定 max.poll.records。
在producer端send时指定key,可以确定消费端唯一性。
Demo
Producer
@Resource
private KafkaTemplate kafkaTemplate; @SuppressWarnings("unchecked")
public void sendMessage(String topic, final String message) {
LogUtil.info(LogTypeEnum.APPLICATION, "sending message='{}' to topic='{}'", message, topic);
kafkaTemplate.send(topic, message);
}
Consumer
@KafkaListener(topics = "${topic}", groupId = "groupId",
containerFactory = "kafkaListenerContainerFactory",
autoStartup = "${kafka.consumer.listen.auto.start}",
properties = "max.poll.records=1")
public void businessConsumer(ConsumerRecord<Integer, String> consumerRecord,
@Header(KafkaHeaders.CONSUMER) KafkaConsumer<String, String> consumer) {
LogUtil.info(LogTypeEnum.APPLICATION,
"business log, offset is {}, partition id is {}, received message key is {}, param is {}",
consumerRecord.offset(), consumerRecord.partition(), consumerRecord.key(),
consumerRecord.value());
checkLag(consumer);
}
private void checkLag(KafkaConsumer<String, String> consumer) {
final Set<TopicPartition> topicPartitions = consumer.assignment();
Map<TopicPartition, Long> tailOffsetMap = consumer.endOffsets(topicPartitions);
for (final TopicPartition topicPartition : topicPartitions) {
final long tailOffset = tailOffsetMap.get(topicPartition);
final long currentOffset = consumer.position(topicPartition);
if (tailOffset < currentOffset || (tailOffset - currentOffset) > 30) {
LogUtil.error(LogTypeEnum.APPLICATION,
"kafka consumer lag exception, current offset is {}, max offset is {}",
currentOffset, tailOffset);
}
}
}
Kafka 实践的更多相关文章
- php下kafka实践
Kafka是一种高吞吐的分布式发布订阅消息系统 kafka安装和简单测试 安装kafka 下载 wget https://www-us.apache.org/dist/kafka/2.1.1/kafk ...
- Kafka实践1--Producer
一.Kafka设计原理参考: http://blog.csdn.net/suifeng3051/article/details/48053965?locationNum=2 http://www.cn ...
- Kafka实践
1. kafka发送方法 @Component@Import(KafkaAutoProperties.class)public class KafkaProducer { @Autowired pri ...
- Kafka实践、升级和新版本(0.10)特性预研
本文来自于网易云社区 一.消息总线MQ和Kafka (挡在请求的第一线) 1. 几个应用场景 case a:上游系统往下游系统推送消息,而不关心处理结果: case b:一份新数据生成,需要实时保存到 ...
- python操作kafka实践
1.先看最简单的场景,生产者生产消息,消费者接收消息,下面是生产者的简单代码. ------------------------------------------------------------ ...
- Kafka入门 --安装和简单实用
一.安装Zookeeper 参考: Zookeeper的下载.安装和启动 Zookeeper 集群搭建--单机伪分布式集群 二.下载Kafka 进入http://kafka.apache.org/do ...
- 02_Kafka单节点实践
1.实践场景 开始前的准备条件: 1) 确认各个节点的jdk版本,将jdk升级到和kafka配套的版本(解压既完成安装,修改/etc/profile下的JAVA_HOME,source /etc/pr ...
- kafka消费者
from kafka import KafkaConsumer,TopicPartition import json scrapy_kafka_hosts = ["ip:端口", ...
- 【AI】微软人工智能学习笔记(一)
数据分析平台 01|数据平台概况图示 上面图中所示就是微软人工智能数据平台的相关的技术. 02.1| Cortana Intelligence Suite 从上面图中可以看到, 其中有一个Cortan ...
随机推荐
- C语言memset函数详解
C语言memset函数详解 memset() 的作用:在一段内存块中填充某个给定的值,通常用于数组初始化与数组清零. 它是直接操作内存空间,mem即“内存”(memory)的意思.该函数的原型为: # ...
- Linux安装配置go运行环境
1. 下载go,解压 gz包 wget https://storage.googleapis.com/golang/go1.7.5.linux-amd64.tar.gz tar zxvf go1.7. ...
- 安全开发Java动态代理
关于安全开发的一些思考 之前面试某宝的时候,某人问过我,如果解决开发不懂安全的问题,就比如说SSRF,XEE这样的漏洞,如果一旦发生,应该如果立刻去响应,并帮助开发人员修复漏洞,难道写一个jar包?然 ...
- Am335x SD卡刷eMMC二
犹豫前段时间一直在搞另一个项目,Am335x这个BBlack板就放置一边了.前几天把BBlack板重新拿到手,之前搞得给全忘了.SD卡烧写emmC时突然出现了错误,一直找不到原因,今天终于算是有点眉目 ...
- vim文本编辑及文件查找应用3
文件查找 locate,find两个命令 在文件系统上查找符合条件的文件: 实现工具:locate,find locate命令: 依赖于事先构建好的索引库,索引库可以由下边两种方式构建 系统自动实现( ...
- [转载]pytest学习笔记
pytest学习笔记(三) 接着上一篇的内容,这里主要讲下参数化,pytest很好的支持了测试函数中变量的参数化 一.pytest的参数化 1.通过命令行来实现参数化 文档中给了一个简单的例子, ...
- 03—Code First
Code First模式我们称之为“代码优先”模式,使用Code First模式进行EF开发时开发人员只需要编写对应的数据类(其实就是领域模型的实现过程),然后自动生成数据库.这样设计的 ...
- RHEL6 学习:使用 cryptsetup 给分区加密
RHEL6 学习:使用 cryptsetup 给分区加密 今天学习了 RHEL 对硬盘分区加密的知识,在 RHEL 系统里可以通过使用 cryptsetup 工具对硬盘分区进行加密,加密后的分区需要输 ...
- JavaScript 运算符的优先级
㈠逗号(,)运算符 ⑴使用 , 可以分割多个语句,一般可以在声明多个变量时使用 , : ⑵使用 , 运算符同时声明多个变量 // var a , b , c ; ⑶可以同时声明多个变量并赋值 ...
- AtCoder Beginner Contest 137 D题【贪心】
[题意]一共有N个任务和M天,一个人一天只能做一个任务,做完任务之后可以在这一天之后的(Ai-1)天拿到Bi的工资,问M天内最多可以拿到多少工资. 链接:https://atcoder.jp/cont ...