Kafka-设计原理

news2024/9/19 21:02:23
  • Controller
  • Leader - Partition
  • Rebalance
  • 消息发布机制
  • HW与LEO
  • 日志分段

Controller

  • Kafka核心总控制器Controller:在Kafka集群中会有一个或者多个broker,其中有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态
    • 当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本
    • 当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息
    • 当使用kafka-topics.sh脚本为某个topic增加分区数量时,同样还是由控制器负责让新分区被其他节点感知到
  • Controller选举机制
    • zookeeper临时节点的创建来选举controller:在kafka集群启动的时候,会自动选举一台broker作为controller来管理整个集群,选举的过程是集群中每个broker都会尝试在zookeeper上创建一个 /controller 临时节点,zookeeper会保证有且仅有一个broker能创建成功,这个broker就会成为集群的总控器controller
    • controller重新选举:当这个controller角色的broker宕机了,此时zookeeper临时节点会消失,集群里其他broker会一直监听这个临时节点,发现临时节点消失了,就竞争再次创建临时节点,就是我们上面说的选举机制,zookeeper又会保证有一个broker成为新的controller
  • 具备控制器身份的broker需要比其他普通的broker多一份职责,具体细节如下
    • 监听broker相关的变化。为Zookeeper中的/brokers/ids/节点添加BrokerChangeListener,用来处理broker增减的变化
    • 监听topic相关的变化。为Zookeeper中的/brokers/topics节点添加TopicChangeListener,用来处理topic增减的变化;为Zookeeper中的/admin/delete_topics节点添加TopicDeletionListener,用来处理删除topic的动作
    • 从Zookeeper中读取获取当前所有与topic、partition以及broker有关的信息并进行相应的管理。对于所有topic所对应的Zookeeper中的/brokers/topics/[topic]节点添加PartitionModificationsListener,用来监听topic中的分区分配变化
    • 更新集群的元数据信息,同步到其他普通的broker节点中

Leader - Partition

  • Partition副本选举Leader机制
    • controller感知到分区leader所在的broker挂了(controller监听了很多zk节点可以感知到broker存活)
    • controller会从ISR列表(参数unclean.leader.election.enable=false的前提下)里挑第一个broker作为leader(第一个broker最先放进ISR列表,可能是同步数据最多的副本)
    • 如果参数unclean.leader.election.enable为true,代表在ISR列表里所有副本都挂了的时候可以在ISR列表以外的副本中选leader,这种设置,可以提高可用性,但是选出的新leader有可能数据少很多
  • 副本进入ISR列表有两个条件
    • 必须能与zookeeper保持会话以及跟leader副本网络连通
    • 副本能复制leader上的所有写操作,并且不能落后太多
      • 与leader副本同步滞后的副本,是由 replica.lag.time.max.ms 配置决定的,超过这个时间都没有跟leader同步过的一次的副本会被移出ISR列表
  • 消费者消费消息的offset记录机制
    • 每个consumer会定期将自己消费分区的offset提交给kafka内部topic:__consumer_offsets
      • 提交过去的时候,key是consumerGroupId+topic+分区号,value就是当前offset的值
      • kafka会定期清理topic里的消息,最后就保留最新的那条数据
    • 因为__consumer_offsets可能会接收高并发的请求,kafka默认给其分配50个分区(可以通过offsets.topic.num.partitions设置),这样可以通过加机器的方式抗大并发

