当前位置: 首页 > article >正文

kafka服务端之控制器

文章目录

  • 概述
  • 控制器的选举与故障恢复
    • 控制器的选举
    • 故障恢复
  • 优雅关闭
  • 分区leader的选举

概述

在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controler),它负责管理整个集群中所有分区和副本的状态。当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。当使用kafka-topics.sh脚本为某个topic增加分区数量时,同样还是由控制器负责分区的重新分配

这里主要讲控制器的功能与实现,优雅关闭部分会简单概括。

控制器的选举与故障恢复

控制器的选举

Kafka中的控制器选举工作依赖于ZooKeeper,成功竞选为控制器的broker会在ZooKeeper中创建/controller这个临时(EPHEMERAL)节点,此临时节点的内容参考如下:
(version":1,brokerid":0,“timestamp":”1529210278988”)
其中version在目前版本中固定为1,brokeria表示成为控制器的broker的ia编号,timestamp 表示竞选成为控制器时的时间戳。

在任意时刻,集群中有且仅有一个控制器。每个broker启动的时候会去尝试读取/controller节点的brokeria的值,如果读取到brokerid的值不为-1,则表示已经有其他broker节点成功竞选为控制器,所以当前broker就会放弃竞选:如果ZooKeeper中不存在/controller,或者这个节点中的数据异常,那么就会尝试去创建/controller节点。当前broker去创建节点的时候,也有可能其他broker同时去尝试创建这个节点,只有创建成功的那个broker才会成为控制器,而创建失败的broker竞选失败。每个broker都会在内存中保存当前控制器的brokerid值,这个值可以标识为activeControllerid。

ZooKeeper中还有一个与控制器有关的/controller_epoch节点,这个节点是持久(PERSISTENT)节点,节点中存放的是一个整型的controller_epoch值。controller_epoch用于记录控制器发生变更的次数,即记录当前的控制器是第几代控制器,我们也可以称之为“控制器的纪元”

controller_epch的初始值为1,即集群中第一个控制器的纪元为1,当控制器发生变更时,每选出一个新的控制器就将该字段值加1。每个和控制器交互的请求都会携带controller_epoch这个字段,如果请求的controller_epoch值小于内存中的controller_epoch值,则认为这个请求是向已经过期的控制器所发送的请求,那么这个请求会被认定为无效的请求。如果请求的controller_epoch值大于内存中的controller_epoch值,那么说明已经有新的控制器当选了。由此可见,Kafka通过controller_epoch来保证控制器的唯性,进而保证相关操作的一致性。

具备控制器身份的broker需要比其他普通的broker多一份职责,具体细节如下:

  • 监听分区相关的变化。为ZooKeeper中的/admin/reassign partitions节点注 册
    PartitionReassignmentHandler,用来处理分区重分配的动作。为ZooKeeper中的/isr change notification节点注册IsrChangeNotificetionHandler,用来处理ISR集合变更的动作。为ZooKeeper中中的/admin/preferred-replica-election节点添加
    PreferredReplicaElectionHandler,用来处理优先副本的选举动作

  • 监听主题相关的变化。为ZooKeeper中的/brokers/topics节点添加
    TopicChangeHandler,用来处理主题增减的变化;为ZooKeeper中的/admin/ delete
    topics节点添加TopicDeletionHandler,月用来处理删除主题的动作。

  • 监听broker相关的变化。为ZooKeeper中的/brokers/ids节点添加BrokerChangeHandler,用来处理broker增减的变化。

  • 从ZooKeeper中读取获取当前所有与主题、分区及broker有关的信息并进行相应的管理。对所有主题对应的ZooKeeper中的/brokers/topics/节点添加PartitionModificationsHandler,用来监听主题中的分区分配变化

  • 启动并管理分区状态机和副本状态机

  • 更新集群的元数据信息

  • 如果参数auto.leader.rebalance.enable设置为true,贝则还会开启一个名为
    “auto-leader-rebalance-task”的定时任务来负责维护分区的优先副本的均衡

控制器在选举成功之后会读取ZooKeeper中各个节点的数据来初始化上下文信息(ControllerContext),并且需要管理这些上下文信息。比如为某个主题增加了若干分区,控制器在负责创建这些分区的同时要更新上下文信息,并且需要将这些变更信息同步到其他普通的broker节点中。不管是监听器触发的事件,还是定时任务触发的事件,或者是其他事件都会读取或更新控制器中的上下文信息,那么这样就会涉及多线程间的同步。如果单纯使用锁机制来实现,那么整体的性能会大打折扣。针对这一现象,Kafka的控制器使用单线程基于事件队列的模型,将每个事件都做一层封装,然后按照事件发生的先后顺序暂存到LinkedBlockingQueue中,最后使用一个专用的线程(ControllerEventThread)按照FIFO(FirstInputFirstOutput,先入先出)的原则顺序处理各个事件,这样不需要锁机制就可以在多线程间维护线程安全,具体可以参考下图。
在这里插入图片描述

在Kafka的早期版本中,并没有采用KafkaController这样一个概念来对分区和副本的状态进行管理,而是依赖于ZooKeeper,每个broker都会在ZooKeeper上为分区和副本注册大量的监听器(Watcher)。当分区或副本状态变化时,会唤醒很多不必要的监听器,这种严重依赖

ZooKeeper的设计会有脑裂羊群效应,以及造成ZooKeeper过载的隐患(旧版的消费者客户端存在同样的问题)。在目前的新版本的设计中,只有KafkaController在ZooKeeper上注册相应的监听器,其他的broker极少需要再监听ZooKeeper中的数据变化,这样省去了很多不必要的麻烦。不过每个broker还是会对/controller节点添加监听器,以此来监听此节点的数据变化(ControllerChangeHandler)

故障恢复

当/controller节点的数据发生变化时,每个broker都会更新自身内存中保存的activeControllerlds如果broker在数据变更前是控制器,在数据变更后自身的brokerid值与新的 activeControllerId值不一致,那么就需要“退位”,关闭相应的资源,比如关闭状态机、注销相应的监听器等。有可能控制器由于异常而下线,造成/controller这个临时节点被自动删除;也有可能是其他原因将此节点删除了。

当/controller节点被删除时,每个broker都会进行选举,如果broker在节点被删除前是控制器,那么在选举前还需要有一个“退位”的动作。如果有特殊需要,则可以手动删除/controller节点来触发新一轮的选举。当然关闭控制器所对应的broker,以及手动向/controller节点写入新的brokerid的所对应的数据,同样可以触发新一轮的选举。

优雅关闭

Kafka自身提供了一个脚本工具,就是存放在其bin目录下的kafka-server-stop.sh,这个脚本的内容非常简单,具体内容如下:

PIDS=S (ps ax I grep -i kafkal.Kafka’ Igrep java l grep -v grep 1 awk print S1)') if[-Z”SPIDS”】;then echo rNokafkaserver to stop' exit 1 else kill -S TERM SPIDS fi

以上脚本直接执行会存在执行不成功,这是因为与Kafka进程有关的输出信息太长,所以kafka-server-stop.sh脚本在很多情况下并不会奏效。

可以通过修改计算机PAGE_SIZE的大小或者修改脚本内容,这里我们可以直接修改kafka-server-storsh脚本的内容,将其中的第一行命令修改如下:
PIDS=S(ps axIgrep -i 'kafka’i grep javalgrep-v greplawkitprint Si}'
即把“.Kafka”去掉,这样在绝大多数情况下是可以奏效的。如果有极端情况,即使这样也不能关闭,那么只需要按照以下两个步骤就可以优雅地关闭Kafka的服务进程:
(1)获取Kafka的服务进程号PIDS。可以使用Java中的jps命令或使用Linux系统中的ps命令来查看。
(2)使用kill-STERMSPIDS或kill-15 $PIDS的方式来关闭进程,注意千万不要使用kill-9的方式。

为什么这样关闭的方式会是优雅的?Kafka服务入口程序中有一个名为“kafka-shutdown-hock”的关闭钩子,待Kafka进程捕获终止信号的时候会执行这个关闭钩子中的内容,其中除了正常关闭一些必要的资源,还会执行一个控制关闭C ControlledShutdown )的动作。使用ControlledShutdown的方式关闭Kafka有两个优点:一是可以让消息完全同步到磁盘上,在服务下次重新上线时不需要进行日志的恢复操作;二是ControllerShutdown在关闭服务之前,会对其上的leader副本进行证移,这样就可以减少分区的不可用时间。这里更加详细的分析可以查下其他人的博客。

当然这里是通过脚本进行优雅关闭,你也可以自己通过KafkaAdminClient自己写一个优雅关闭的接口去执行。这里详细的设计与实现可以查下其他博客。

分区leader的选举

分区leader副本的选举由控制器负责具体实施。当创建分区(创建主题或增加分区都有创建分区的动作)或分区上线(比如分区中原先的leader副本下线,此时分区需要选举一个新的leader上线来对外提供服务)的时候都需要执行leader的选举动作,对应的选举策略为OfflinePartitionLeaderElectionStrategy。这种策略的基本思路是按照AR集合中副本的顺序查找第一个存活的副本,并且这个副本在ISR集合中。一个分区的AR集合在分配的时候就被指定并且只要不发生重分配的情况,集合内部副本的顺序是保持不变的,而分区的ISR集合中副本的顺序可能会改变。注意这里是根据AR的顺序而不是ISR的顺序进行选举的

如果ISR集合中没有可用的副本,那么此时还要再检查一下所配置的unclean.leader.election.enable参数(默认值为false)。如果这个参数配置为true那么表示允许从非ISR列表中的选举leader,从AR列表中找到第一个存活的副本即为leader。

那么哪些情况下会出现leader选举呢?

  • 当分区进行重分配的时候也需要执行leader的选举动作,对应的选举策略为ReassignPartitionLeaderElectionStrategy。这个选举策略的思路比较简单:从重分配的AR列表中找到第一个存活的副本,且这个副本在日前的ISR列表中。

  • 当发生优先副本的选举时,直接将优先副本设置为leader即可,AR集合中的第一个副本即为优先副本(PreferredReplicaPartitionLeaderElectionStrategy)

  • 还有一种情况会发生leader的选举,当某节点被优雅地关闭(也就是执行 ControlledShutdown)时,位于这个节点上的leader副本都会下线,所以与此对应的分区需要执行leader的选举。与此对应的选举策略(ControlledShutdownPartitionLeaderElectionStrategy)为:从AR列表中找到第一个存活的副本,且这个副本在日前的ISR列表中,与此同时还要确保这个副本不处于正在被关闭的节点上。

相关文章:

kafka服务端之控制器

文章目录 概述控制器的选举与故障恢复控制器的选举故障恢复 优雅关闭分区leader的选举 概述 在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controler),它负责管理整个集群中所有分区和副本的状态。…...

