kafka多线程消费topic的问题
案例:
topic:my-topic,分区:6
消费者:部署三台机器,每台机器上面开启6个线程消费。
消费结果:只有一台机器可以正常消费,另外两台机器直接输出六条告警日志:
No broker partitions consumed by consumer thread my-topic-group_adfc6be4a509-1496976531798-d70f9a43-3 for topic my-topic
No broker partitions consumed by consumer thread my-topic-group_adfc6be4a509-1496976531798-d70f9a43-1 for topic my-topic
No broker partitions consumed by consumer thread my-topic-group_adfc6be4a509-1496976531798-d70f9a43-2 for topic my-topic
No broker partitions consumed by consumer thread my-topic-group_adfc6be4a509-1496976531798-d70f9a43-4 for topic my-topic
No broker partitions consumed by consumer thread my-topic-group_adfc6be4a509-1496976531798-d70f9a43-6 for topic my-topic
No broker partitions consumed by consumer thread my-topic-group_adfc6be4a509-1496976531798-d70f9a43-5 for topic my-topic
在源码分析之前,先给个图示吧,花了两个小时才画完。

源码分析:
for (topic <- ctx.myTopicThreadIds.keySet) {
// curConsumers = 6*3 = 18,当前消费者数量
val curConsumers = ctx.consumersForTopic(topic)
// curPartitions = 6,当前分区数量
val curPartitions: Seq[Int] = ctx.partitionsForTopic(topic)
// nPartsPerConsumer = 6/18 = 0,平均每个消费者能分到的分区数【取整】
val nPartsPerConsumer = curPartitions.size / curConsumers.size
/*
nConsumersWithExtraPart = 6%18 = 6,如果分割不均匀(消费者和分区数不是倍数关系),那么前N个消费者将会消费一个额外的分区
这里得出结果是6,那么其含义可以理解为前6个消费者可以比其他消费多消费一个分区,前6个各占有一个分区,后面12个消费者各占有0个分区
*/
val nConsumersWithExtraPart = curPartitions.size % curConsumers.size
info("Consumer " + ctx.consumerId + " rebalancing the following partitions: " + curPartitions +
" for topic " + topic + " with consumers: " + curConsumers)
for (consumerThreadId <- curConsumers) {
// myConsumerPosition是指当前consumerThreadId在消费者集合中的位置
val myConsumerPosition = curConsumers.indexOf(consumerThreadId)
assert(myConsumerPosition >= 0)
/*
startPart = 0*6 + myConsumerPosition.min(6),min函数表示取两个数值中小的一个,那么startPart的值就分成了两个部分:[0-5] -> 0-5,[6-17] -> 6
分区升序排列之后,startPart表示当前消费者从哪个分区开始消费。
*/
val startPart = nPartsPerConsumer * myConsumerPosition + myConsumerPosition.min(nConsumersWithExtraPart)
/*
nParts = 0 + (myConsumerPosition + 1 > 6 ) ? 0 : 1 ,这里nParts的值也分成了两部分,[0-5] -> 1 , [6-17] -> 0
如果消费者数量小于分区数量,则前nConsumersWithExtraPart个消费者的分区数量会是2,nParts只会有三种值【0,1,2】,
表示当前消费者可以消费分区的数量。
*/
val nParts = nPartsPerConsumer + (if (myConsumerPosition + 1 > nConsumersWithExtraPart) 0 else 1)
/**
* Range-partition the sorted partitions to consumers for better locality.
* The first few consumers pick up an extra partition, if any.
*/
// 这里myConsumerPosition在[6-17]的comsumer都会直接告警,也就是上文提到的【额外部分消费者】
if (nParts <= 0)
warn("No broker partitions consumed by consumer thread " + consumerThreadId + " for topic " + topic)
else {
// 这里myConsumerPosition在[0-5]的comsumer进入topic分区分配
for (i <- startPart until startPart + nParts) {
val partition = curPartitions(i)
info(consumerThreadId + " attempting to claim partition " + partition)
// record the partition ownership decision
val assignmentForConsumer = partitionAssignment.getAndMaybePut(consumerThreadId.consumer)
assignmentForConsumer += (TopicAndPartition(topic, partition) -> consumerThreadId)
}
}
}
}
结果:topic里面的每个partition只会由一个线程消费,在分配的时候就已经指定好,如果有消费者线程加入或者退出,则会重新开始分配。
kafka多线程消费topic的问题的更多相关文章
- kafka多线程消费及处理和手动提交处理方案设计[转]
转自:http://blog.csdn.net/haoyifen/article/details/54692503 kafka与其他消息队列不同的是, kafka的消费者状态由外部( 消费者本身或者类 ...
- kafka 多线程消费
一. 1.Kafka的消费并行度依赖Topic配置的分区数,如分区数为10,那么最多10台机器来并行消费(每台机器只能开启一个线程),或者一台机器消费(10个线程并行消费).即消费并行度和分区数一致. ...
- kafka多线程消费
建立kafka消费类ConsumerRunnable ,实现Runnable接口: import com.alibaba.fastjson.JSON; import com.alibaba.fastj ...
- Kafka创建&查看topic,生产&消费指定topic消息
启动zookeeper和Kafka之后,进入kafka目录(安装/启动kafka参考前面一章:https://www.cnblogs.com/cici20166/p/9425613.html) 1.创 ...
- NET中解决KafKa多线程发送多主题
NET中解决KafKa多线程发送多主题 一般在KafKa消费程序中消费可以设置多个主题,那在同一程序中需要向KafKa发送不同主题的消息,如异常需要发到异常主题,正常的发送到正常的主题,这时候就需要实 ...
- Kafka vs RocketMQ—— Topic数量对单机性能的影响-转自阿里中间件
引言 上一期我们对比了三类消息产品(Kafka.RabbitMQ.RocketMQ)单纯发送小消息的性能,受到了程序猿们的广泛关注,其中大家对这种单纯的发送场景感到并不过瘾,因为没有任何一个网站的业务 ...
- Kafka重复消费和丢失数据研究
Kafka重复消费原因 底层根本原因:已经消费了数据,但是offset没提交. 原因1:强行kill线程,导致消费后的数据,offset没有提交. 原因2:设置offset为自动提交,关闭kafka时 ...
- Flume简介与使用(三)——Kafka Sink消费数据之Kafka安装
前面已经介绍了如何利用Thrift Source生产数据,今天介绍如何用Kafka Sink消费数据. 其实之前已经在Flume配置文件里设置了用Kafka Sink消费数据 agent1.sinks ...
- Kafka动态增加Topic的副本
一.kafka的副本机制 由于Producer和Consumer都只会与Leader角色的分区副本相连,所以kafka需要以集群的组织形式提供主题下的消息高可用.kafka支持主备复制,所以消息具备高 ...
随机推荐
- swoole集群 nginx配置
nginx配置文件: upstream cat { server 192.168.149.133:9502 weight=5; server 192.168.149.134:9502 weight=5 ...
- [转]WCF体系结构-一张图就是好
本文转自:http://www.cnblogs.com/snakevash/archive/2011/05/02/2034414.html 今天在MSDN上面看到了这么一张图,让我顿时感觉脑袋清醒很多 ...
- 23 DesignPatterns学习笔记:C++语言实现 --- 1.4 Builder
23 DesignPatterns学习笔记:C++语言实现 --- 1.4 Builder 2016-07-21 (www.cnblogs.com/icmzn) 模式理解
- Python + selenium + unittest装饰器 @classmethod
前言 前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间. 于是就想是不是可以 ...
- XXX 不是当前用户的有效责任,请联系您的系统管理员
EBS中,有时进入一些基于OA Framework 的Web页面时,会出现这种现象: XXX 不是当前用户的有效责任,请联系您的系统管理员 ( or: xxx is not a valid resp ...
- Android-FileUtils工具类
文件相关工具类 public final class FileUtils { private FileUtils() { throw new UnsupportedOperationException ...
- mysql 主从日志文件mysql-bin文件清除方法
默认情况下mysql会一直保留mysql-bin文件,这样到一定时候,磁盘可能会被撑满,这时候是否可以删除这些文件呢,是否可以安全删除,是个问题,不建议使用rm命令删除,这样有可能会不安全,正确的方法 ...
- ajax +LoadLayer插件实现访问页面跳转loading..
布局页:第一步进行扩展ajax$(function () { $.ajax2 = function (options) {//遮罩 Mask();//jquery 原生ajax $.ajax(opti ...
- JgrId 无数据返回设置
在addJSONData方法中 while (i < len) { 前增加以下代码 ) { rowData.push('<tr role="row" id=" ...
- Let it crash philosophy part II
Designing fault tolerant systems is extremely difficult. You can try to anticipate and reason about ...