首页天道酬勤kafka的ack,kafka 卡住

kafka的ack,kafka 卡住

张世龙 05-13 09:52 97次浏览

控制器组件(Controller),是 Apache Kafka 的核心组件。它的主要作用是在 Apache ZooKeeper 的帮助下管理和协调整个 Kafka 集群群集中的任何Broker都可以充当控制器,但在运行过程中只有一个Broker是控制器,负责管理和协调。 然后介绍了控制器的原理和内部运行机制。 在本文中,您将发现

什么是控制器中介控制器中介。 如何选举的控制器经纪人的主要作用是什么? Kafka是如何处理大脑分裂的? 什么是控制器经纪人? 分布式系统通常需要在分布式系统发生异常时发挥特殊作用的协调员。 在Kafka中,协调器称为“控制器”,但实际上控制器没有什么特殊之处,它本身也是普通的Broker,可以跟踪群集中的其他Broker,并根据需要添加新的Broker

控制器中介是如何选择的上一节介绍了什么是控制器中介,每个中介都可能充当控制器。 那么,控制器是怎么选择的呢? 集群启动后,Kafka如何确认哪个Broker有控制器?

实际上,Broker会尝试在启动时在ZooKeeper中创建/controller节点。 Kafka目前的选举控制规则是Kafka集群中始终只有一个Controller Broker。

控制器中介的具体作用是什么? 控制器中介的主要角色有很多,主要是一些管理行为,主要包括以下几个方面:

创建、删除主题、增加分区和分配leader分区群集的Broker管理(新Broker、Broker主动关闭、Broker故障)第一个成功创建 /controller 节点的 Broker 会被指定为控制器选举)分区leader选举)分区重新分配处理群集中的脱机Broker节点必须快速找到备用leader分区,以最大限度地减少停机时间。

控制器中介可以响应失败的中介,控制器中介可以从Zookeeper侦听(Zookeeper Watch )获取通知信息,Zookeeper可以向客户端发送znode的通知当创建、删除znode节点、更改子节点的数量或更改znode中存储的数据本身时,ZooKeeper节点更改侦听器会显式通知客户端。

每个Broker启动时,都会在zookeeper的/Brokers/ids下创建临时znode。 当Broker关闭或主动关闭时,该Broker与ZooKeeper的会话将停止,其znode将自动删除。 同样,zookeeper watch机制将此更改推送到控制器,以便控制器知道Broker已关闭或已关闭,并可以进行后续的协调操作。

控制器将收到通知并对其执行操作,以确定哪个Broker分区将成为leader分区。 然后通知每个相关的Broker,要求Broker的主题分区成为leader,或者通过LeaderAndIsr从新leader分区复制数据。

要处理群集中新添加的Broker,请将Leader分区副本均匀分布在群集的不同Broker上,以确保群集的负载平衡。 如果Broker发生故障,某些Broker上的分区副本将被选择为leader,并且Broker上有多个leader分区副本。 由于客户端只与leader分区副本进行交互,因此会给Broker带来额外的负担,并损害群集的性能和运行状况。 因此,尽快恢复平衡有利于集群健康运行。

Kafka认为leader分区副本的第一个分配(每个节点处于活动状态)是平衡的。 这些第一个选定分区的副本支持所谓的preferred leaderKafka或首选领导者(preferred leaders),因此leader分区和follower分区因此,leader分区副本的存在位置会影响集群的可靠性。

