IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> kafka系列(七)—— kafka常见面试题 -> 正文阅读

[大数据]kafka系列(七)—— kafka常见面试题

1、kafka中的ISR、AR又代表什么?ISR伸缩又是什么?

分区中的所有副本统称为AR(Assigned Repllicas)。所有与leader副本保持一定程度同步的副本(包括Leader)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。消息会先发送到leader副本,然后follower副本才能从leader副本中拉取消息进行同步,同步期间内follower副本相对于leader副本而言会有一定程度的滞后。前面所说的“一定程度”是指可以忍受的滞后范围,这个范围可以通过参数进行配置。与leader副本同步滞后过多的副本(不包括leader)副本,组成OSR(Out-Sync Relipcas),由此可见:AR=ISR+OSR。在正常情况下,所有的follower副本都应该与leader副本保持一定程度的同步,即AR=ISR,OSR集合为空。

? Leader副本负责维护和跟踪ISR集合中所有的follower副本的滞后状态,当follower副本落后太多或者失效时,leader副本会吧它从ISR集合中剔除。如果OSR集合中follower副本“追上”了Leader副本,之后再ISR集合中的副本才有资格被选举为leader,而在OSR集合中的副本则没有机会(这个原则可以通过修改对应的参数配置来改变)


ISR的伸缩:

Kafka在启动的时候会开启两个与ISR相关的定时任务,名称分别为“isr-expiration"和”isr-change-propagation"。isr-expiration任务会周期性的检测每个分区是否需要缩减其ISR集合。这个周期和“replica.lag.time.max.ms”参数有关。大小是这个参数一半。默认值为5000ms,当检测到ISR中有是失效的副本的时候,就会缩减ISR集合。如果某个分区的ISR集合发生变更, 则会将变更后的数据记录到ZooKerper对应/brokers/topics//partition//state节点中。节点中数据示例如下:

