Kafka源码解析(六)- 发送数据流程(4)

本篇介绍下 kafka发送数据流程中是如何选择分区的。

点进步骤三这行代码。

我们在调用doSend()方法时会将消息封装下,可以使用指定分区的构造方法

如果我们调用上面的构造函数,指定分区编号,这里就不需要进行分区选择了,如果没有指定,kafka会有两种分区选择的方式,下面解读下这两种选择方式。

第一种策略:在发送消息的时候没有指定key。这种方式,kafka首先会有一个线程安全的累加器,每当这个方法被调用的时候都会加1,然后再拿这个累加器中的值对可用分区数取模。

这样做会达到这样一个轮询效果,从而达到负载均衡的目的。比如有3个分区,假如第一条发送到了0号分区,第2条会发送到1号分区,第3条会发送到2号分区,第4条会发送到0号分区,

第5条会发送到1号分区,以此类推。感兴趣的话可以自己建一个工程,把Utils.toPositive(nextValue) % availablePartitions.size(); 这部分相关代码拷贝出来然后循环调用试试看。

第二种策略:在发送消息的时候指定key。这种方式,kafka将用户指定的key 序列化成一个字节数组,然后根据murmur2这个hash算法取hash值,然后再对分区数取模,得到分区编号。

这么做的目的是:如果我想让某些消息发送到同一分区,那么就把这些消息指定同一个key,比如要让同一用户产生的消息发送到相同的分区,把这个key指定成userid。

把这些消息路由到一个分区的目的是要保证消息的有序性,如果被分配到了不同的分区,那么无论这几个分区是由同一个消费者消费的还是由不同消费者消费的,都可能造成数据不是按照我们发送时的顺序消费的。

这样就乱序了。当然这种方式是负载不均衡的,不需要保证消息顺序的情况下,就不要用。

至此,kafka分区选择的方式解读完毕,如果自己生产中也有需要这两种场景的,可以参照kafka的方式,代码copy出来直接用。

posted @ 2020-09-14 22:50  写写代码睡着了  阅读(58)  评论(0)    收藏  举报