6.2.2 分区与副本
6.2.2分区与副本
本章最开始分析底层的消息集时,主要专注物理层面的日志、日志分段、日志管理器,并没有过多考虑什么时候通过日志管理器去调用日志对象的相关方法。然后,在分析副本管理器时,我们知道日志管理器在启动时会作为副本管理器的成员变量。但是,富lj本管理器并不负责创建日志,它只是管理消息代理节点上的分区。所以,副本管理器将日志管理器这个全局的成员变量,传给了它所管理的每个分区。副本管理器的每个分区会通过日志管理器,为每个副本创建对应的日志。
如表6-7所示,“日志管理器”对“日志”进行管理,“副本管理器”对“副本”进行管理。日志管理器(LogManager)通过每个日志对象(Log)管理日志的所有分段(LogSegment),副本管理器(ReplicaManager)也通过每个分区(Partition)管理分区的所有副本(Replica)。
为了保证数据的可靠存储Kafka在0.8版本之后提供了副本机制,副本机制的本质是:将同一个分区的数据分别存储在多个消息代理节点上。如因6-48所示,副本分主副本(LeaderReplica)和备份副本(FollowerReplica),每个分区管理多个副本。在实现方式上,我们可以在主副本所在的消息代理节点上,管理其余消息代理节点上的备份副本,但是这种做法的缺点是:在需要查询分区的所有副本信息时,主副本所在的节点都需要和备份副本的节点进行通信。另外,如果主副本所在的节点挂掉了,即使其他副本所在的节点正常。但分区对象就不存在了,分区和副本之间的关联关系也都不复存在了。
Kafka副本机制的做法是:同一个分区会存在于多个消息代理节点上,并被对应节点的副本管理器所管理。虽然每个节点上的分区在逻辑意义上都有多个副本,但只有本地副本才有对应的日志文件(一个节点上只需要存储一个副本对应的日志文件)。如图6-49所示,分区Pl存在l个节点上,每个分区都有3个副本,深色方框表示本地副本,以及对应的日志文件。比如,节点1的本地副本是副本l,它同时也是分区的主副本。节点2的本地副本是副本2,节点3的本地副本是副本3,它们都是分区的备份副本。
备份副本会向主副本拉取消息保持数据的同步,服务端处理备份副本的拉取请求,也会更新对应的备份副本信息(副本的信息包括偏移量、最高水位)。比如,节点2和节点3上的备份副本向主副本所在的节点l拉取消息,节点l会在返回主副本的数据给备份副本之前,分别更新副本2和副本3的信息。这样,当需要获取分区的所有副本信息时,就不需要和备份副本所在的物理节点进行网络通信了。另外,即使主副本所在的节点挂掉,其他备份副本所在的节点也保存着分区和副本的对应关系,所以分区和副本的关联仍然存在。
要理解Kafka的副本机制,可以从逻辑层和物理层两个方面进行分析:同一个分区在多个消息代理节点上、一个分区管理多个副本都属于逻辑层;每个消息代理节点上的本地副本都有一个日志文件,则属于物理层。并且,不同消息代理节点上同一个分区的不同副本,它们的日志目录都是以分区命名的。比如主题名称为test、分区编号为0,副本所在每个节点上对应的日志目录都是:test-0。
- 分区对象
每个分区都只有一个主副本和多个备份副本,不同节点上的分区对象,它们的主副本对象都是同一个(leaderRepHcaldOpt变量)。另外,分区对象还维护了所有的副本(assignedReplicaMap字典,简称AR)、同步的副本(inSyncReplicas集合,简称ISR)。
举例,分区Pl有3个编号为[1,2,3]的副本,分别存储在对应编号的节点上,每个节点的副本管理器都会管理分区Pl。不同节点上的每个分区对象除了本地节点编号(localBrokerId)不一样,其他的成员变量都是一样的:assignedReplicaMap等于[1,2,巧,leaderReplicaldOpt等于[2]。相关代码如下:
如表6-8所示,分区的getReplica()方法会返回当前节点所在的副本,不同节点返回不同的值。分区的leaderReplica!flocal()方法则只有主副本所在的节点才有数据,在备份副本所在的节点上调用分区的这个方法,返回值为None。
上面分区对象(Partition)的几个变量和方法都是获取数据,副本管理器还会通过调用分区的getO亿reateReplica()方法,根据给定的副本编号创建对应的副本对象(Replica)。
- 副本对象
分区创建副本分成本地副本(localReplica)和远程副本(rer时eReplica)。节点编号和副本编号相同的副本叫作本地副本,编号不同的叫作远程副本。本地副本和远程副本的区别如下。
- 本地副本有日志(Log),远程副本没有日志。有日志就表示有日志文件。
- 创建本地副本时,会读取“检查点文件”中这个分区的初始最高水位。远程副本没有初始最高水位。
注意:Kafka的数据目录下有3个检查点文件:恢复点、清理点、最高水位。检查点文件记录了每个分区及其对应的检查,点位直。最高水位也叫作复制,点,表示备份副本的数据同步位直。分区创建副本的相关代码如下:
每个副本对象都定义了两个元数据:最高水位元数据(highwater!'larkMetadata,简称HW)和偏移量元数据(logEndOffsetMetadata,简称LEO)。创建副本对象时,从检查点文件读取(replicationoffset-checkpoint)分区的HW作为初始的最高水位。相关代码如下:
副本对象定义了两个元数据,以及对应的get/set方法。以偏移iil元数据为例,logEndOffset_=是set方法,logEndOffset是get方法。副本对象的两个元数据代表副本的状态,对应的get/set方法会更新或者获取副本的状态。下面是偏移量和最高水位的更新方法调用链:
先来看偏移盐元数据的更新和获取方法。如果从本地副本的角度来看,有下面两种场景。
- 消息、集追加到主副本的本地日志,更新日志的下一个偏移量元数据(nextOffsetMetadata)。
- 备份副本读取到主副本的拉取结果,将拉取结果写到本地日志,也更新日志的下一个偏移量元数据。
上面两种场景都只是更新“日志”的下一个偏移量元数据,并不需要更新“副本”的偏移量元数据。针对本地副本,当需要获取副本的偏移量元数据,可以直接获取“日志”的偏移量元数据。如图6-50所示,生产者追加消息集到主副本的本地日志(步骤(2)),备份副本同步数据也会将拉取结果写入向己的本地日志(步骤(6)),这两种场景都会更新本地日志的偏移量元数据。除此之外,主副本所在的服务端处理备份副本的拉取请求,也会更新备份副本的偏移量元数据(步骤(4)),具体步骤如下。
(2)消息、集追加到主副本的本地日志,会更新日志的偏移量元数据。
(3)其他消息代理节点上的备份副本向主副本所在的消息代理节点同步数据。
(4)主副本所在的副本管理器读取本地日志,井更新对应拉取的备份副本信息。
(5)主副本所在的服务端将拉取结果返回给发起拉取请求的备份副本。
(6)备份副本接收到服务端返回的拉取结果,将消息集追加到本地日志,更新日志的偏移量元数据。
从图6-50可以看出,主副本所在节点更新备份副本的偏移量元数据,它更新的是远程副本(步骤(4))。而如果备份副本更新本地日志的偏移量元数据,它更新的是本地副本(步骤(6))。这两种更新动作发生的前提都必须是:备份副本向主副本发起了拉取请求(步骤。))。
- “备份副本”同步数据
备份副本向主副本所在的消息代理节点发送拉取请求,会指定备份副本编号(replicald)。服务端处理备份副本的拉取请求,会先读取主副本的本地日志文件,然后用日志的读取结果(logReadResults)更新备份副本的相关信息。相关代码如下:
服务端处理备份副本的拉取请求,除了更新备份副本的偏移量元数据,调用l"laybeExpandisr()方法可能还会扩展分区的ISR集合。扩展ISR集合必须满足下面3个条件。户
- 这个备份副本之前不在分区的ISR集合中,如果已经在ISR集合中,就不需要重复加入。
- 这个备份副本必须在分区的AR集合中,只有属于分区的副本,才会加入到ISR集合中。
- 这个备份副本的偏移量必须大于或等于主副本的最高水位,才会加入到ISR集合中。
分区扩展ISR的相关代码如下:
服务端处理备份副本的拉取请求,除了更新备份副本的偏移量元数据、判断是否需要将备份副本加入到ISR集合,还会调用MaybeIncrementleaderHW()方法判断是否需要增加主副本的最高水位。如果分区对应主副本的最高水位有增加,就会调用tryCoMpleteDelayedRequests()方法尝试完成延迟的请求:包括“延迟的生产”和“延迟的拉取”。相关代码如下:
注意:在6.2.1节中,生产者客户端设直的应答值如采是-1,则主副本必须等到JSR的所有备份副本都向主副本发送了应答后,服务端才会返回响应结果给客户端。服务端完成“延迟生产”的外部触发事件就是备份副本发送应答,那么当备份副本向主副本发送拉耳又请求,服务端处理备份副本的拉取请求,就可能会完成飞迟的生产”。除了备份副本主动发送拉取请求可能会尝试完成延迟的生产,另外一种场景是:追加消息集到主副本的本地日志,如果ISR只有一个主副本,会立即增加主副本的HW,并不需要等待其他备份副本发送应答。这种情况也会同时调用MaybeIncrementleaderHW()和tryCompleteDelayedRequests()方法。
尝试完成“延迟生产”对应的场景是:服务端处理生产者客户端的生产请求,没有满足“ISR所有副本发送应答给主副本”限制条件,创建了延迟的生产。尝试完成“延迟拉取”对应的场景是:服务端处理消费者客户端的拉取请求,没有满足“拉取到足够的消息”限制条件,创建了延迟的拉取。主副本的最高水位增加了,就可以同时尝试完成这两个被延迟的操作对象,可以从下面两个角度来分析这个原因。
- 消费者最多只能消费到主副本的最高水位,如果消费者已经消费到最高水位,但是主副本的最高水位一直没有增加,服务端就不会返回拉取结果给消费者。而一旦主副本的最高水位增加了,就有可能满足“拉取到足够的消息”限制条件,服务端就可以返回拉取结果给消费者。
- 主副本等待ISR集合的所有备份副本都向它发送应答,在这之前,服务端不会返回生产请求给生产者。主副本的最高水位会选择ISR集合中所有备份副本的最小偏移盐值。服务端处理备份副本的拉取请求,会更新备份副本的偏移量,那么就有可能会增加主副本的最高水位。
一旦增加了主副本的最高水位,表示ISR集合中所有副本一定都发送了应答,服务端就可以返回生产请求给生产者。
偏移量和最高水位是副本对象的两个重要数据,下面分析这两个状态的使用场景。
- 偏移量、最高水位、复制j点
备份副本向主副本同步数据的过程中,备份副本自己会更新本地的日志偏移茧,主副本所在的服务端也会更新对应备份副本的偏移量。比如,有l个主副本和3个备份副本,主副本的偏移盘是25,3个备份副本的偏移量分别是[8,9,lO],这些信息都可以通过分区对象的assignedReplicaMap成员变革获取。这就意味着:当需要获取分区所有副本的日志偏移盘时,直接查询分区的所有副本状态即可。如图6-51所示,备份副本同步数据时,除了更新副本的偏移量(LEO),也会更新副本的最高水位(HW),具体步骤如下。
(2)备份副本拉取到数据,更新本地的LEO。拉取响应带有主副本的HW,但主副本的HW还是0,备份
副本的HW也为0。
(3)备份副本再次拉取数据,会更新主副本的酬。主副本返回给备份副本的拉取响应包含最新的H训。
(4)备份副本拉取到数据,更新本地的LEO,并且也会更新备份副本的HW~
注意:备份副本无论在服务端读取出多少条记录,服务端都会把读取到的所有记录返回给备份副本。服务端知道本次读取的记录条数,就可以在返回结果前,更新备份副本对应的LEO。备份副本在收到拉取记录后,也会更新本地日志文件的LEO,这样主副本记录的备份副本LEO、备份副本自己记录的LEO是一致的数据。更新副本的偏移盘有下面两种场景:更新本地日志的偏移量、更新远程的备份剧本偏移量。
- 追加消息到主副本的本地日志、备份副本拉取消息写到自己的本地日志,都会更新日志的偏移量。
- 主副本所在的服务端处理备份副本的拉取请求,也会更新分区中备份副本对应的偏移量。更新副本的最高水位也有下面两种场景:更新主副本的最高水位、更新备份副本的最高水位。
- 主副本的最高水位取决于ISR中所有副本的最小偏移量。最小值没有变化,最高水位也不会变化。
- 备份副本的最高水位取决于主副本的最高水位和它向己的偏移量,它会选择这两者的最小值。
备份副本的拉取线程(ReplicaFetcherThread)发送拉取请求,它在收到主副本所在服务端返回的拉取结果后,会将拉取到的消息追加到备份副本向己的本地日志文件中,并且会更新日志的偏移量。同时,拉取结果中包含了主副本当前最新的最高水位,拉取线程会在备份副本的偏移量、主副本的最高水位两者之间选择最小值,作为备份副本的最高水位。相关代码如下:
日志管理器会定时将所有分区的副本偏移茧,刷写到恢复点文件(recovery-point-offset-checkpoint检查点文件)。副本管理器也会定时将所有分区的副本最高水位,刷写到复制点文件(replication-offsetcheckpoint检查点文件)。相关代码如下:
同一个分区在不同消息代理节点上,它们的本地副本都有偏移盘和最高水位 。 如图 6-52所示,主副本所在的节点会记录所有副本的偏移量,备份副本所在的节点只会记录它向己的偏移盐,不会记录其他副本的偏移量。
对于消费者客户端而言,它最多只会读取到主副本的最高水位。但因为主副本可能会出现故障,所以备份副本也需要记录最高水位。当主副本出现故障时,备份副本成为主副本,它的最高水位如果和之前主副本的最高水位保持一致,消费者客户端就不会丢失数据。关于分区和副本的容错处理,以及如何创建分区会在第7章控制器做更深入的分析。本节主要分析了逻辑意义上与存储相关的副本管理器、分区、副本。副本管理器管理了分区,分区管理了副本,副本对应了日志。副本管理器处理生产请求、拉取请求,如果不能立即返回响应结果给客户端,会创建对应的延迟操作对象。下面继续分析延迟操作会在什么时候完成。
6.2.2 分区与副本相关推荐
- kafka 分区和副本以及kafaka 执行流程,以及消息的高可用
1.Kafka概览 Apache下的项目Kafka(卡夫卡)是一个分布式流处理平台,它的流行是因为卡夫卡系统的设计和操作简单,能充分利用磁盘的顺序读写特性.kafka每秒钟能有百万条消息的吞吐量,因此 ...
- kafka分区及副本在broker的分配
kafka分区及副本在broker的分配 @(KAFKA)[kafka, 大数据] 部分内容参考自:http://blog.csdn.net/lizhitao/article/details/4177 ...
- kafka查看broker上主副本_kafka分区及副本在broker的分配
kafka分区及副本在broker的分配 以下以一个Kafka集群中4个Broker举例,创建1个topic包括4个Partition,2 Replication:数据Producer流动如图所看到的 ...
- Kafka topic分区增加副本
Kafka中topic的每个分区可以设置多个副本.如果副本数为1,当该分区副本的leader节点宕机后,会导致该分区不可用.故需要设置多副本来保证可用性. 实际项目中,存在项目初期创建了副本数为1的t ...
- kafka的副本以及分区与副本的关系
一 副本的作用 1.Kafka 副本作用:提高数据可靠性. 2.Kafka 中副本分为:Leader 和 Follower.Kafka 生产者只会把数据发往 Leader, 然后 Follower 找 ...
- Kafka系列之:深入理解Kafka 主题、分区、副本、LEO、ISR、HW、Kafka的主写主读和分区leader选举
Kafka系列之:深入理解Kafka 主题.分区.副本.LEO.ISR.HW.Kafka的主写主读和分区leader选举 一.Kafka重要知识点提炼 二.详细介绍Kafka 主题.分区.副本.LEO ...
- Kafka从入门到精通(七)分区和副本机制
1. 分区和副本机制 1.1 生产者分区写入策略 生产者写入消息到topic,Kafka将依据不同的策略将数据分配到不同的分区中 轮询分区策略 随机分区策略 按key分区分配策略 自定义分区策略 1. ...
- Kafka的分区和副本机制
文章目录 Leader和Follower 生产者分区写入策略 轮询分区策略 随机策略(不用) 按key分配策略 乱序问题 自定义分区策略 消费者组Rebalance机制 消费者分区分配策略 Range ...
- 【Kafka-分区增加副本】Kafka分区增加副本
[Kafka-分区增加副本]Kafka分区增加副本 1)前言 2)创建测试topic 3)增加副本 4)附录 1)前言 Kafka 中 topic 的每个分区可以设置多个副本.如果副本数为1,当该分区 ...
最新文章
- mysql级联查询_mysql 各种级联查询后更新(update select)
- mysql 表 地图_报表中的地图怎么做?
- dp线和hdmi区别_HDMI铜线与光纤线有啥区别?为什么铜线传播速度更快?看完涨知识...
- Java多线程学习十六:读写锁 ReadWriteLock 获取锁有哪些规则
- 怎么会Sql serverW数据库模型图转化成ord于--您还可以查看属性信息字段
- rk3399_android7.1调试USB蓝牙模块小结
- 在线搜索音乐播放器源码
- lisp如何将度分秒转换为弧度_1/16怎么转换成角度(度分秒)??
- 音视频同步、网络抖动
- Unity3d之坦克对战游戏 AI设计
- vm tools iso 文件下载 win 7
- autoquad源码分析1
- 《神奇的数学》读后感_《走进奇妙的数学世界》读后感
- css控制文本只显示两行
- Android 多进程的基础使用及优缺点
- win2003 由于可用空间计算失败_幼儿编程启蒙怎么做?智能家居+ai 玩空间是最佳教具...
- 粉色噪声 褐色噪声 布朗噪声
- 6 Vue 原理(SY)
- vim如何提高效率:使用jk绑定Esc
- 程序实现启用/禁用设备(驱动)enable/disable device with windows api
热门文章
- 三星s8怎么分屏操作_双屏互动,大有可为 三星Galaxy Z Fold2 5G的魅力折叠体验
- 片上总线Wishbone 学习(七)总线周期之握手协议
- oracle 实用记录
- matlab DSB-AM与SSB-AM的调制与解调
- ios下overflow:scoll中卡顿问题
- 程序员赚的辛苦钱及好朋友借钱[借钱时你是爷爷,借出去后丢一个朋友不说还多出一个爷爷]
- Github常用License总结(MIT/Apache/GPL)
- 《朗读者》读后感作文3100字
- 100baseT,1000baseX,1000baseTX,1000baseFX分别表示的意思
- # 2gether 在一起 # 一份生日Party邀请函待查收