在阅读本文之前, 希望你可以思考一下下面几个问题, 带着问题去阅读文章会获得更好的效果。
-
发送消息的时候, 当Broker挂掉了,消息体还能写入到消息缓存中吗?
-
当消息还存储在缓存中的时候, 假如Producer客户端挂掉了,消息是不是就丢失了?
-
当最新的ProducerBatch还有空余的内存,但是接下来的一条消息很大,不足以加上上一个Batch中,会怎么办呢?
-
那么创建ProducerBatch的时候,应该分配多少的内存呢?
什么是消息累加器RecordAccumulator
kafka为了提高Producer客户端的发送吞吐量和提高性能,选择了将消息暂时缓存起来,等到满足一定的条件, 再进行批量发送, 这样可以减少网络请求,提高吞吐量。
而缓存这个消息的就是RecordAccumulator类.
上图就是整个消息存放的缓存模型,我们接下来一个个来讲解。
消息缓存模型
上图表示的就是 消息缓存的模型, 生产的消息就是暂时存放在这个里面。
-
每条消息,我们按照TopicPartition维度,把他们放在不同的
Deque<ProducerBatch>
队列里面。TopicPartition相同,会在相同Deque<ProducerBatch>
的里面。 -
ProducerBatch
: 表示同一个批次的消息, 消息真正发送到Broker端的时候都是按照批次来发送的, 这个批次可能包含一条或者多条消息。 -
如果没有找到消息对应的ProducerBatch队列, 则创建一个队列。
-
找到ProducerBatch队列队尾的Batch,发现Batch还可以塞下这条消息,则将消息直接塞到这个Batch中
-
找到ProducerBatch队列队尾的Batch,发现Batch中剩余内存,不够塞下这条消息,则会创建新的Batc