Rebalance

  • Rebalance分区分配策略(partition.assignment.strategy):range(默认)、round-robin、sticky
    • range:按照分区序号排序,比如分区0~3给一个consumer,分区4~6给一个consumer,分区7~9给一个consumer
    • round-robin:轮询分配,比如分区0、3、6、9给一个consumer,分区1、4、7给一个consumer,分区2、5、8给一个consumer
    • sticky:与round-robin类似,但是在rebalance的时候,需要保证如下两个原则(当两者发生冲突时,第一个目标优先于第二个目标)
      • 分区的分配要尽可能均匀
      • 分区的分配尽可能与上次分配的保持相同
  • Rebalance机制:如果消费组里的消费者数量有变化或消费的分区数有变化,kafka会重新分配消费者消费分区的关系。比如consumer group中某个消费者挂了,此时会自动把分配给他的分区交给其他的消费者,如果他又重启了,那么又会把一些分区重新交还给他
    • rebalance只针对subscribe这种不指定分区消费的情况,如果通过assign这种消费方式指定了分区,kafka不会进行rebanlance
    • rebalance过程中,消费者无法从kafka消费消息,这对kafka的TPS会有影响,如果kafka集群内节点较多,比如数百个,那重平衡可能会耗时极多,所以应尽量避免在系统高峰期的重平衡发生
  • 触发消费者rebalance
    • 消费组里的consumer增加或减少了
    • 动态给topic增加了分区
    • 消费组订阅了更多的topic
  • Rebalance过程:当有消费者加入消费组时,消费者、消费组及组协调器之间会经历以下几个阶段
    1. 选择组协调器(GroupCoordinator):每个consumer group都会选择一个broker作为自己的组协调器coordinator,负责监控这个消费组里的所有消费者的心跳,以及判断是否宕机,然后开启消费者rebalance
      • consumer group中的每个consumer启动时会向kafka集群中的某个节点发送FindCoordinatorRequest请求来查找对应的组协调器GroupCoordinator,并跟其建立网络连接
      • 组协调器选择方式:通过如下公式可以选出consumer消费的offset要提交到__consumer_offsets的哪个分区,这个分区leader对应的broker就是这个consumer group的coordinator。说白了,leader分区所在的节点就是GroupCoordinator
    2. 加入消费组(JOIN GROUP),选择消费组协调器
      1. 在成功找到消费组所对应的 GroupCoordinator 之后就进入加入消费组的阶段,在此阶段的消费者会向 GroupCoordinator 发送 JoinGroupRequest 请求,并处理响应。
      2. 然后GroupCoordinator 从一个consumer group中选择第一个加入group(第一个与GroupCoordinator连接的consumer)的consumer作为leader(消费组协调器)
      3. 把consumer group情况发送给这个leader,接着这个leader会负责制定分区方案
    3. SYNC GROUP
      1. consumer leader通过给GroupCoordinator发送SyncGroupRequest
      2. 接着GroupCoordinator就把分区方案下发给各个consumer,他们会根据指定分区的leader broker进行网络连接以及消息消费

在这里插入图片描述


消息发布机制

  • producer发布消息机制
    • 写入方式:producer 采用 push 模式将消息发布到 broker,每条消息都被 append 到 patition 中,属于顺序写磁盘(顺序写磁盘效率比随机写内存要高,保障 kafka 吞吐率)
    • 消息路由:producer 发送消息到 broker 时,会根据分区算法选择将其存储到哪一个 partition
      1. 指定了 patition,则直接使用
      2. 指定 patition 但指定 key,通过对 key 的 value 进行 hash 选出一个 patition
      3. patition 和 key 都未指定,使用轮询选出一个 patition
    • 写入流程
      1. producer 先从 zookeeper 的 “/brokers/…/state” 节点找到该 partition 的 leader
      2. producer 将消息发送给该 leader
      3. leader 将消息写入本地 log
      4. followers 从 leader pull 消息,写入本地 log 后向leader 发送 ACK
      5. leader 收到所有 ISR 中的 replica 的 ACK 后,增加 HW(high watermark,最后 commit 的 offset) 并向 producer 发送 ACK

在这里插入图片描述


HW与LEO

  • HW:HW俗称高水位,HighWatermark的缩写,取一个partition对应的ISR中最小的LEO(log-end-offset)作为HW,consumer最多只能消费到HW所在的位置。

    • 每个replica都有HW,leader和follower各自负责更新自己的HW的状态。
    • 对于leader新写入的消息,consumer不能立刻消费,leader会等待该消息被所有ISR中的replicas同步后更新HW,消息才能被consumer消费。
    • 这样就保证了如果leader所在的broker失效,该消息仍然可以从新选举的leader中获取。
    • 对于来自内部broker的读取请求,没有HW的限制
  • 当producer生产消息至broker后,ISR以及HW和LEO的流转过程

    • 在这里插入图片描述
  • Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制,很好的均衡了确保数据不丢失以及吞吐率

  • 当 acks=1

    • 在这里插入图片描述

