kafka broker相关文档阅读

This commit is contained in:
2023-10-06 23:03:28 +08:00
parent 4197045981
commit a871d01214

View File

@@ -164,3 +164,86 @@ broker宕机并不会导致分区的重新分配例如一个分区的replica-
>
> 该属性默认设置为true一个后台线程会定期(时间间隔为`leader.imbalance.check.interval.seconds`,默认为300s)检测分区leader是否为默认的perferred leader。如果分区leader不为preferred leader的数量超过一定的比率(` leader.imbalance.per.broker.percentage`默认为10%)会触发将分区leader改为默认preferred leader的操作。
##### broker AR & OSR
kafka中副本的默认数量为1个通常生产环境将其配置为2个或2个以上以便在leader副本宕机后follower副本能够继续服务避免数据丢失。
- AR: AR代表集群中分区对应的所有副本集合all-replicas
- ISR 代表集群中处于同步状态的副本集合in-sync-replicas 如果ISR中的节点长期未从leader中同步数据会被剔除出ISR最长未同步的时间由`replica.lag.time.max.ms`控制默认为30s。如果leader对应的broker宕机那么新leader将会从ISR中选举产生
- OSR代表集群中不处于同步状态的副本集合为AR - ISR
##### leader选举机制
leader选举根据AR中节点的排序来决定能够成为leader的节点需要再ISR中存活然后ISR中存活节点在AR中排序最靠前的将会被选举为leader。如果leader发生宕机那么由ISR中存活且AR中排序最靠前的的节点成为新leader。
> 选举机制中leader决定是按照AR中broker节点的顺序进行决定的每一个分区都有一个默认的preferred leader。如果某些节点宕机后再恢复ISR中节点的顺序将会发生变化但是AR中的节点顺序并不变并且preferred leader也不会发生变化。
##### follower故障恢复细节
follower故障恢复细节中涉及到如下两个概念
- LEO(Log End Offset)每个副本结束offset的下一个位置类似于java中的List.size()
- HW(High WaterMark)当前ISR队列中所有副本最小的HOW水位线类似于木桶效应中最短的那一根木板
如果follower发生故障那么会按顺序发生如下
1. 故障follower会被剔除出ISR
2. follower故障期间ISR中剩余的follower节点和leader节点会继续接受数据
3. 故障follower如果恢复会读取宕机前记录的旧集群HW并且将大于等于该旧HW的log记录全部都删除并且从leader重新同步记录
4. 当故障恢复的follower从旧HW位置同步消息到当前集群中的新HW位置时此时故障恢复的log区数据已经同步到新HW的水位线水平此时故障恢复的follower节点可以重新加入到ISR中
##### leader宕机的细节
如果leader broker发生宕机那么新选举成为leader的follower将会成为leader并且所有节点会将大于等于HW的数据丢弃(由于宕机的是leaderLEO最大故而leader宕机不会对HW造成影响)并且重新从新选举的leader中同步数据。
由上可知如果leader宕机前其他follower尚未同步完leader中全部的消息那么leader宕机后可能会发生消息的丢失。如果需要确保消息不丢失需要设置生产者的acks为all确保消息再提交前同步到ISR中所有的节点中。
##### kafka分区存储机制
kafka中topic是一个逻辑概念topic由分区组成每个分区则是可以看作一个log文件log中存放生产者产生的数据。生产者产生的消息会被追加到log文件的末端由于是线性追加不涉及到平衡树等数据结构故而**kafka追加消息时不管当前分区数据存储量大小追加数据的开销都是相同的追加操作不会随着数据量变大而变慢**。
为了防止分区对应的log文件过大而导致的数据定位效率低下kafka采用了分片和索引的机制将每个分区分为了多个segment。单个segment默认存储的数据量的大小为1G且单个segment由如下文件组成
- .log文件日志文件用于存储消息log文件的命名以当前segment中第一条消息再分区中的offset来命名
- .index偏移量索引文件用于存储偏移量和position的映射关系用于快速定位消息
- .timeindex时间戳索引文件该文件用于存储消息对应的时间戳信息kafka中的消息默认保存7天后丢弃通过时间戳信息来决定消息是否应该丢弃
> index索引
>
> kafka中的索引为稀疏索引默认每往log中写入4KB的数据.index文件中会记录一条偏移量索引信息。
>
> 可以通过`log.index.interval.bytes`来配置索引记录的密度,每写入多少数据才记录一条索引
##### kafka文件清除策略
kafka中默认消息保存的时间为7天可以通过修改如下配置来对默认保存时间进行修改
- log.retention.hours消息默认保存小时默认为16824 * 7
- log.retention.minutes消息默认保存时间按分钟计
- log.retention.ms消息设置默认保存时间按ms计
上述设置中,优先级为`ms`>`minutes`>`hours`,如果优先级较大的被设置,那么取优先级高的设置,在高优先级条目没有被设置时,才取低优先级设置。
> 如果想要设置消息不超时,可以将`log.retention.ms`设置为-1
`log.retention.check.interval.ms`参数可以检查消息是否超时的周期默认情况下该值设置为5min。
kafka中的日志清除策略由如下两种
- 删除
- 压缩
> 删除
>
> 当`log.cleanup.policy`默认值为delete当该值被设置为delete时存储超期日志的文件将会被删除。
>
> - 基于时间默认打开。如果segment中所有记录中时间戳最大的记录最新插入的记录超过最长时间设置那么会将该segment删除。以segment中最新消息时间戳作为segment文件时间戳
> - 基于大小:基于大小的删除默认是关闭的。`log.retention.bytes`默认值为-1表示对log文件最大的限制如果单个log文件的大小超过该大小限制那么会删除log文件对应的最早的segment
> 压缩
>
> 当`log.cleanup.policy`值设置为compact时会对超时的segment进行压缩指segment最新一条插入的消息超时对于相同key的消息只会保留最后插入的一条消息演示如下。
>
> | k2 | k1 | k3 | k1 | k2 |
> |:-:|:-:|:-:|:-:|:-:|
> | 1 | 2 | 3 | 4 | 5 |
>
> 会被压缩为
>
> | k3 | k1 | k2 |
> |:-:|:-:|:-:|
> | 3 | 4 | 5 |
>
> 压缩后offset可能并不连续此时若想要消费的offset不存在那么会拿到比预期offset大的offset的消息