Kafka学习--------消息存储,ISR

1.Kafka消息存储

1.1Kafka集群中的几个概念

Broker:消息中间件处理结点,一个Kafka节点就是一个broker,多个broker能够组成一个Kafka集群。

Topic:一类消息,比如page view日志、click日志等都能够以topic的形式存在。Kafka集群能够同一时候负责多个topic的分发。

Partition:topic物理上的分组。一个topic能够分为多个partition,每一个partition是一个有序的队列。

Segment:partition物理上由多个segment组成。以下有具体说明。

offset:每一个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每一个消息都有一个连续的序列号叫做offset,用于partition中唯一标识的这条消息。

1.2 存储流程

一个topic被创建时会设置–replication-factor 和–partitions ,即设置topic的副本个数和分区数。一个topic可以设置>=1个分区(不设置默认为一个分区)和1<=副本数<=broker 个数。
一个topic可以对应多个分区,每一个分区会存在n个副本,分布在不同的Kafka集群节点上。在这些副本中有一个leader和多个follower组成。leader负责接受生产者发送的消息和存储消息到Kafka集群(0.9版本以后)。follower负责对leader的数据备份。每一个分区会在当前节点上的log.dir/toppicName-分区id/(log.dir 在Kafka server.proper配置文件中配置)目录下创建00000000000000000000.log和00000000000000000000.index两个文件。这两个文件组成了这个分区的一个Segment。log文件主要存储消息,而index文件负责对log的索引。
当log文件达到配置的log.segment.bytes=107370 (设置分段大小),默认是1Gb时,会新建一个0000000000000000XXXX.log和0000000000000000XXXX.index(XXXX为上一个segment的最大偏移量+1).这样有生成了一个新的segment。所以一个分区可以对应多个segment。
如图所示:
Kafka学习--------消息存储,ISR_第1张图片
Kafka学习--------消息存储,ISR_第2张图片segment file 由 2 大部分组成,分别为 index file 和 datafile,此 2 个文件一一对应,成对出现,后缀".index"和“.log”分别表示为 segment 索引文件、数据文件.segment 文件命名规则:partion 全局的第一个 segment从 0 开始,后续每个 segment 文件名为上一个 segment文件最后一条消息的 offset 值进行递增。数值最大为 64 位long 大小,20 位数字字符长度,没有数字用 0 填充(为了方便,例子中少写了一些0)

举例说明:
当消费者之前已经获取了三条消息,现在需要继续获取消息,此时他需要读取的消息偏移量为3(从0开始)。首先会在多个index文件中根据文件名利用二分查找,定位消息所在的index文件,由于需要读取第四条消息偏移量为3,所以定位到00000000.index文件(如果需要获取第8条数据(偏移量为7),就会定位到000006.index文件)。
index文件中每条索引的大小为固定值,假设为100个字节。根据偏移量*100,可以获取到这条消息所对应的索引的起始地址。读取索引内的起始位置的值,就对应了这条消息在000000.log文件的起始地址值。根据消息的大小和起始地址就可以很快的从000000.log中取出第四条消息。

2. ISR

同步复制: 只有所有的follower把数据拿过去后才commit,一致性好,可用性不高。
异步复制: 只要leader拿到数据立即commit,等follower慢慢去复制,可用性高,立即返回,一致性差一些。
Commit:是指leader告诉客户端,这条数据写成功了。kafka尽量保证commit后立即leader挂掉,其他flower都有该条数据。

kafka不是完全同步,也不是完全异步,是一种ISR机制:

  1. leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护
  2. 如果一个flower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除
  3. 当ISR中所有Replica都向Leader发送ACK时,leader才commit

既然所有Replica都向Leader发送ACK时,leader才commit,那么flower怎么会leader落后太多?
producer往kafka中发送数据,不仅可以一次发送一条数据,还可以发送message的数组;批量发送,同步的时候批量发送,异步的时候本身就是就是批量;底层会有队列缓存起来,批量发送,对应broker而言,就会收到很多数据(假设1000),这时候leader发现自己有1000条数据,flower只有500条数据,落后了500条数据,就把它从ISR中移除出去,这时候发现其他的flower与他的差距都很小,就等待;如果因为内存等原因,差距很大,就把它从ISR中移除出去。
————————————————
原文链接:https://blog.csdn.net/qq_37502106/article/details/80271800

在Kafka0.9版本之后,ISR移除了数据条数这一条件,只保留了超时时间这一条件。原因:由于生产者发送数据为批批量发送,假设一次发送12条数据,如果ISR设置的条数限制为10条,此时ISR里面的所有follower都不满足条件,都被踢出ISR队列,但是在10000ms以内,大部分follower已经同步完成leader的数据,又被重新加入到ISR队列中。由于ISR存储在zookeeper之中,多次踢出,重新加入,导致频繁读写zookeeper,导致效率降低,所有0.9以后,移除了条数这个限制,保留了时间限制。

你可能感兴趣的:(Kafka)