kafka(三): 数据生产流程,数据复制与Replica Failover

版权声明:本文为博主原创文章,转载请注明出处,欢迎交流,qq911283415。 https://blog.csdn.net/HaixWang/article/details/81090720

【这是一篇7月份躺在草稿箱的文章,今天翻出来整理一下。】

数据生产流程

1.发送到kafka的数据会封装为ProducerRecord对象,包含topic、partition、key、value信息;
2.调用send()方法后,将数据序列化为字节数组,如果没有指定分区 ,那么分区器会根据ProducerRecord 对象的键来计算一个分区;
3.当消息达到一个批次设定的量(消息放在缓冲区中),通过网络发送到不同的主题,不同的分区;
4.如果消息成功写入 Kafka,就返回 一 个
RecordMetaData 对象,它包含了主题和分区信息,以及记录在分区里的偏移量。如果写入
失败, 则告知生产者尝试重新发送消息,达到最大重试次数就抛出异常。

数据复制

第一个注册到Zookeeper的broker为Contrllor,除了具有一般 broker 的功能之外,还负责加入集群的broker上的分区首领的选举(以及离开集群的broker上的首领分区的重新选举)。

  1. kafka中,每一个partition,有一个leader(所以集群并不是一定只有一个leader,可能有多个leader),其他follower去拉取数据。
  2. 考虑到数据的一致性,Kafka中,消费者只能读取被commit的数据,因为如果允许消费者读取非commit的数据,考虑消费者1读取机器A中的数据,而该数据只有A和leader中有数据,其他flower还没与pull复制,这个时候leader和A挂了,此时别的消费者就读取不到,从而数据不一致。
    副本有“首领副本”和“跟随者副本”的概念(LSR就与它们有关):为了保证一致性,所有生产者请求和消费者请求都会经过首领副本。
    【跟随者副本不处理来自客户端的请求,它们唯一的任务就是从首领那里复制消息,保持与首领一致的状态。】

  3. 一个partition物理上由多个segment组成,每个Segment存着message信息(每个partiton为一个目录)数据过期清除,就是以segment为单位,分区的复制设置:offsets.topic.replication.factor

  4. partition的命名规则为:topic名称+有序序号,第一个序号从0开始计,最大的序号为partition数量减1
  5. 每个partition(目录)相当于一个巨型文件被平均分配到多个大小相等的segment(段)数据文件中(每个segment 文件中消息数量不一定相等)这种特性也方便old segment的删除,即方便已被消费的消息的清理,提高磁盘的利用率。每个partition只需要支持顺序读写就行,segment的文件生命周期由服务端配置参数(log.segment.bytes,log.roll.{ms,hours}等若干参数)决定。
  6. segment文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示为segment**索引文件和数据文件**。这两个文件的命令规则为:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充

Kafka 的消息复制机制一般只能在单个集群里进行。
Kafka 提供了 一 个叫作 MirrorMaker 的工具,可以用它来实现集群间的消息复制。

这里写图片描述
2. leader会维护一个与leader同步的Replica列表(ISR),当其发现某一flower的复制的列表落后太多,或者超时没有发起拉取请求,会将其从ISR中移除。换句话说,leader负责维护和跟踪ISR(In-Sync Replicas)中所有follower滞后的状态
3. 剔除出ISR依靠延迟时间replica.lag.time.max.ms和延迟条数replica.lag.max.messages两个维度, 当前最新的版本0.10.x中只支持replica.lag.time.max.ms这个维度),任意一个超过阈值都会把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表。也就是说,总副本数=ISR中副本+OSR中副本

副本、拉取、多leader图:(图片源自网络):
这里写图片描述

数据可靠性

1.producer向leader发送数据时,可以通过request.required.acks参数来设置数据可靠性的级别

  • 1(默认):这意味着producer在ISR中的leader已成功收到的数据并得到确认后发送下一条message。如果leader宕机了,则会丢失数据。(可以理解为更偏向于同步复制)
  • 0:这意味着producer无需等待来自broker的确认而继续发送下一批消息。这种情况下数据传输效率最高,但是数据可靠性确是最低的。(可以理解为更偏向于异步复制)
  • -1:producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。但是这样也不能保证数据不丢失,比如当ISR中只有leader时
    所以数据可靠性要求极高时,可设置该参数值为-1
  • Topic的参数min.insync.replicas当request.required.acks参数设置为-1时,才生效。表示ISR中的最小副本数是多少,如果ISR中的副本数少于min.insync.replicas配置的数量时,客户端会返回异常:org.apache.kafka.common.errors.NotEnoughReplicasExceptoin
  • 我们也很有必要将上方的两个参数结合使用,因为在min.insync.replicas设置为1时,leader挂掉,就没有备份的数据了(其他flower还没来得及去pull)
    2.Kafka 可以保证分区消息的顺序(对于单个分区而言)
    3.只有当消息被写入分区的所有同步副本时(但不一定要写入磁盘),它才被认为是“已提交”的,否则,broker不认为它正确接受了此消息。消费者只能读取已经提交的悄息。
    4.上方提到的消息分本的复制策略。

Replica Failover

部分宕机

这里写图片描述
1.第一次LSR中有A、B、C、三个server(leader+flower),此时只有m1可以commit。
2.leader A挂掉,产生新的leader B,commit m2
4.A恢复,发现落后的数量小于参数设定值,会catch up——重新pull m2、m4、m5
5.flower的恢复类似,只是说flower挂掉后不重新选举leader
m3的恢复?
因为m3从来没有被commit,所以producer会retry发送
所以kafka不能保证消费者消费的数据时producer发送的数据,消费者消费数据的顺序是leader们commit的顺序!!!

全部宕机

这里写图片描述

假设9台机器,全部宕机前5台机器在LSR中:
1.等待之前在LSR中的任一一台机器恢复。一致性好。(CAP之consistency)
2.等待9台机器任意一台恢复,设置为leader。高可用性。(默认)(CAP之Availability)

参考

importnew,深度好文

猜你喜欢

转载自blog.csdn.net/HaixWang/article/details/81090720
今日推荐