element-plus el-tree-select 修改 value 字段

element-plus el-tree-select 修改 value 字段 &#xff0c;不显示label 需要注意两个地方&#xff1a; <el-tree-select v-model"value" :data"data" multiple :render-after-expand"false" show-checkbox style"width: 240px" …...

SQL最佳实践(笔记)

写在前面&#xff1a; 之前baeldung的Java Weekly &#xfeff;Reviews里面推荐了一篇关于SQL优化的文章&#xff0c;正好最近在学习数据库相关知识&#xff0c;记一些学习笔记 原文地址&#xff1a;SQL Best Practices Every Java Engineer Must Know 1. 使用索引 使用索引…...

在 Java 中执行一个复杂的 SQL 查询(包含多表连接、子查询和聚合函数),如何确保查询的性能?请列举至少三条措施。请简要描述其工作原理?

在Java中执行复杂的SQL查询时&#xff0c;确保查询性能是非常重要的。 以下是三条关键措施&#xff0c;以及它们的详细解释、代码示例和实际开发中的注意事项。 1. 使用索引 索引是提高数据库查询性能的最基本手段之一。通过在查询条件中使用的列上创建索引&#xff0c;可以…...

java将list转成树结构

首先是实体类 public class DwdCusPtlSelectDto {//idprivate String key;//值private String value;//中文名private String title;private List<DwdCusPtlSelectDto> children;private String parentId;public void addChild(DwdCusPtlSelectDto child) {if(this.chil…...

【R语言】数据分析

一、描述性统计量 借助R语言内置的airquality数据集进行简单地演示&#xff1a; 1、集中趋势&#xff1a;均值和中位数 head(airquality) # 求集中趋势 mean(airquality$Ozone, na.rmT) # 求均值 median(airquality$Ozone, na.rmT) # 求中位数 2、众数 众数&#xff08;mod…...

传输层协议 UDP 与 TCP

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 前置复盘&#x1f98b; 传输层&#x1f98b; 再谈端口号&#x1f98b; 端口号范围划分&#x1f98b; 认识知名端口号 (Well-Know Port Number) 二&#xf…...

Linux 调用可执行程序

Linux 调用可执行程序 1. system() 函数1.1 system() 函数的声明1.2 system() 函数的不同场景返回值1.3 system() 函数的代码示例 2. exec() 函数族2.1 exec() 函数族的声明2.2 exec() 函数族执行失败的情况2.3 exec() 函数族的代码示例 3. exec() 与 system() 的区别以及使用注…...

Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用

概览 Jimmer是一个Java/Kotlin双语框架 包含一个革命性的ORM 以此ORM为基础打造了一套综合性方案解决方案&#xff0c;包括 DTO语言 更全面更强大的缓存机制&#xff0c;以及高度自动化的缓存一致性 更强大客户端文档和代码生成能力&#xff0c;包括Jimmer独创的远程异常 …...

剪辑学习整理

文章目录 1. 剪辑介绍 1. 剪辑介绍 剪辑可以干什么&#xff1f;剪辑分为哪些种类&#xff1f; https://www.bilibili.com/video/BV15r421p7aF/?spm_id_from333.337.search-card.all.click&vd_source5534adbd427e3b01c725714cd93961af 学完剪辑之后如何找工作or兼职&#…...

IDEA查看项目依赖包及其版本

一.IDEA将现有项目转换为Maven项目 在IntelliJ IDEA中,将现有项目转换为Maven项目是一个常见的需求,可以通过几种不同的方法来实现。Maven是一个强大的构建工具,它可以帮助自动化项目的构建过程,管理依赖关系,以及其他许多方面。 添加Maven支持 如果你的项目还没有pom.xm…...

centos虚拟机迁移没有ip的问题

故事背景&#xff0c;我们的centos虚拟机本来是好好的&#xff0c;但是拷贝到其他电脑上就不能分配ip&#xff0c;我个人觉得这个vmware他们软件应该搞定这个啊&#xff0c;因为这个问题是每次都会出现的。 网络选桥接 网络启动失败 service network restart Restarting netw…...

Java 大视界 -- Java 大数据在智能供应链中的应用与优化(76)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Java中的继承及相关概念

在 Java 中&#xff0c;继承是一种允许一个类继承另一个类的特性。通过继承&#xff0c;子类可以获取父类的属性和方法&#xff0c;这有助于减少代码冗余并提高代码的可维护性。以下是关于文件内容的相关分析和知识点总结&#xff1a; 一、继承的核心概念 1.继承的语法 Java …...

赛博算命之 ”梅花易数“ 的 “JAVA“ 实现 ——从玄学到科学的探索

hello~朋友们&#xff01;好久不见&#xff01; 今天给大家带来赛博算命第三期——梅花易数的java实现 赛博算命系列文章&#xff1a; 周易六十四卦 掐指一算——小六壬 更多优质文章&#xff1a;个人主页 JAVA系列&#xff1a;JAVA 大佬们互三哦~互三必回&#xff01;&#xf…...

DNS攻击方式有哪些,应该采取哪些应对措施?

在当今数字化时代&#xff0c;网络已成为人们生活和工作不可或缺的一部分。而 DNS&#xff08;域名系统&#xff09;作为互联网的关键基础设施&#xff0c;如同电话簿一般&#xff0c;将人们易于记忆的域名转换为计算机能够识别的 IP 地址&#xff0c;让我们能够轻松访问各类网…...

即梦(Dreamina)技术浅析(六):多模态生成模型

多模态生成模型是即梦(Dreamina)的核心技术之一,旨在结合文本和图像信息,生成更符合用户需求的视觉内容。多模态生成模型通过整合不同类型的数据(如文本和图像),能够实现更丰富、更精准的生成效果。 1. 基本原理 1.1 多模态生成模型概述 多模态生成模型的目标是结合不…...

如何优化爬虫以提高搜索效率

在数据采集和网络爬虫领域&#xff0c;优化爬虫性能是提升数据采集效率的关键。随着网页结构的日益复杂和数据量的不断增长&#xff0c;高效的爬虫能够显著降低运行时间和资源成本。本文将详细介绍如何优化爬虫以提高搜索效率&#xff0c;包括选择合适的工具、优化代码逻辑、使…...

Node.js中http模块(二)

一、http模块 http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer0) 方法&#xff0c;就能方便的把一台普通的电脑&#xff0c;变成一台 Web 服务器&#xff0c;从而对外提供 Web 资源服务。 二、域名和域名服务器 尽管 I…...