日志分段

  • 日志分段存储:Kafka 一个分区的消息数据对应存储在一个文件夹下,以topic名称+分区号命名,消息在分区内是分段(segment)存储,每个段的消息都存储在不一样的log文件里,这种特性方便old segment file快速被删除,kafka规定了一个段位的 log 文件最大为 1G,做这个限制目的是为了方便把 log 文件加载到内存去操作
    • 00000000000000000000.index:部分消息的offset索引文件,kafka每次往分区发4K(可配置)消息就会记录一条当前消息的offset到index文件
      • 如果要定位消息的offset会先在这个文件里快速定位,再去log文件里找具体消息
    • 00000000000000000000.log:消息存储文件,主要存offset和消息体
    • 00000000000000000000.timeindex:息的发送时间索引文件,kafka每次往分区发4K(可配置)消息就会记录一条当前消息的发送时间戳与对应的offset到timeindex文件
      • 如果需要按照时间来定位消息的offset,会先在这个文件里查找
    • 文件名00000000000000000000就是表了这个日志段文件里包含的起始 Offset
  • log.segment.bytes:限定了每个日志段文件的大小,最大就是 1GB
    • 一个日志段文件满了,就自动开一个新的日志段文件来写入,避免单个文件过大,影响文件的读写性能,这个过程叫做log rolling,正在被写入的那个日志段文件,叫做 active log segment。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2103567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hyper-v 安装 centOS

一.Hyper-v安装 1. 右键此电脑,点击属性,查看自己的window版本 如果是专业版或者企业版,则无需额外操作,如果是家庭版,则需要先运行一个脚本来进行安装。 参考这一篇:window10 家庭版如何开启Hyper-v-CSDN…

FPGA开发:初识FPGA

FPGA是什么? FPGA的全称是现场可编程门阵列(Field Programmable Gate Array),一种以数字电路为主的集成芯片,属于可编程逻辑器件PLD的一种。简单来说,就是能用代码编程,直接修改FPGA芯片中数字…

OceanBase 关于 place_group_by HINT的使用

PLACE_GROUP_BY Hint 表示在多表关联时,如果满足单表查询后直接进行group by 的情形下,在跟其它表进行关联统计,减少表内部联接。 NO_PLACE_GROUP_BY Hint 表示在多表关联时,在关联后才对结果进行group by。 使用place_group_by …

二百五十九、Java——采集Kafka数据,解析成一条条数据,写入另一Kafka中(一般JSON)

一、目的 由于部分数据类型频率为1s,从而数据规模特别大,因此完整的JSON放在Hive中解析起来,尤其是在单机环境下,效率特别慢,无法满足业务需求。 而Flume的拦截器并不能很好的转换数据,因为只能采用Java方…

启动.cmd文件一闪而过,看不到报错信息

在window的环境中,双击.cmd文件,有报错信息,但是一闪而过 例如启动zookeeper时,没有zoo.cfg文件会报错,但是启动一闪而过,你看不到报错信息 有文本工具编辑cmd文件,在最后添加 pause 再次启…

Linux 之 lsblk 【可用块的设备信息】

功能介绍 在 Linux 系统中,“lsblk”(list block devices)命令用于列出所有可用的块设备信息 应用场景 查看存储设备信息:“lsblk” 命令可以帮助你快速了解系统中的存储设备,包括硬盘、固态硬盘、U 盘等。你可以查…

9_4_QTextEdit

QTextEdit //核心属性//获取文本 toPlainText(); toHtml(); toMarkdown(); //输入框为空时的提示功能 placeHolderText(); //只读 readOnly();//定义文本光标 QTextcursor cursorcursor.position(); cursor.selectedText();//核心信号//文本改变 textChanged(); //选中范围 se…

【黑马点评】附近商户

需求 选择商铺类型后,按照距离当前用户所在位置从近到远的顺序,分页展示该类型的所有商铺。 接口: 参数: typeId:商铺类型current:页码x:经度y:纬度 返回值:所有typeId…

LVS 负载均衡集群指南

1. 引言 LVS (Linux Virtual Server) 虚拟服务器,是 Linux 内核中实现的负载均衡技术,以其高性能、高可靠性和高可用性而闻名。LVS 工作在 TCP/IP 协议栈的第四层 (传输层),通过将流量分配到多个后端服务器,提高系统性能、可用性…

