目录
序言:
副本机制是分布式系统中最常见的概念,在常见的分布式系统中,为了对外提供高可用的服务,一般都对数据和服务进行副本构建。Kafka对于Topic进行了物理上进行数据切片(Partition分区),而对于每一个分区都为了其高可用,在0.8之后采用了多副本的概念,即一个Partition对应多个副本,其中一个副本为leader, 其它的为follower,典型的主从结构,而与其它分布式系统中主从结构的不同,Kafka中只有leader对外提供服务,而follower只会同步leader数据,而不提供服务,至于为何Kafka这样设计,后文描述,Kafka主要就是通过多副本机制来保证kafka中消息的一致性,以及高可用性。
1:副本物理存储结构
Kafka对于一个Topic中多个Partition会尽量的进行平均分配到整个集群中(通过Kafka分区策略来做到的,通过生产者属性partition .assignment.strategy= org.apache.kafka.clients.cons me.RangeAssignor 关于此可参考kafka分区策略)。这样的好处可以使得整个集群每个broker的消费压力更平均,整体吞吐量更大。而follower作为leader的backup为了保证高可用,follower一般不会和leader分配在一个broker中(除非broker数量小于副本的数量,或者broker)。例如现有3个broker,一个topic有3个分区,每个分区3个副本,最终落地到每个broker为一个partition的leader副本,两个partition的follower副本,对于我们来说这样就是一个最优分区选择。那么对于生产中的partition与副本数的多少我们如何设定(并不是partition越多,性能越高),可以通过对于单broker通过Kafka提供的压测命令来进行测试(Kafka本身提供的用于生产者性能测试kafka-producer-perf-test.sh 和用于消费者性能测试的 kafka-consumer-perf-test.sh要结合生产数据量以及消费能力来决定),获取最优的分区数(普遍发现一个partition数大约在50左右时可以获得最大吞吐量,这也是为何对于kafka中内部__consumer_offsets与consume-transform-produce默认的partition数为50)。一个Partition被创建消费之后那么在磁盘中存储的结构如下所示:
- .log后缀中存储的为kafka中的数据,文件名为当前segment的起始的BaseOffset的偏移量。对于该文件数据格式随着kafka版本的不同,也有着非常大的变化经历过vO 版本,vl版本,v2版本,这里不详细介绍。
- .index中存储的是逻辑上的offset与物理存储位置的映射,格式如图所示: 其中relativeOffset占用4字节,为相对于BaseOffset的偏移量,索引文件名为当前segment的起始的BaseOffset的偏移量,position记录为log文件中实际的物理地址.
- .timeindex中存储的是消息生产的时间戳的与物理存储位置的映射,格式如图所示: timestamp通过8字节记录该message对应的timestamp(后面的timestamp必须要大于之前的timestamp),每个后面索引项对应的timestamp必须要大于timestamp否则不予追加,如果broker端参数log.message.timestamp