{“controller_cpoch":26,“leader”:0,“version”:1,“leader_epoch”:2,“isr”:{0,1}}

? 其中controller_epoch表示的是当前的kafka控制器epoch.leader表示当前分区的leader副本所在的broker的id编号,version表示版本号,(当前半本固定位1),leader_epoch表示当前分区的leader纪元,isr表示变更后的isr列表。

除此之外,当ISR集合发生变更的时候还会将变更后的记录缓存到isrChangeSet中,isr-change-propagation任务会周期性(固定值为2500ms)地检查isrChangeSet,如果发现isrChangeSet中有ISR 集合的变更记录,那么它会在Zookeeper的/isr_change_notification的路径下创建一个以isr_change开头的持久顺序节点(比如/isr_change_notification/isr_change_0000000000), 并将isrChangeSet中的信息保存到这个节点中。kafka控制器为/isr_change_notification添加了一个Watcher,当这个节点中有子节点发生变化的时候会触发Watcher动作,以此通知控制器更新相关的元数据信息并向它管理的broker节点发送更新元数据信息的请求。最后删除/isr_change_notification的路径下已经处理过的节点。频繁的触发Watcher会影响kafka控制器,zookeeper甚至其他的broker性能。为了避免这种情况,kafka添加了指定的条件,当检测到分区ISR集合发生变化的时候,还需要检查一下两个条件:

? (1)上一次ISR集合发生变化距离现在已经超过5秒,

? (2)上一次写入zookeeper的时候距离现在已经超过60秒。

满足以上两个条件之一者可以将ISR写入集合的变化的目标节点。

有缩减就会有补充,那么kafka何时扩充ISR的?

随着follower副本不断进行消息同步,follower副本LEO也会逐渐后移,并且最终赶上leader副本,此时follower副本就有资格进入ISR集合,追赶上leader副本的判定准侧是此副本的LEO是否小于leader副本HW,这里并不是和leader副本LEO相比。ISR扩充之后同样会更新ZooKeeper中的/broker/topics/partition/state节点和isrChangeSet,之后的步骤就和ISR收缩的时的相同。

? 当ISR集合发生增减时,或者ISR集合中任一副本LEO发生变化时,都会影响整个分区的HW。

如下图所示,leader副本的LEO为9,follower副本的LEO为7,而follower2副本的LEO为6,如果判定这三个副本都处于ISR集合中,那么分区的HW为6,如果follower3已经判定失效副本被剥离出ISR集合,那么此时分区HW为leader副本和follower副本中LEO的最小值,即为7。

LW是Low Watermark的缩写,俗称“低水位”,代表AR集合中最小的logStartOffset值,副本的拉取请求(FetchRequest,它有可能触发新建日志分段而旧的的被清理,进而导致logStartoffset的增加)和删除请求(DeleteRecordRequest)都可能促使LW的增长。

在这里插入图片描述

?kafka中的HW、LEO、LSO、LW等分别代表什么?

?ISR与HW和LEO也有紧密的关系,HW是High Watermak的缩写, 俗称高水位,它表示了一个特定消息的偏移量(offset),消费之只能拉取到这个offset之前的消息。

如下,它代表一个日志文件,这个日志文件中有9条消息,第一消息的offset(LogStartOffset)为0,最后的一条消息offset为8,offset为9的消息用虚线框表示,代表下的一个待写入的消息。日志文件的HW为6.表示消费者只能拉取到offset0至5之间的消息,而offset为6的消息对消费者而言是不可见的。

在这里插入图片描述

LEO是Log End Offset的缩写,它表示了当前日志文件中下一条待写入消息的offset,如上图offset为9的位置即为当前日志文件LEO,LEO的大小相当于当前日志分区中最后一条消息的offset值加1。分区ISR集合中的每个副本都会维护自身的LEO,而ISR集合中最小的LEO即为分区的HW,对消费这而言只能消费HW之前的消息。

? 如下图,假设某个分区的ISR集合中有三个副本,即一个leader副本和两个follower副本,此时分区的LEO和HW都为3。消息3和消息4从生产者发出之后会被先存入leader副本。
在这里插入图片描述

在这里插入图片描述

在消息写入leader副本之后,follower副本会发送拉取请求来拉取消息3和消息4以进行消息同步。

? 在同步过程中,不同的follower副本的同步效率也不尽相同。如下图,在某一时刻follower1完全跟上了leader副本而follower2只同步了消息3,如此leader副本的LEO为5,follower1的LEO为5,Follower2的LEO为4。那么当前分区的HW最小值4,此时消费者可以消费到offset为0-3之间的消息。

? 写入消息如下图,所有的副本都成功写入了消息3和消息4,整个分区的HW和LEO为5,因此消费者可以消费offset为4的消息了。

在这里插入图片描述

由此可见,kafka的复制机制不是完全的同步复制,也不是单纯的异步复制,事实上,同步复制要求所有能工作的Follower副本都复制完,这条消息才会被确认为成功提交,这种复制方式影响了性能。而在异步复制的情况下, follower副本异步地从leader副本中复制数据,数据只要被leader副本写入就被认为已经成功提交。在这种情况下,如果follower副本都没有复制完而落后于leader副本,如果突然leader副本宕机,则会造成数据丢失。Kafka使用这种ISR的方式有效的权衡了数据可靠性与性能之间的关系。


什么是LSO?

LSO特指LastStableOffset。它具体与kafka的事物有关。

消费端参数——isolation.level,这个参数用来配置消费者事务的隔离级别。字符串类型,“read_uncommitted”和“read_committed”,表示消费者所消费到的位置,如果设置为“read_committed",那么消费这就会忽略事务未提交的消息,既只能消费到LSO(LastStableOffset)的位置,默认情况下,”read_uncommitted",既可以消费到HW(High Watermak)的位置。

注:follower副本的事务隔离级别也为“read_uncommitted",并且不可修改。

? 在开启kafka事务的同时,生产者发送了若干消息,(msg1,msg2,)到broker中,如果生产者没有提交事务(执行CommitTransaction),那么对于isolation.level=read_committed的消费者而言是看不多这些消息的,而isolation.level=read_uncommitted则可以看到。事务中的第一条消息的位置可以标记为firstUnstableOffset(也就是msg1的位置)。

? 这个LSO还会影响到kafka消费之后的量,(也就是kafka,Log,很多时候也称之为kafka堆积量)的计算 。如下图。

在这里插入图片描述

在图中,对每一个分区而言,它Lag等于HW-ConsumerOffset的值,其中ComsmerOffset表示当前的消费的位移,当然这只是针对普通的情况。如果为消息引入了事务,那么Lag的计算方式就会有所不同。

如果当消费者客户端的isolation.level的参数配置为“read_uncommitted"(默认),那么Lag的计算方式不受影响,如果这个参数配置为“read_committed",那么就要引入LSO来进行计算了。
在这里插入图片描述

对于未完成的事务而言,LSO的值等于事务中的第一条消息所在的位置,(firstUnstableOffset)

? 对于已经完成的事务而言,它的值等同于HW相同,所以我们可以得出一个结论:LSO≤HW≤LEO

在这里插入图片描述

所以,对于分区中未完成的事务,并且消费者客户端的isolation.level参数配置为”read_committed"的情况,它对应的Lag等于LSO-ComsumerOffset的值。

原文链接:https://blog.csdn.net/weixin_43975220/article/details/93190906

2.Kafka 中的 ISR(InSyncRepli)、OSR(OutSyncRepli)、AR(AllRepli)代表什么?

AR = ISR+OSR

ISR:In-Sync Replicas 副本同步队列
AR:Assigned Replicas 所有副本
ISR是由leader维护,follower从leader同步数据有一些延迟(包括延迟时间replica.lag.time.max.ms和延迟条数replica.lag.max.messages两个维度, 当前最新的版本0.10.x中只支持replica.lag.time.max.ms这个维度),任意一个超过阈值都会把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中。AR=ISR+OSR。

ISR:?kafka 使用多副本来保证消息不丢失,多副本就涉及到kafka的复制机制,在一个超大规模的集群中,时不时地这个点磁盘坏了,那个点cpu负载高了,出现各种各样的问题,多个副本之间的复制,如果想完全自动化容错,就要做一些考量和取舍了。我们举个例子说明下运维中面对的复杂性,我们都知道 kafka 有个 ISR集合,我先说明下这个概念:

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

1. leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护

2. 如果一个follower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除

3. 当ISR中所有Replica都向Leader发送ACK时,leader才commit,这时候producer才能认为一个请求中的消息都commit了。

kafka中的副本机制是以分区粒度进行复制的,我们在kafka中创建 topic的时候,都可以设置一个复制因子,这个复制因子决定着分区副本的个数,如果leader 挂掉了,kafka 会把分区主节点failover到其他副本节点,这样就能保证这个分区的消息是可用的。leader节点负责接收producer 打过来的消息,其他副本节点(follower)从主节点上拷贝消息。

存在的问题:

从上面的情况来看,两个参数看似已经足够了,如果一个副本超过 replica.lag.time.max.ms 还没有发送fetch同步请求, 可以认为这个副本节点卡住了,然后踢出去,但是还有一种比较特殊的情况没有考虑到,我们上文中设置 replica.lag.max.messages 为4,之所以设置为 4, 是我们已经知道 producer 每次请求打过来的消息数都在 4 以下,如果我们的参数是作用于多个 topic 的情况,那么这个 producer 最大打过来的消息数目就不好估计了,或者说在经常出现流量抖动的情况下,就会出现一个什么情况呢,我们还是使用例子说明:

  如果我们的 topic — foo 的 producer 因为流量抖动打过来一个 包含 4条消息的请求,我们设置的 replica.lag.max.messages 还是为4, 这个时候,所有的 follower 都会因为超出落后条数被踢出 ISR集合。

  然后,因为 follower 是正常的,所以下一次 fetch 请求就会又追上 leader, 这时候就会再次加入 ISR 集合,如果经常性的抖动,就会不断的移入移出ISR集合,会造成令人头疼的 告警轰炸。

  kafka 给出的方案是这样的,对 replica.lag.time.max.ms?这个配置的含义做了增强,和之前一样,如果 follower 卡住超过这个时间不发送fetch请求, 会被踢出ISR集合,新的增强逻辑是,在 follower 落后 leader 超过?eplica.lag.max.messages?条消息的时候,不会立马踢出ISR 集合,而是持续落后超过?replica.lag.time.max.ms?时间,才会被踢出

3.Kafka 中的 HW、LEO 等分别代表什么?

  • LEO:即日志末端位移(log end offset),记录了该副本底层日志(log)中下一条消息的位移值。注意是下一条消息!也就是说,如果LEO=10,那么表示该副本保存了10条消息,位移值范围是[0, 9]。
  • High Watermark(高水位线)以下简称HW,表示消息被leader和ISR内的follower都确认commit写入本地log,所以在HW位置以下的消息都可以被消费(不会丢失)。

Kafka复制协议有两个阶段,第一阶段,follower从leader获取到消息;第二阶段,在下一轮的RPC中向leader发送fetch request确认收到消息。假设其他的follower也都确认了,那么leader会更新HW,并在接下来的RPC中响应给follower。
同时,在重启一个follower时,这个follower可能会把日志截断到HW处(意味着此follower将会删除一些消息),然后从leader获取消息。

正是有与Kafka的复制协议分两个阶段,导致使用高水位会出现数据丢失和数据不一致的问题,下面我们分别讲一下这两种问题:

①数据丢失【Scenario 1: High Watermark Truncation followed by Immediate Leader Election】

假设有A、B两个Broker,初始时B为leader,A从B中取到消息m2,所以A中有消息m2了,但是由于在下一轮RPC中,A才会更新自己的HW,所以此时A的HW没变。如果这时候A重启了,他截取自己的日志到HW并发送一个fetch request到B。不幸的是,B这时宕机了,A成了新的leader,那么此时消息m2就会永久的丢失了。

②数据不一致:【Scenario 2: Replica Divergence on Restart after Multiple Hard Failures】

假设我们有两个Broker,初始时A是leader,B是follower。A接收到m2消息,但B还没来得及复制时,断电了。过了一会,B重启了,成为了leader,接收了m3消息,HW+1。然后A重启了,截断日志到高水位,但是此时的消息却出现了不一致。

在0.11版本使用leader epoch解决这两个问题。

4.Kafka 中的分区器、序列化器、拦截器是否了解?它们之间的处理顺序是什么?

分区器:根据键值确定消息应该处于哪个分区中,默认情况下使用轮询分区,可以自行实现分区器接口自定义分区逻辑
  序列化器:键序列化器和值序列化器,将键和值都转为二进制流 还有反序列化器 将二进制流转为指定类型数据
  拦截器:两个方法 doSend()方法会在序列化之前完成 ,onAcknowledgement()方法在消息确认或失败时回调。 可以添加多个拦截器按顺序执行。

 调用顺序:?拦截器doSend() -> 序列化器 -> 分区器

5.当你使用 kafka-topics.sh 创建(删除)了一个 topic 之后,Kafka 背后会执行什么逻辑?

1)会在 zookeeper 中的/brokers/topics 节点下创建一个新的 topic 节点,如:

/brokers/topics/first

2)触发 Controller 的监听程序
3)kafka Controller 负责 topic 的创建工作,并更新 metadata cache

6.Kafka 有内部的 topic 吗?如果有是什么?有什么所用?

kafka在0.10.x版本后默认将消费者组的位移(offset)提交到自带的topic__consumer_offsets里面,当有消费者第一次消费kafka数据时就会自动创建,它的副本数不受集群配置的topic副本数限制,分区数默认50(可以配置),默认压缩策略为compact

7.Kafka 分区分配的概念?

当遇到“分区分配”这个字眼的时候,一定要记住有三处地方,分别是生产者发送消息、消费者消费消息、创建主题

1、生产者的分区分配

  对于用户而言,当调用send方法发送消息之后,消息就自然而然的发送到了broker中。其实在这一过程中,有可能还要经过拦截器、序列化器和分区器(Partitioner)的一系列作用之后才能被真正地发往broker。

  消息在发往broker之前是需要确定它所发往的分区的,如果消息ProducerRecord中指定了partition字段,那么就不需要分区器的作用,因为partition代表的就是所要发往的分区号。如果消息    

  ProducerRecord中没有指定partition字段,那么就需要依赖分区器,根据key这个字段来计算partition的值。分区器的作用就是为消息分配分区。

  默认情况下,如果消息的key不为null,那么默认的分区器会对key进行哈希(采用MurmurHash2算法,具备高运算性能及低碰撞率),最终根据得到的哈希值来计算分区号,拥有相同key的消息会被写入同一个分区。如果key为null,那么消息将会以轮询的方式发往主题内的各个可用分区