android selinux 问题

参考 Android Selinux介绍&#xff0c;如何添加selinux 权限SELinux权限-总结添加Selinux 权限/常见的Selinux 权限问题为何Android普通APP可以执行私有数据中的so文件&#xff0c;而system app却不可以&#xff1f;Android SELinux权限概念和配置说明Selinux中的APP分类Andro…...

递增三元组(蓝桥杯18F)

暴力求解&#xff1a; #include<iostream> using namespace std; int main() {int N;cin >> N;int* A new int[N];int* B new int[N];int* C new int[N];for (int i 0; i < N;i) {cin >> A[i];}for (int i 0; i < N; i) {cin >> B[i];}for…...

计算机毕业设计SparkStreaming+Kafka广告推荐系统 广告预测 广告数据分析可视化 广告爬虫 大数据毕业设计 深度学习 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

FreeCAD创建零件(系列1)

1、新建草图绘制1个矩形 2、画1个半圆弧 3、增加一个约束点 4、标注距离 5、将线段转为辅助线 将图中的线段切换为辅助线,线条颜色之后转为蓝色线。 6、离开草图...

韶音科技:消费电子行业售后服务实现数字化转型,重塑客户服务体系

韶音科技&#xff1a;消费电子行业售后服务实现数字化转型&#xff0c;重塑客户服务体系 在当今这个科技日新月异的时代&#xff0c;企业之间的竞争早已超越了单纯的产品质量比拼&#xff0c;**售后服务成为了衡量消费电子行业各品牌实力与客户满意度的关键一环。**深圳市韶音…...

