【原创】如何确定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的各个 ...
随机推荐
- 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】
由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...
- 初学者看过来之JSON入门
1. 什么是JSON JSON---Javascript Object Notation,前两个单词大家应该都认识,最后一个notation,是"记号.标记法"的意思,连在一起,便 ...
- 谈谈JS中的函数节流
好吧,一直在秋招中,都没怎么写博客了...今天赶紧来补一补才行...我发现,在面试中,讲到函数节流好像可以加分,尽管这并不是特别高深的技术,下面就聊聊吧! ^_^ 备注:以下内容部分来自<Jav ...
- 使用github远程仓库
经过几天对github的研究,终于把自己想完成的给解决了,发现google真的有很多解释,但是很多也会出现一些bug,对于初学者真的很多烦恼,所以整理一份,能给初识github的你有所帮助 一,首先, ...
- 【centos7常用技巧】RPM打包
一.RPM打包的目的 1.当目标机中不存在编译环境时,可以先在本地环境中编译打包,然后直接在目标机中用rpm -ivh *.rpm安装即可. 2.当需要在目标机中安装多个软件或者增加多个文件时,可以将 ...
- mysql-5.6.34 Installation from Source code
Took me a while to suffer from the first successful souce code installation of mysql-5.6.34. Just pu ...
- SQLite学习笔记(十)&&加密
随着移动互联网的发展,手机使用越来越广泛,sqlite作为手机端存储的一种解决方案,使用也非常普遍.但是sqlite本身安全特性却比较弱,比如不支持用户权限,只要能获取到数据库文件就能进行访问:另外也 ...
- photoshop:无法完成请求 因为暂存盘已满
今天photoshop打开一个问题,提醒:无法完成请求因为暂存盘已满 不用担心这个问题很好解决可能是你做的图比较大并不需要清理C盘空间 选择:编辑→首选项→暂存盘 设置第一暂存盘为D盘或E盘 总之 第 ...
- Spring MVC数据校验
在web应用程序中,为了防止客户端传来的数据引发程序异常,常常需要对 数据进行验证.输入验证分为客户端验证与服务器端验证.客户端验证主要通过JavaScript脚本进行,而服务器端验证则主要通过Jav ...
- Princeton Algorithms week3 Assignment
这周编程作业是实现检测点共线的算法.和排序算法有关系的地方在于,对斜率排序后可以很快的检测出来哪些点是共线的,另外这个算法的瓶颈也在于排序的性能. 一点收获: java传参数时传递的是值,这很多人都知 ...