2、消费者的分区分配

  在Kafka的默认规则中,每一个分区只能被同一个消费组中的一个消费者消费。消费者的分区分配是指为消费组中的消费者分配所订阅主题中的分区。

Kafka自身提供了三种策略,分别为RangeAssignorRoundRobinAssignor以及StickyAssignor,其中RangeAssignor为默认的分区分配策略

3、broker端的分区分配

  生产者的分区分配是指为每条消息指定其所要发往的分区,消费者中的分区分配是指为消费者指定其可以消费消息的分区,而这里的分区分配是指为集群制定创建主题时的分区副本分配方案,即在哪个broker中创建哪些分区的副本。分区分配是否均衡会影响到Kafka整体的负载均衡,具体还会牵涉到优先副本等概念。

8.聊一聊 Kafka Controller 的作用?

 Controller 作为 Kafka Server 端一个重要的组件,它的角色类似于其他分布式系统 Master 的角色,跟其他系统不一样的是,Kafka 集群的任何一台 Broker 都可以作为 Controller,但是在一个集群中同时只会有一个 Controller 是 alive 状态。Controller 在集群中负责的事务很多,比如:集群 meta 信息的一致性保证、Partition leader 的选举、broker 上下线等都是由 Controller 来具体负责。

Controller 是运行在 Broker 上的,任何一台 Broker 都可以作为 Controller,但是一个集群同时只能存在一个 Controller,也就意味着 Controller 与数据节点是在一起的,Controller 做的主要事情如下:

  1. Broker 的上线、下线处理;
  2. 新创建的 topic 或已有 topic 的分区扩容,处理分区副本的分配、leader 选举;
  3. 管理所有副本的状态机和分区的状态机,处理状态机的变化事件;
  4. topic 删除、副本迁移、leader 切换等处理。

