kafka中topic的partition数量和customerGroup的customer数量关系以及storm消费kafka时并行度设置问题总结:

前段时间通过网上查找和自己测试仔细研究了partition和customer关系以及工作中遇到的storm并行度调整的问题,认真梳理了一下现总结如下:

一、先说kafka部分:

produce方面:

如果有多个分区,发送的时候按照key值hashCode%partitionNum哈希取模分区数来决定该条信息发往哪个partition, 这里可以自定义partition的分发策略,只要实现Partitioner接口就好,可以自定义成随机分发或者fangwang发往指定分区;

customer方面:

对于topic中的partition来说,一个partition只允许一个customer来消费,同一个partition上不允许customer并发;

Partition数量>customer数量时:一个consumer会对应于多个partitions,这里主要合理分配consumer数和partition数,否则会导致partition里面的数据被取的不均匀 。最好partiton数目是consumer数目的整数倍,所以partition数目很重要,比如取24,就很容易设定consumer数目 。

Partition数量<customer数量时:   就会有剩余的customer闲置,造成浪费;

如果一个consumer从多个partition读到数据,不保证数据间的顺序性,kafka只保证在一个partition上数据是有序的,但多个partition,根据你读的顺序会有不同 ;kafka只保证在一个上数据是有序的(每个partition都有segment文件记录消息的顺序性),无法保证topic全局数据的顺序行;

增减consumer,broker,partition会导致rebalance,所以rebalance后consumer对应的partition会发生变化。

下面用图片展示更容易理解(图片是拷贝其他网友的,自己做了下陈述)

同一个topic的一个partition只能被同一个customerGroup的一个customer消费;group里多于partition数量的customer会空闲;

同一个topic的partition数量多于同一个customerGroup的customer数量时,会有一个customer消费多个partition,这样也就没法保证customer接收到的消息的顺序性,kafka只保证在一个partition上数据是有序的,无法保证topic全局数据的顺序性;

一个topic 的partitions被多个customerGroup消费时,可以并行重复消费;

这样就可以解决下面问题:kafka topic partition同一个GROUPID的多个消费者消费,只有一个能收到消息的原因一般有如下

  1. 只有一个partition分区;同一个topic的同一个partition分区只允许同一个customerGroup的一个消费者消费信息,一个partition上不允许同一个消费者组的多个消费者并发,但同一个partition上是可以多个消费者组的消费者并发消费的;
  2. 多个partition分区,但是,消息在生产时只发往到了一个partiton上;key的hashCode%partitionNum相同导致,或者自定义了分区策略;导致这种严重的数据倾斜;

二、storm部分

首先明确的一点是,storm的并行度都是executor即线程级别的并行;包括work(进程),executor(线程)的设置,具体体现在works,spout,bolt设置上,同一个executor上设置多个task还是会串行化执行,并不能提高执行效率,这也是由于并行是线程并行,一个线程的多个task肯定是有先后执行顺序的,有顺序那就不是并行;关于node,work,executor,task关系和work,spout,bolt,并行度设置网上有很多资料,挺详细;这里记录下我遇到的自己关系的另外两个问题:一个是从kafka消费消息是spout并行度设置,另一个ack响应开启的是线程还是进程以及如何设置其数量;

第一个问题:其实理解了上面kafka customer和partition的关系第一个问题也就解决了,spout的并发度实例数量设置最好和partition数量一样,这样能保证一个spout消费者实例对应一个partition,即实现了一个partition中消息消费的顺序性(有时消息的顺序性要求并不是很高)也能很好地提高整个topology的执行效率,至少对拓扑执行效率来说,瓶颈不会卡在spout(数据源)这里;

第二个问题:通过Storm UI发现,work和spout,bolt并行度不变的情况下,多开几个acker_executors,works的数量并没有增加,反而是executors数量增加,这样就确定了acker_executors如其名一样只是线程,并不像有些网友说的ack的执行是会单独开启ack进程再在该进程里运行ack响应线程。他其实就是一个普通的ack线程,运行在已有的work进程里;

另外通过测试发现,我设置了4个work,4个spout,4个bolt,没有设置acker_executors, Storm UI上显示Num workers是4,Num executors却是12(4个spout,4个bolt 这里一共是8个executors),所以默认情况下一个work里会有一个acker_executors。

默认情况下一个work会有一个executor,一个executor会有一个task,如果设置了他们的数量,就会按照设置的数量来生成对应实例;如开了4个work,2个spout,3个bolt,那spout和bolt的executors一共就会有5个(spout executors 2个,bolt executors 3个,),相当于有2个work里是1个spout executor和1个bolt executor,有1个work里只有1个boltexecutor,还有一个work里啥也没有;其实这种配置会导致多开一个啥活也不干的work进程,有些浪费;

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值