mes系统对工业数字化转型起到重要作用,它的实际应用有哪些

一、生产计划与调度 在工业数字化转型中&#xff0c;MES 系统能够对生产计划进行高效的管理和调度。通过与企业资源计划&#xff08;ERP&#xff09;系统的集成&#xff0c;MES 可以获取生产订单信息&#xff0c;并根据生产设备的状态、人员安排以及物料供应情况等因素&#x…...

mongodb 使用内存过大分析

os 分析 内存使用 ps aux|head -1;ps aux|grep -v PID|sort -rn -k 4|head -10swap 使用 for i in $(ls /proc | grep "^[0-9]" | awk $0>100); do awk /Swap:/{aa$2}END{print "$i",a/1024"M"} /proc/$i/smaps;done| sort -k2nr | headmo…...

网络安全:挑战、技术与未来发展

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 在数字化时代&#xff0c;网络安全已成为全球关注的焦点。随着互联网的普及和信息技术的高速发展&#xff0c;网络攻击的…...

从零开始玩转Docker:轻松开启容器化之旅

一、什么是 Docker Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。简单来说&#xff0c;Docker 就像是一个超级 “快递箱”&#xff0c…...

Python Pandas(5):Pandas Excel 文件操作

Pandas 提供了丰富的 Excel 文件操作功能&#xff0c;帮助我们方便地读取和写入 .xls 和 .xlsx 文件&#xff0c;支持多表单、索引、列选择等复杂操作&#xff0c;是数据分析中必备的工具。 操作方法说明读取 Excel 文件pd.read_excel()读取 Excel 文件&#xff0c;返回 DataF…...

预算限制下R1推理模型的复制与LLM推理能力提升策略

摘要 在预算有限的情况下&#xff0c;复制R1推理模型并增强大型语言模型&#xff08;LLM&#xff09;的推理能力成为研究热点。本文介绍四种主要构建方法&#xff1a;微调预训练模型、设计轻量级架构、迁移学习及知识蒸馏。每种方法各有优势&#xff0c;适用于不同场景。同时&a…...