Kafka原理

目录

1、kafka架构图

2、如何读取消息的?

3、kafka复制原理和同步方式的基本概念

4、副本消息复制原理?

5、消费者什么时候能开始读消息?

6、消息可以不丢失或不重复吗?

7、Kafka如何确保消息在producer和consumer之间传输?

 8、生产者和消费者常用参数

生产者

消费者

其它


1、kafka架构图

2、如何读取消息的?

  • partition还可以细分为segment,防止partition中的消息无限扩张,以segment为单位又将partition细分。
  • segment文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示为segment索引文件和数据文件。
  • 命名规则:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充,如下:
00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log

例如:segment:00000000000000170410的 “.index”文件和“.log”文件的对应的关系,如下图: 

具体流程:读取消息时以“.index”索引文件中的元数据[3, 348]为例,在“.log”数据文件表示第3个消息,即在全局partition中表示170410+3=170413个消息,该消息的物理偏移地址为348。

例如要读取offset=170418的消息,由于170418>0 并且小于239430,先找到00000000000000170410.index文件,然后根据二分查找法找到第8个文件,再找到对应的物理偏移地址“1325”,通过[8,1325]定位到00000000000000170410.log文件中的1325的位置进行读取。

3、kafka复制原理和同步方式的基本概念

LEO:是LogEndOffset的缩写,表示每个partition的log最后一条Message的位置。

HW:是HighWatermark的缩写,高水位。是指consumer能够看到的此partition的位置。leader和follower各自负责更新自己的HW的状态。(例如:发送消息4和5,当leader接收到4和5,follower都同步数据4后,hw更新到4,此时消费者可以消费4这条数据。)

ISR: (In-Sync Replicas),这个是指副本同步队列。消息复制延迟受最慢的follower限制,重要的是快速检测慢副本,如果follower“落后”太多或者失效,leader将会把它从ISR中删除,放到OSR中

AR:(Assigned Replicas),所有副本(replicas)的统称。

OSR:(Outof-Sync Replicas)列表,延迟超过一定延迟时间后,副本会放入OSR中,新加入的follower也会先存放在OSR中。AR=ISR+OSR。

4、副本消息复制原理?

leader处理partition的所有读写请求,与此同时,follower会被动定期地去复制leader上的数据。

例如:4个broker, 某topic有3个partition,且复制因子即副本个数也为3,如下图:

5、消费者什么时候能开始读消息?

leader会等待该消息被所有ISR中的replicas同步后更新HW,此时消息才能被consumer消费。这样就保证了如果leader所在的broker失效,该消息仍然可以从新选举的leader中获取。

如图:当producer生产消息至broker后,ISR以及HW和LEO的流转过程:

Controller:Kafka集群中的其中一个Broker会被选举为Controller,主要负责Partition管理和副本状态管理,也会执行类似于重分配partition之类的管理任务。如:leader的重新选举

leader来维护:leader有单独的线程定期检测ISR中follower是否脱离ISR, 如果发现ISR变化,则会将新的ISR的信息返回到Zookeeper的相关节点中。

6、消息可以不丢失或不重复吗?

不丢失:request.required.acks=-1时(其它情况leader异常,消息丢失,因为副本(之后会被选择为leader)没有同步到最新的消息),当所有的follower都同步消息成功后发送ack。如果所有副本同步成功消息后,leader异常,不会有消息丢失。如果部分副本没有同步完消息,此时leader异常可能会有消息重复消费的情况,但是不能确保不重复。

如图:如果在leader crash的时候,follower2还没有同步到任何数据,而且follower2被选举为新的leader的话,这样消息就不会重复。如果follower1选举为leader,由于4、5消息重新发送,所以会重复消费4和5这两个消息。

注意:leader挂掉会重新选举,新的leader会发送“指令”让其余的follower截断至自身的HW的位置然后再拉取新的消息。 当ISR中的个副本的LEO不一致时,如果此时leader挂掉,选举新的leader时并不是按照LEO的高低进行选举,而是按照ISR中的顺序选举。

如图:A机器宕机,这时候如果B成为leader,假如没有HW,在A重新恢复之后会做同步(makeFollower)操作,在宕机时log文件之后直接做追加操作,而假如B的LEO已经达到了A的LEO,会产生数据不一致的情况,所以使用HW来避免这种情况。A在做同步操作的时候,先将log文件截断到之前自己的HW的位置,即3,之后再从B中拉取消息进行同步。

7、Kafka如何确保消息在producer和consumer之间传输?

有一下三种可能:

  • At most once: 消息可能会丢,但绝不会重复传输

  • At least once:消息绝不会丢,但可能会重复传输

  • Exactly once:每条消息肯定会被传输一次且仅传输一次

1、如果producer发送数据给broker后,遇到的网络问题而造成通信中断,那producer就无法判断该条消息是否已经提交(commit)。虽然Kafka无法确定网络故障期间发生了什么,但是producer可以retry多次,确保消息已经正确传输到broker中,所以目前Kafka实现的是at least once。

2、consumer消费消息时,从broker中读取消息后,可以选择commit,该操作会在Zookeeper中存下该consumer在该partition下读取的消息的offset。该consumer下一次再读该partition时会从下一条开始读取。

  • 自动提交时:即读取到消息就提交,则是Exactly once。但producer可能由于网络异常会进行retry,此时是At least once。但是,consumer还没处理消息就crash了,下次重新开始工作后就无法读到刚刚已提交而未处理的消息,这就对应于at most once了。
  • 读完消息先处理再commit时:这种模式下,如果处理完了消息在commit之前consumer crash了,下次重新开始工作时还会处理刚刚未commit的消息,实际上该消息已经被处理过了,这就对应于at least once。

 8、生产者和消费者常用参数

生产者

1、request.required.acks (默认-1)

producer接收消息ack的时机,

0:producer不会等待broker发送ack;

1:当leader接收到消息之后发送ack;

-1:当所有的follower都同步消息成功后发送ack;

2、request.timeout.ms (10000)

在向producer发送ack之前,broker允许等待的最大时间。如果超时,broker将会向producer发送一个error ack。意味着上一次消息因为某种原因未能成功(比如follower未能同步成功)

3、message.send.max.retries(3)

当producer接收到error ack,或者没有接收到ack时,允许消息重发的次数。

消费者

partition.rebalance.type (30s gap)

partiton重新分配时挂起的时间,默认30s(2.2.26及以上客户端版本支持。场景:服务重新上线时,partition会进行重新分配,为防止重复消费,partition会被挂起30s,会照成短暂消息积压,如果不关系重复消费,比较关心积压,可设置no gap)

其它

1、unclean.leader.election.enable=false时,leader只能从ISR中选举,当ISR中所有副本都失效之后,需要ISR中最后失效的那个副本能恢复之后才能选举leader

2、min.insync.replicas设置为2,如果ISR中replicas只有一个节点存活,可以提供read服务,不能write

3、leader选举

只有ISR里的成员才能有被选为leader的可能(unclean.leader.election.enable=false) 

在ISR中至少有一个follower时,Kafka可以确保已经commit的数据不丢失。

两种策略,默认是第二种

  • 等待ISR中任意一个replica“活”过来,并且选它作为leader
  • 选择第一个“活”过来的replica(并不一定是在ISR中)作为leader

参考:

 必读:kafka数据可靠性深度解读

常用参数:kafka生产者和消费者常用参数

一直rebalance: session.timeout.ms 和 heartbeat.interval.ms的区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值