kafka的partition和offset

转载自:http://www.tuicool.com/articles/MZNfAj7html

在kafka快速上手中,留下的问题是关于partition和offset,这篇文章主要解释这个.linux

Log机制

说到分区,就要说kafka对消息的存储.在 官方文档 中.算法

首先,kafka是经过log(日志)来记录消息发布的.每当产生一个消息,kafka会记录到本地的log文件中,这个log和咱们平时的log有必定的区别.这里能够参考一下 The Log ,很少解释.数据库

这个log文件默认的位置在config/server.properties中指定的.默认的位置是log.dirs=/tmp/kafka-logs,linux不用说,windows的话就在你对应磁盘的根目录下.我这里是D盘.apache

分区partition

kafka是为分布式环境设计的,所以若是日志文件,其实也能够理解成消息数据库,放在同一个地方,那么必然会带来可用性的降低,一挂全挂,若是全量拷贝到全部的机器上,那么数据又存在过多的冗余,并且因为每台机器的磁盘大小是有限的,因此即便有再多的机器,可处理的消息仍是被磁盘所限制,没法超越当前磁盘大小.所以有了partition的概念.windows

kafka对消息进行必定的计算,经过hash来进行分区.这样,就把一份log文件分红了多份.如上面的分区读写日志图,分红多份之后,在单台broker上,好比快速上手中,若是新建topic的时候,咱们选择了 --replication-factor 1 --partitions 2 ,那么在log目录里,咱们会看到分布式

test-0目录和test-1目录.就是两个分区了.ui

你可能会想,这特么没啥区别呀.注意,当有了多个broker以后,这个意义就存在了.这里上一张图,原文在参考连接里有spa

这是一个topic包含4个Partition,2 Replication(拷贝),也就是说所有的消息被放在了4个分区存储,为了高可用,将4个分区作了2份冗余,而后根据 分配算法 .将总共8份数据,分配到broker集群上..net

结果就是每一个broker上存储的数据比全量数据要少,但每份数据都有冗余,这样,一旦一台机器宕机,并不影响使用.好比图中的Broker1,宕机了.那么剩下的三台broker依然保留了全量的分区数据.因此还能使用,若是再宕机一台,那么数据不完整了.固然你能够设置更多的冗余,好比设置了冗余是4,那么每台机器就有了0123完整的数据,宕机几台都行.须要在存储占用和高可用之间作衡量.至于宕机后,zookeeper会选出新的partition leader.来提供服务.这个等下篇文章

偏移offset

上一段说了分区,分区就是一个有序的,不可变的消息队列.新来的commit log持续日后面加数据.这些消息被分配了一个下标(或者偏移),就是offset,用来定位这一条消息.

消费者消费到了哪条消息,是保持在消费者这一端的.消息者也能够控制,消费者能够在本地保存最后消息的offset,并间歇性的向zookeeper注册offset.也能够重置offset

如何经过offset算出分区

其实partition存储的时候,又分红了多个segment(段),而后经过一个index,索引,来标识第几段.这里先能够去看一下本地log目录的分区文件夹.

在我这里,test-0,这个分区里面,会有一个index文件和一个log文件,

对于某个指定的分区,假设每5个消息,做为一个段大小,当产生了10条消息的状况想,目前有会获得(只是解释)

0.index (表示这里index是对0-4作的索引)

5.index (表示这里index是对5-9作的索引)

10.index (表示这里index是对10-15作的索引,目前还没满)

0.log

5.log

10.log

,当消费者须要读取offset=8的时候,首先kafka对index文件列表进行二分查找,能够算出.应该是在5.index对应的log文件中,而后对对应的5.log文件,进行顺序查找,5->6->7->8,直到顺序找到8就行了