硬件工程师笔试面试知识器件篇——电阻

目录 1、电阻 1.1 基础 电阻原理图 阻实物图 1.1.1、定义 1.1.2、工作原理 1.1.3、类型 1.1.4、材料 1.1.5、标记 1.1.6、应用 1.1.7、特性 1.1.8、测量 1.1.9、计算 1.1.10、颜色编码 1.1.11、公差 1.1.12、功率 1.1.13、重要性 1.2、相关问题 1.2.1、电阻…

数组和指针 笔试题(1)

目录 0.复习 1.笔试题1 2.笔试题2 3.笔试题3 4.笔试题4 5.笔试题5 0.复习 在做笔试题之前,我们首先复习一下数组名的理解 数组名的所有情况: 1.&数组名,取出的是整个数组的地址 2.sizeof(数组名)&#x…

LLM常见问题(Attention 优化部分)

1. 传统 Attention 存在哪些问题? 传统的 Attention 机制忽略了源端或目标端句子中词与词之间的依赖关系。传统的 Attention 机制过度依赖 Encoder-Decoder 架构上。传统的 Attention 机制依赖于Decoder的循环解码器,所以依赖于 RNN,LSTM 等循环结构。传…

【Transformer】Tokenization

文章目录 直观理解分词方式词粒度-Word字粒度-Character子词粒度-Subword(目前最常使用) 词表大小的影响参考资料 直观理解 在理解Transformer或者大模型对输入进行tokenize之前,需要理解什么是token? 理工科的兄弟姐妹们应该都…

027集——goto语句用法——C#学习笔记

goto语句可指定代码的跳行运行: 实例如下: 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Security.Policy; using System.Text; using System.Threading.Tasks;namespace ConsoleApp2 { //…

采用基于企业服务总线(ESB)的面向服务架构(SOA)集成方案实现统一管理维护的银行信息系统

目录 案例 【题目】 【问题 1】(7 分) 【问题 2】(12 分) 【问题 3】(6 分) 【答案】 【问题 1】解析 【问题 2】解析 【问题 3】解析 相关推荐 案例 阅读以下关于 Web 系统设计的叙述,在答题纸上回答问题 1 至问题 3。 【题目】 某银行拟将以分行为主体…

是噱头还是低成本新宠?加州大学用视觉追踪实现跨平台的机器手全掌控?

导读: 在当今科技飞速发展的时代,机器人的应用越来越广泛。从工业生产到医疗保健,从物流运输到家庭服务,机器人正在逐渐改变我们的生活方式。而机器人的有效操作和控制,离不开高效的遥操作系统。今天,我们要…

OHIF Viewer (3.9版本最新版) 适配移动端——最后一篇

根据一些调用资料和尝试,OHIF 的底层用的是Cornerstonejs ,这个是基于web端写的,如果说写在微信小程序里,确实有很多报错, 第一个问题就是 npm下载的依赖, 一、运行环境差异 微信小程序的运行环境与传统的 Node.js 环境有很大不同。小程序在微信客户端中运行,有严格的…

传输大咖38 | 如何应对汽车行业内外网文件交换挑战?

在数字化浪潮的推动下,汽车行业正经历着前所未有的变革。随着智能网联汽车的兴起,内外网文件的安全交换成为了一个亟待解决的问题。本文将探讨汽车行业在内外网文件交换中遇到的难题,并介绍镭速如何为这些问题提供有效的解决方案。 跨网文件传…

js封装上传组件 点击拖拽上传

效果图 上传组件代码 <template><div id"appp"><label for"fileInput" class"upload" dragover"fileDragover" drop"fileDrop" v-if"log ! checkLog"><!-- <div class"jia" …

CTFHub技能树-备份文件下载-.DS_Store

目录 方法一&#xff1a;直接访问/.DS_Store文件 方法二&#xff1a;使用Python-dsstore工具解析.Dsstore文件 方法三&#xff1a;直接使用crul访问/./.DS_Store文件 .DS_Store 是 Mac OS 保存文件夹的自定义属性的隐藏文件。通过.DS_Store可以知道这个目录里面所有文件的清单…