默认情况下,机架感知的leader选举(rack-aware leader election为true,表示Kafka可以定期执行一些主题分区

Leader 重选举。大部分情况下,Broker的失败很短暂,这意味着Broker通常会在短时间内恢复。所以当节点离开群集时,与其相关联的元数据并不会被立即删除。

当Controller注意到Broker已加入集群时,它将使用Broker ID来检查该Broker上是否存在分区,如果存在,则Controller通知新加入的Broker和现有的Broker,新的Broker上面的follower分区再次开始复制现有leader分区的消息。为了保证负载均衡,Controller会将新加入的Broker上的follower分区选举为leader分区。

注意:上面提到的选Leader分区,严格意义上是换Leader分区,为了达到负载均衡,可能会造成原来正常的Leader分区被强行变为follower分区。换一次 Leader 代价是很高的,原本向 Leader分区A(原Leader分区) 发送请求的所有客户端都要切换成向 B (新的Leader分区)发送请求,建议你在生产环境中把这个参数设置成 false。

同步副本(in-sync replica ,ISR)列表

ISR中的副本都是与Leader进行同步的副本,所以不在该列表的follower会被认为与Leader是不同步的. 那么,ISR中存在是什么副本呢?首先可以明确的是:Leader副本总是存在于ISR中。 而follower副本是否在ISR中,取决于该follower副本是否与Leader副本保持了“同步”。

始终保证拥有足够数量的同步副本是非常重要的。要将follower提升为Leader,它必须存在于同步副本列表中。每个分区都有一个同步副本列表,该列表由Leader分区和Controller进行更新。

选择一个同步副本列表中的分区作为leader 分区的过程称为clean leader election。注意,这里要与在非同步副本中选一个分区作为leader分区的过程区分开,在非同步副本中选一个分区作为leader的过程称之为unclean leader election。由于ISR是动态调整的,所以会存在ISR列表为空的情况,通常来说,非同步副本落后 Leader 太多,因此,如果选择这些副本作为新 Leader,就可能出现数据的丢失。毕竟,这些副本中保存的消息远远落后于老 Leader 中的消息。在 Kafka 中,选举这种副本的过程可以通过Broker 端参数 *unclean.leader.election.enable *控制是否允许 Unclean 领导者选举。开启 Unclean 领导者选举可能会造成数据丢失,但好处是,它使得分区 Leader 副本一直存在,不至于停止对外提供服务,因此提升了高可用性。反之,禁止 Unclean Leader 选举的好处在于维护了数据的一致性,避免了消息丢失,但牺牲了高可用性。分布式系统的CAP理论说的就是这种情况。

不幸的是,unclean leader election的选举过程仍可能会造成数据的不一致,因为同步副本并不是完全同步的。由于复制是异步完成的,因此无法保证follower可以获取最新消息。比如Leader分区的最后一条消息的offset是100,此时副本的offset可能不是100,这受到两个参数的影响:

replica.lag.time.max.ms:同步副本滞后与leader副本的时间zookeeper.session.timeout.ms:与zookeeper会话超时时间脑裂

如果controller Broker 挂掉了,Kafka集群必须找到可以替代的controller,集群将不能正常运转。这里面存在一个问题,很难确定Broker是挂掉了,还是仅仅只是短暂性的故障。但是,集群为了正常运转,必须选出新的controller。如果之前被取代的controller又正常了,他并不知道自己已经被取代了,那么此时集群中会出现两台controller。

其实这种情况是很容易发生。比如,某个controller由于GC而被认为已经挂掉,并选择了一个新的controller。在GC的情况下,在最初的controller眼中,并没有改变任何东西,该Broker甚至不知道它已经暂停了。因此,它将继续充当当前controller,这是分布式系统中的常见情况,称为脑裂。

假如,处于活跃状态的controller进入了长时间的GC暂停。它的ZooKeeper会话过期了,之前注册的/controller节点被删除。集群中其他Broker会收到zookeeper的这一通知。

由于集群中必须存在一个controller Broker,所以现在每个Broker都试图尝试成为新的controller。假设Broker 2速度比较快,成为了最新的controller Broker。此时,每个Broker会收到Broker2成为新的controller的通知,由于Broker3正在进行”stop the world”的GC,可能不会收到Broker2成为最新的controller的通知。

等到Broker3的GC完成之后,仍会认为自己是集群的controller,在Broker3的眼中好像什么都没有发生一样。

现在,集群中出现了两个controller,它们可能一起发出具有冲突的命令,就会出现脑裂的现象。如果对这种情况不加以处理,可能会导致严重的不一致。所以需要一种方法来区分谁是集群当前最新的Controller。

Kafka是通过使用epoch number(纪元编号,也称为隔离令牌)来完成的。epoch number只是单调递增的数字,第一次选出Controller时,epoch number值为1,如果再次选出新的Controller,则epoch number将为2,依次单调递增。

每个新选出的controller通过Zookeeper 的条件递增操作获得一个全新的、数值更大的epoch number 。其他Broker 在知道当前epoch number 后,如果收到由controller发出的包含较旧(较小)epoch number的消息,就会忽略它们,即Broker根据最大的epoch number来区分当前最新的controller。

 

上图,Broker3向Broker1发出命令:让Broker1上的某个分区副本成为leader,该消息的epoch number值为1。于此同时,Broker2也向Broker1发送了相同的命令,不同的是,该消息的epoch number值为2,此时Broker1只听从Broker2的命令(由于其epoch number较大),会忽略Broker3的命令,从而避免脑裂的发生。

总结

本文主要讲解了什么是Kafka Controller,它其实就是一个普通的Broker,除了需要负责一些额外的工作之外,其角色与其他的Broker基本一样。另外还介绍了Kafka Controller的主要职责,并对其中的一些职责进行了详细解释,最后还说明了kafka是如何避免脑裂的。

转自:

https://jiamaoxiang.top/2020/07/06/Kafka%E7%9A%84Controller-Broker%E6%98%AF%E4%BB%80%E4%B9%88/

mvc分别用什么实现,controller kafka常用命令,消息队列作用