9.Kafka 中有那些地方需要选举?这些地方的选举策略又有哪些?

Kafka中的选举大致可以分为三大类:控制器的选举、分区leader的选举以及消费者相关的选举。

1、控制器的选举

在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态等工作。比如当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。再比如当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。

Kafka Controller的选举是依赖Zookeeper来实现的,在Kafka集群中哪个broker能够成功创建/controller这个临时(EPHEMERAL)节点他就可以成为Kafka Controller。

2、分区leader的选举

  分区leader副本的选举由Kafka Controller 负责具体实施。当创建分区(创建主题或增加分区都有创建分区的动作)或分区上线(比如分区中原先的leader副本下线,此时分区需要选举一个新的leader上线来对外提供服务)的时候都需要执行leader的选举动作。

  基本思路是按照AR集合中副本的顺序查找第一个存活的副本,并且这个副本在ISR集合中。一个分区的AR集合在分配的时候就被指定,并且只要不发生重分配的情况,集合内部副本的顺序是保持不变的,而分区的ISR集合中副本的顺序可能会改变。注意这里是根据AR的顺序而不是ISR的顺序进行选举的。

  还有一些情况也会发生分区leader的选举,比如当分区进行重分配(reassign)的时候也需要执行leader的选举动作。这个思路比较简单:从重分配的AR列表中找到第一个存活的副本,且这个副本在目前的ISR列表中。

  再比如当发生优先副本(preferred replica partition leader election)的选举时,直接将优先副本设置为leader即可,AR集合中的第一个副本即为优先副本。

3、消费者相关的选举

  组协调器GroupCoordinator需要为消费组内的消费者选举出一个消费组的leader,这个选举的算法也很简单,分两种情况分析。如果消费组内还没有leader,那么第一个加入消费组的消费者即为消费组的leader。如果某一时刻leader消费者由于某些原因退出了消费组,那么会重新选举一个新的leader。

10.失效副本是指什么?有那些应对措施?

正常情况下,分区的所有副本都处于 ISR 集合中,但是难免会有异常情况发生,从而某些副本被剥离出 ISR 集合中。在 ISR 集合之外,也就是处于同步失效或功能失效(比如副本处于非存活状态)的副本统称为失效副本,失效副本对应的分区也就称为同步失效分区,即 under-replicated 分区。

  可以参考??https://www.cnblogs.com/luozhiyun/p/12079527.html

参考:https://www.cnblogs.com/wsw-seu/p/13462327.html

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-08-11 12:28:56  更:2021-08-11 12:30:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 20:16:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码