kafka consumer重复消费问题
在做分布式编译的时候,每一个worker都有一个consumer,适用的kafka+zookeep的配置都是默认的配置,在消息比较少的情况下,每一个consumer都能均匀得到互不相同的消息,但是当消息比较多的时候,这个时候consumer就有重复消费的情况。
如何排查这种问题呢?
最开始以为是系统资源的瓶颈,编译worker和kafka cluster都在一个集群上,导致消息同步不及时,所以就另外找了几个机器,kafka和编译worker分开。但是还是会遇到上述问题。
然后就想集群环境一致性最重要的一个条件是时间,然后将所有的机器都设置了统一的时间服务器,结果还是不行。
最后查看自己写的代码,将缓存队列开大一些,竟然没有重复了。
心想可能是自己使用的方式有点问题:下面是分析的过程
1: 分析重复的情况是什么?是由于不同hosts上重复的消费,还是相同hosts上的重复消费?
经过对比测试,是属于相同hosts上的重复消费,间隔大概为20个message
2: kafka的消息队列模型是什么?
- 一个topic: tizen-unified
- 三个partition:0,1,2
- 一个producer, 三个consumer。
- 每个consumer 端设置一个缓存队列,当队列满的时候,consumer线程进入阻塞的状态,这个时候编译进程从队列中取package进行编译,直到队列为空为止。
如下是consumer端的代码:
#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4
"""gbs-worker - distributed system worker module."""
import os
import re
import Queue
import time
import threading
import multiprocessing
from multiprocessing import Process
from kafka import KafkaConsumer
from kafka import KafkaProducer class Producer(Process):
def __init__(self):
super(Producer, self).__init__()
self.messageHandler = KafkaConsumer('tizen-unified',group_id='tizen-worker',bootstrap_servers='109.123.100.144:9092')
def run(self):
print "start produce, os pid: %d" % (os.getpid())
for message in self.messageHandler: # which will resume if there is a message from kafka
while(WorkerPool.taskQueue.full() is True):
time.sleep(5)
print "put package %s into queue" % message.value
WorkerPool.taskQueue.put(message.value) class GbsBuild(object):
errorRule = re.compile(r"some packages failed to be built")
def __init__(self,packageName, id):
super(GbsBuild, self).__init__()
self.sourcePath = "/home/scm/renjg/workspace"
self.logPath = "/home/scm/renjg/logs"
self.gbsPath = "/usr/bin/gbs"
self.gbsconf = self.sourcePath+"/.gbs.conf"
self.gbsRoot = "/home/scm/GBS-ROOT"
self.packageName = packageName
self.threadId = id
def build(self):
os.system("cd %s" % (self.sourcePath))
os.system("mkdir -p %s" % self.logPath)
result = os.popen("gbs -c %s build -A armv7l -B %s-%d --binary-list %s --clean >%s/%s.log 2>&1" % (self.gbsconf,self.gbsRoot, self.threadId, self.packageName, self.logPath, self.packageName)).read()
if GbsBuild.errorRule.findall(result):
print "%s build error \n log file is: %s/%s.log" % (self.packageName, self.logPath, self.packageName)
return "Fail"
os.system("scp -r %s renjg@109.123.123.6:/home/renjg/GBS-ROOT/local/repos/unified_standard/" % (self.gbsRoot+"-"+str(self.threadId)+"/local/repos/unified_standard/armv7l/"))
print "%s package in process %d ,build done, copy done" % (self.packageName, self.threadId)
return "Success" class Consumer(Process):
def __init__(self, threadId, partition = 0):
super(Consumer,self).__init__()
self.partition = partition
self.threadId = threadId
self.messageHandler = KafkaProducer(bootstrap_servers="109.123.100.144:9092")
def run(self):
print "start consume thread %d , os pid: %d" % (self.threadId, os.getpid())
while True:
while WorkerPool.taskQueue.empty() is True:
time.sleep(1)
packageName = WorkerPool.taskQueue.get()
print "thread %d start %s package " % (self.threadId, packageName)
gbsbuild = GbsBuild(packageName,self.threadId)
print "thread %d building %s package" % (self.threadId, packageName) if gbsbuild.build() == "Success":
#if True:
result = self.messageHandler.send("tizen-unified-status", value = "succeed", key = packageName, partition=0)
if(result.get(60)):
print "send success"
else:
print "send fail"
else:
result = self.messageHandler.send("tizen-unified-status", value = "failed", key = packageName, partition=0)
if(result.get(60)):
print "send success"
else:
print "send fail" class WorkerPool(object):
capcaticy = 4
curThreadNum = 0
taskQueue = multiprocessing.Queue(capcaticy*100) #如果taskQueue很小的话,那么就会出现producer重复的获取消息的情况。
def __init__(self):
self.producer = Producer()
self.consumers = [Consumer(i) for i in xrange(WorkerPool.capcaticy)]
def start(self):
print "start Worker pool"
self.producer.start()
for i in range(0, WorkerPool.capcaticy):
self.consumers[i].start()
self.producer.join()
for i in range(0, WorkerPool.capcaticy):
self.consumers[i].join()
wp = WorkerPool()
wp.start()
print "Done"
当前的改进思路是:扩大WorkerPool.taskQueue的容量,当一次poll就获取足够多的message,然后consumer慢慢处理。
还有一种改进思路是:去掉producer,直接在每一个consumer中间创建一个connection, 把互斥的任务交给kafka去做。待测试。
kafka consumer重复消费问题的更多相关文章
- Apache Kafka(九)- Kafka Consumer 消费行为
1. Poll Messages 在Kafka Consumer 中消费messages时,使用的是poll模型,也就是主动去Kafka端取数据.其他消息管道也有的是push模型,也就是服务端向con ...
- Kafka重复消费和丢失数据研究
Kafka重复消费原因 底层根本原因:已经消费了数据,但是offset没提交. 原因1:强行kill线程,导致消费后的数据,offset没有提交. 原因2:设置offset为自动提交,关闭kafka时 ...
- kafka丢失和重复消费数据
Kafka作为当下流行的高并发消息中间件,大量用于数据采集,实时处理等场景,我们在享受他的高并发,高可靠时,还是不得不面对可能存在的问题,最常见的就是丢包,重发问题. 1.丢包问题:消息推送服务,每天 ...
- 【消息队列】kafka是如何保证消息不被重复消费的
一.kafka自带的消费机制 kafka有个offset的概念,当每个消息被写进去后,都有一个offset,代表他的序号,然后consumer消费该数据之后,隔一段时间,会把自己消费过的消息的offs ...
- kafka一直rebalance故障,重复消费
今天我司线上kafka消息代理出现错误日志,异常rebalance,而且平均间隔2到3分钟就会rebalance一次,分析日志发现比较严重.错误日志如下 08-09 11:01:11 131 pool ...
- Kafka中的消息是否会丢失和重复消费(转)
在之前的基础上,基本搞清楚了Kafka的机制及如何运用.这里思考一下:Kafka中的消息会不会丢失或重复消费呢?为什么呢? 要确定Kafka的消息是否丢失或重复,从两个方面分析入手:消息发送和消息消费 ...
- Kafka如何保证百万级写入速度以及保证不丢失不重复消费
一.如何保证百万级写入速度: 目录 1.页缓存技术 + 磁盘顺序写 2.零拷贝技术 3.最后的总结 “这篇文章来聊一下Kafka的一些架构设计原理,这也是互联网公司面试时非常高频的技术考点. Kafk ...
- kafka如何保证不重复消费又不丢失数据_Kafka写入的数据如何保证不丢失?
我们暂且不考虑写磁盘的具体过程,先大致看看下面的图,这代表了 Kafka 的核心架构原理. Kafka 分布式存储架构 那么现在问题来了,如果每天产生几十 TB 的数据,难道都写一台机器的磁盘上吗?这 ...
- 实际业务处理 Kafka 消息丢失、重复消费和顺序消费的问题
关于 Kafka 消息丢失.重复消费和顺序消费的问题 消息丢失,消息重复消费,消息顺序消费等问题是我们使用 MQ 时不得不考虑的一个问题,下面我结合实际的业务来和你分享一下解决方案. 消息丢失问题 比 ...
随机推荐
- html5 javascript 事件练习3随机键盘
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- Delphi中类的运行期TypeInfo信息结构说明(转载)
Delphi中类的运行期TypeInfo信息结构说明作者:刘啸CnPack开发组 http://www.cnpack.org关键字:RTTI, TypeInfo, TypeData, PropInfo ...
- Solution about MB STAR C4, MB STAR C5 Update and can not test vehicles problems
Solution about MB Star C4, MB Star C5 Update and can not test vehicles problems 1. Make sure your co ...
- ubuntu安装git
安装git,输入sudo apt-get install git 这是unbutu安装东西的简单命令啊 apt-get
- 多条件搜索优化sql
SELECT ctm.* FROM crawltaskmanage ctm,urlmanage um WHERE (ctm.status='0' AND um.`urlId`=ctm.`urlId`) ...
- 20190402Linux进阶命令week1.2
Linux常用命令详解(week1_day1_2) aliasunaliasunamesuhostnamehistorywhichwcwwhowhoamipingkillseqdudffreedate ...
- iperf使用指南
注意:iperf板上版本和PC上版本要一致,至少都要是2或者3,不能一个是2,一个是3. You also get a "connection refused" error whe ...
- 剑指offer(36)两个链表中的第一个公共节点
题目描述 输入两个链表,找出它们的第一个公共结点. 题目分析 我发现关于链表的题都涉及双指针,大家做的时候记得用双指针. 题目理解了就很好做了,比较简单,先在长的链表上跑,知道长的和短的一样长,再一起 ...
- Guitar Pro里自动化编辑器有什么用?如何使用?
我们在使用操作Guitar Pro来进行吉他学习创作时,会遇到下面几个问题.当我们想要改变全部小节或者某一特定小节的拍速时,就会在想,有没有什么简便工具来实现我们的想法呢?告诉大家,Guitar Pr ...
- JavaScript test() 方法
JavaScript test() 方法 JavaScript RegExp 对象 定义和用法 test() 方法用于检测一个字符串是否匹配某个模式. 语法 RegExpObject.test(str ...