【原创】如何确定Kafka的分区数、key和consumer线程数
def partition(key: Any, numPartitions: Int): Int = {
Utils.abs(key.hashCode) % numPartitions
}
这就保证了相同key的消息一定会被路由到相同的分区。如果你没有指定key,那么Kafka是如何确定这条消息去往哪个分区的呢?
if(key == null) { // 如果没有指定key
val id = sendPartitionPerTopicCache.get(topic) // 先看看Kafka有没有缓存的现成的分区Id
id match {
case Some(partitionId) =>
partitionId // 如果有的话直接使用这个分区Id就好了
case None => // 如果没有的话,
val availablePartitions = topicPartitionList.filter(_.leaderBrokerIdOpt.isDefined) //找出所有可用分区的leader所在的broker
if (availablePartitions.isEmpty)
throw new LeaderNotAvailableException("No leader for any partition in topic " + topic)
val index = Utils.abs(Random.nextInt) % availablePartitions.size // 从中随机挑一个
val partitionId = availablePartitions(index).partitionId
sendPartitionPerTopicCache.put(topic, partitionId) // 更新缓存以备下一次直接使用
partitionId
}
}
可以看出,Kafka几乎就是随机找一个分区发送无key的消息,然后把这个分区号加入到缓存中以备后面直接使用——当然了,Kafka本身也会清空该缓存(默认每10分钟或每次请求topic元数据时)
val nPartsPerConsumer = curPartitions.size / curConsumers.size // 每个consumer至少保证消费的分区数
val nConsumersWithExtraPart = curPartitions.size % curConsumers.size // 还剩下多少个分区需要单独分配给开头的线程们
...
for (consumerThreadId <- consumerThreadIdSet) { // 对于每一个consumer线程
val myConsumerPosition = curConsumers.indexOf(consumerThreadId) //算出该线程在所有线程中的位置,介于[0, n-1]
assert(myConsumerPosition >= 0)
// startPart 就是这个线程要消费的起始分区数
val startPart = nPartsPerConsumer * myConsumerPosition + myConsumerPosition.min(nConsumersWithExtraPart)
// nParts 就是这个线程总共要消费多少个分区
val nParts = nPartsPerConsumer + (if (myConsumerPosition + 1 > nConsumersWithExtraPart) 0 else 1)
...
}
针对于这个例子,nPartsPerConsumer就是10/3=3,nConsumersWithExtraPart为10%3=1,说明每个线程至少保证3个分区,还剩下1个分区需要单独分配给开头的若干个线程。这就是为什么C0消费4个分区,后面的2个线程每个消费3个分区,具体过程详见下面的Debug截图信息:







【原创】如何确定Kafka的分区数、key和consumer线程数的更多相关文章
- 如何确定Kafka的分区数、key和consumer线程数
[原创]如何确定Kafka的分区数.key和consumer线程数 在Kafak中国社区的qq群中,这个问题被提及的比例是相当高的,这也是Kafka用户最常碰到的问题之一.本文结合Kafka源码试 ...
- 【转】如何确定Kafka的分区数、key和consumer线程数
文章来源:http://www.cnblogs.com/huxi2b/p/4583249.html -------------------------------------------------- ...
- 【原创】开发Kafka通用数据平台中间件
开发Kafka通用数据平台中间件 (含本次项目全部代码及资源) 目录: 一. Kafka概述 二. Kafka启动命令 三.我们为什么使用Kafka 四. Kafka数据平台中间件设计及代码解析 五. ...
- Apache Samza流处理框架介绍——kafka+LevelDB的Key/Value数据库来存储历史消息+?
转自:http://www.infoq.com/cn/news/2015/02/apache-samza-top-project Apache Samza是一个开源.分布式的流处理框架,它使用开源分布 ...
- 【原创】谈谈redis的热key问题如何解决
引言 讲了几天的数据库系列的文章,大家一定看烦了,其实还没讲完...(以下省略一万字). 今天我们换换口味,来写redis方面的内容,谈谈热key问题如何解决. 其实热key问题说来也很简单,就是瞬间 ...
- kafka如何防止key相同的消息并发消费
最开始,我认为只用把消费者设置为单线程消费,就可以避免并发问题. 因为同一个key,分区一定相同,那么就只会被同一个消费者消费,消费者又是单线程,这样就避免了并发问题 后面发现,上述的方式没有办法处理 ...
- springboot kafka集成(实现producer和consumer)
本文介绍如何在springboot项目中集成kafka收发message. 1.先解决依赖 springboot相关的依赖我们就不提了,和kafka相关的只依赖一个spring-kafka集成包 &l ...
- Apache Kafka - KIP-42: Add Producer and Consumer Interceptors
kafka 0.10.0.0 released Interceptors的概念应该来自flume 参考,http://blog.csdn.net/xiao_jun_0820/article/det ...
- kafka producer自定义partitioner和consumer多线程
为了更好的实现负载均衡和消息的顺序性,Kafka Producer可以通过分发策略发送给指定的Partition.Kafka Java客户端有默认的Partitioner,平均的向目标topic的各个 ...
随机推荐
- AI人工智能系列随笔
初探 AI人工智能系列随笔:syntaxnet 初探(1)
- 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)
坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...
- Ajax使用WCF实现小票pos机打印源码
通过ajax跨域方式调用WCF服务,实现小票pos机的打印,源码提供web方式,客户端方式测试,服务驻留右侧底部任务栏,可控制服务开启暂停,用户可自定义小票打印模板,配合零售录入. qq 22945 ...
- 反应器(Reactor)和主动器(Proactor)
网络方面用的比较多的库是libevent和boost.asio,两者都是跨平台的.其中libevent是基于Reactor实现的,而boost.asio是基于Proactor实现的.Reactor和P ...
- Git(1)
安装Git 完毕 (在开始菜单打开的话,打开的不是你想要的路径,切换路径很麻烦) 1.D盘新建 GitTest 文件夹 2.打开GitTest , 在空白的地方右键, 3.单击 Git Bash He ...
- Ognl表达式基本原理和使用方法
Ognl表达式基本原理和使用方法 1.Ognl表达式语言 1.1.概述 OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个 ...
- 谈谈 Lock
上来先看MSDN关于lock的叙述: lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁. 下面的示例包含一个 lock 语句. lock 关键字可确保当一 ...
- MongoDB数据实体中的ObjectId序列化成json的一个小坑
很多时候我们都需要对实体对象进行序列化与反序列化,而ObjectId类型,只能用mongo的驱动以bson格式来序列化,但我们对外的交互,一般是json格式. 有两种解决方案: 1.自己写一个json ...
- Assertor用于判断参数和抛出异常
代码 /// <summary> 断言器,用于判断和抛出异常 /// </summary> static class Assertor { /// <summary> ...
- 我们为什么不能只用O记号来谈论算法?
在刷LeetCode-1TwoSum的时候,有个人在论坛留言,大致意思如下: 我的算法击败了90%的人,O(nlgn)算法比O(n)算法快. 我觉得这个人是不懂算法的.让我一步一步解释. # O的含义 ...