kafka控制器,复制与存储小结

【README】

  • 1,本文主要总结kafka复制,存储细节;
  • 2,本文的kafka集群版本是3.0.0, 有3个broker,分别是 centos201, centos202, centos203 对应的brokerid为 1, 2, 3 ;

【1】kafka内部原理

【1.1】broker-消息中心点

1)broker一个独立的kafka服务器节点;也称为发送消息的中心点

  • kafka使用zk维护集群成员关系;
  • 每个broker都有自己的id存储在zk;broker启动时,创建zk节点把自己id注册到zk;

2)zk存储的kafka集群信息的节点列表

# zk存储的kafka集群信息的节点
[zk: localhost:2181(CONNECTED) 1] ls /
[cluster,controller_epoch,controller,brokers,zookeeper,feature,admin,isr_change_notification,consumers,log_dir_event_notification,latest_producer_id_block,config]

查看zk中的 broker id

# 查看kafka brokerid 和 topic
[zk: localhost:2181(CONNECTED) 2] ls /brokers 
[ids, topics, seqid]
[zk: localhost:2181(CONNECTED) 3] ls /brokers/ids
[1, 2, 3]
[zk: localhost:2181(CONNECTED) 4] ls /brokers/topics
[hello04, hello05, hello02, hello03, hello01, hello10, __consumer_offsets]

【1.2】控制器

1)控制器定义:集群里第一个启动的broker通过在zk创建临时节点 /controller 让自己成为控制器;

其他broker也尝试创建 controller 节点,若已存在,则报错;其他 broker 会在控制器节点上创建 zk watch 对象,这样非控制器节点可以收到控制器节点状态变更的通知;(干货——这种方式可以确保一个集群只能有一个控制器存在,防止脑裂问题

2)控制器选举策略:一旦控制器被关闭或与zk断开,其他broker通过watch对象就会收到控制器消失的通知,这些 非控制器broker 会竞争在 zk 上创建 controller节点,谁最先创建成功,谁就是集群控制器; 然后其他broker在控制器节点上创建 zk watch对象;

  • 2.1)每次控制器选举后: 控制器纪元值(时代值)controller_epoch  都会递增;其他broker若收到控制器发出的包含旧 epoch 的消息,就会忽略;

3)控制器实验

step1) 查看 控制器和控制器纪元

[zk: localhost:2181(CONNECTED) 5] get /controller_epoch
6[zk: localhost:2181(CONNECTED) 6] get /controller
{"version":1,"brokerid":1,"timestamp":"1638692039821"}

显然, epoch是6,控制器是broker1;

step2)停止掉 broker1; 

这个时候,broker2,3 会竞争选举为控制器;我们再次查看控制器,发现控制器现在是broker2了;且 epoch自增为7; 

[zk: localhost:2181(CONNECTED) 7] get /controller_epoch
7[zk: localhost:2181(CONNECTED) 8] get /controller      
{"version":1,"brokerid":2,"timestamp":"1638733315396"}

4)控制器作用

  • 控制器负责在broker加入或离开时进行分区首领选举;
  • 控制器使用 epoch 避免脑裂问题

【补充】脑裂指两个节点同时认为自己是集群控制器; 

5)zk的作用

  1. kafka使用zk的临时节点来选举控制器;
  2. zk在broker加入或退出集群时通知控制器;

【1.3】复制

复制功能是kafka架构的核心;在kafka 文档里,kafka把自己描述为 一个分布式的,可分区的,可复制的提交日志服务;(kakfa的日志就是数据或消息);

【1.3.1】副本

1)数据存储

kafka使用主题来组织数据(逻辑);使用分区为单位来读写数据(物理);

为什么说kakfa以分区为单位读写? 是因为我们创建带有分区数和副本数的主题后, kakfa会创建以这个分区命名的文件夹,分区文件夹下存储消息内容,索引文件等;


 2)主题,分区,副本关系

  • 1个主题对应多个分区;
  • 1个分区对应多个副本;
  • 1个副本对应多个分段文件;(分段存储) 

3)副本类型 

  • 3.1)首领副本:每个分区都有一个首领副本,消息读写首先会操作首领副本;
  • 3.2)跟随者副本:首领副本以外的副本;它们不处理读写请求,唯一任务是从首领副本复制消息,与首领保持数据同步;如果首领发生崩溃,其中一个同步的跟随者副本被提升为首领副本;

补充1:跟随者副本在成为不同步副本前的时间是通过 replica.lag.time.max.ms 来配置;

补充2:跟随者从首领副本复制消息时的请求,与消费者从首领副本消费消息时发出的请求是一样的;


【1.4】处理请求

1)broker处理请求过程

  • step1)broker会在监听端口上运行一个 Acceptor线程可以理解为服务器套接字 ServerSocket),这个线程会创建一个连接(类似ServerSocket.accept() 方法),把请求交给 Processor线程(网络线程)去处理;
  • step2)Processor线程从客户端获取请求消息,把它放进请求队列,然后从响应队列获取响应结果并发送给客户端;
  • step3) 在请求被放入请求队列后, IO线程会处理它们,并把处理结果放入 响应队列;

 2)常见请求类型

  • 生产请求:生产者发送的请求,包含要写入的消息;
  • 获取请求:消费者或跟随者副本所在broker需要从首领副本所在broker获取消息而发送的请求;

【注意】

  1. 生产请求和获取请求都必须发送给分区的首领副本,跟随者副本不参与消息读写,仅做备份和支持集群高可用;
  2. kafka客户端要自己负责把生产请求和获取请求发送到正确的broker上;否则broker会返回错误响应;

3)客户端怎么知道请求发送到哪里呢?

3.1)客户端在发送请求前,先发送元数据请求

  • 这种请求的响应结果包括 主题,主题分区,分区副本以及首领副本;

3.2)客户端会缓存这些元数据信息;

  • 获取元数据信息后,会直接往对应的 broker发送请求和获取请求;
  • 当然,客户端需要定时刷新元数据缓存; 刷新时间间隔通过  metadata.max.age.ms 来配置; 


【1.4.1】生产请求

1)生产者acks有3个值;

  • acks=0 ; 生产者在发送消息后,默认发送成功;而不会等待服务器响应;
  • acks=1 ; 只要集群的首领节点收到消息,生产者就会收到发送成功的响应;而不管副本节点是否收到消息;
  • acks=all; 需要集群的首领节点和跟随节点(副本节点)都收到消息后,生产者才会收到发送成功的响应;

2)首领副本所在broker收到生产请求后,会对请求做一些验证:

  • 发送数据的用户是否有写入权限;
  • acks的值是否合法; (只允许出现 0, 1, all);
  • 根据acks的值,进行副本复制策略;

【1.4.2】获取请求

1)首领副本所在broker收到获取请求后,会根据客户端指定的请求偏移量从分区里读取消息;

2)kafka使用 零复制技术 向客户端发送消息,即kafka直接把消息从文件发送到网络通道,而不经过任何中间缓冲区;(干货——这是kakfa与大部分数据库不一样的地方,其他数据库在把数据发送到客户端前,会把数据保存到本地缓存)

  • 零复制技术优点:避免了字节复制,也不需要管理内存缓冲区,从而获取更好性能; 

3)消费者客户端只能读取已经被写入所有同步副本的消息,而不是所有消息

  • 因为还没有被足够多副本复制的消息被认为是不安全的;如果首领副本所在broker发送崩溃,另一副本成为新首领,那这些不安全的消息就会丢失;

4)扩展 ISR, HW高水位

  1. ISR, In-Sync-Replica set, 同步副本集合,即所有与首领副本保持同步的副本集合;
  2. LEO,log end offset,日志末端偏移量 ,即副本写入下一条消息的位移值;
  3. HW高水位,High Watermark, 所有副本最小的LEO

小结: 消费者只能看到已经复制所有副本的消息;

5)在 Kafka 中,高水位的作用主要有 2 个。

  1. 定义消息可见性,即用来标识分区下的哪些消息是可以被消费者消费的。
  2. 帮助 Kafka 完成副本同步。

6)下面这张图展示了多个与高水位相关的 Kafka 术语 。

我们假设这是某个分区 Leader副本的高水位图。

1)首先,请你注意图中的“已提交消息”和“未提交消息”。在分区高水位以下的消息被认为是已提交消息,反之就是未提交消息。消费者只能消费已提交消息,即图中位移小于 8 的所有消息。另外,需要关注的是,位移值等于高水位的消息也属于未提交消息。也就是说,高水位上的消息是不能被消费者消费的

2)图中还有一个日志末端位移的概念,即 Log End Offset,简写是 LEO。
它表示副本写入下一条消息的位移值。注意,数字 15 所在的方框是虚线,这就说明,这个副本当前只有 15 条消息,位移值是从 0 到 14,下一条新消息的位移是 15。显然,介于高水位和 LEO 之间的消息就属于未提交消息。这也从侧面告诉了我们一个重要的事实,那就是:同一个副本对象,其高水位值不会大于 LEO 值。

【高水位小结】高水位和 LEO 是副本对象的两个重要属性

  1. Kafka 所有副本都有对应的高水位和 LEO 值,而不仅仅是 Leader 副本。
  2. Kafka 使用 Leader 副本的高水位来定义所在分区的高水位。

 【1.4.3】其他请求

  • OffsetCommitRequest, 偏移量提交请求;
  • OffsetFetchRequest;
  • ListOffsetsRequest;

【1.5】物理存储

1)kafka的基本存储单元是分区; 分区会在所属broker上的kafka数据根目录下新建名为分区名的文件夹,如 hello04-2(主题为hello04的2号分区文件夹),kafka数据根目录由 server.properties 中的 log.dirs 来指定;

2)主题,分区,副本关系

  • 1个主题对应多个分区;
  • 1个分区对应多个副本;
  • 1个副本对应多个分段文件;(分段存储) 


【1.5.1】分区分配

1)创建指定分区和副本数的topic来做实验

# 创建分区数3副本数2的主题 
kafka-topics.sh --bootstrap-server centos201:9092 
--create --topic hello11 --partitions 3 --replication-factor 2 
# 副本数量必须小于等于broker数量,但分区数没有这个限制;

查看分区详情

[root@centos201 hello04-1]# kafka-topics.sh --bootstrap-server centos201:9092 \ 
--describe --topic hello11
Topic: hello11  TopicId: IliU_BDeS8ycreLufxCMMw PartitionCount: 3       ReplicationFactor: 2    Configs: segment.bytes=1024Topic: hello11 Partition: 0    Leader: 2       Replicas: 2,3   Isr: 2,3Topic: hello11 Partition: 1    Leader: 3       Replicas: 3,1   Isr: 3,1Topic: hello11 Partition: 2    Leader: 1       Replicas: 1,2   Isr: 1,2

查看具体存储数据的文件夹,以broker1为例; 

根据topic详情,我们知道 broker1 存储了topic hello11的1号和2号分区; 且它是2号分区首领所在的broker

进入 broker1的kafka数据根目录,

 

 进入其中一个分区文件夹查看  hello11-1 ,如下:

再查看分区文件夹前,我们先写入10条消息; 指定topic hello11, 1号分区

 for (int i = 0; i < 10; i++) {Future<RecordMetadata> future = producer.send(
new ProducerRecord<String, String>("hello11", 1,"", String.format("[%s] ", order++) + now + " > " + DataFactory.INSTANCE.genOneHundred()));try {System.out.println("[生产者] " + future.get().partition() + "-" + future.get().offset());} catch (Exception e) {e.printStackTrace();}
}

查看分区文件夹下的文件 ;

2) kafka的分段存储

因为在一个大文件里查找和删除消息很耗时;所以把一个分区分成若干片段进行存储;默认情况下,一个片段存储1g数据,为了实验,这里我修改为 1k,可以在 server.properties文件中设置 log.segment.bytes=1024 来实现;

3)kafka的稀疏索引

  • kafka并没有对每条消息建立索引,那样太大了,而是采用稀疏索引(稀疏存储)的方式,即一条索引记录指向一个消息范围;

例如: 索引值 1~100 指向 数据文件1.log中的消息1到消息100的消息范围的起始地址;

refer2 Apache Kafka ;

当消费者指定消费某个offset记录时, kafka集群通过二分查找从索引文件找出包含offset的索引值,通过索引值找到对应数据文件的起始地址,然后从起始地址开始顺序读取对应offset的消息;


【1.5.2】文件格式

1)kafka 使用零复制技术给消费者发送消息,避免了对生产者已经压缩过的消息进行解压和再压缩; 

2)普通消息与压缩消息格式  

 可以看出,多个压缩消息共用同一个消息头,从而减少消息大小;

【References】

  1. kafka权威指南;
  2. Apache Kafka

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

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

相关文章

python开发stm32软件_ADB+Python+STM32 实现 微信跳一跳辅助

说明:安卓手机开启USB调试模式&#xff0c;具体如何开启&#xff0c;百度自己手机即可安装ADB工具安装python2.7步骤&#xff1a;1、安装adb工具下载地址&#xff1a;https://download.csdn.net/download/qq_29769263/10420731下载后解压到便于记忆的地方即可&#xff0c;以解压…

不装mono,你的.NET程序照样可以在Linux上运行

让.NET应用程序在linux上运行&#xff0c;目前通用的做法就是在Linux上安装mono&#xff0c;然后通过”mono your.exe“命令运行这个程序。 这种运行.net程序的办法有两个弱点&#xff0c;一个是需要客户机安装mono&#xff0c;二个是 ”mono xx.exe“ 这种命令行总让人感到有点…

JAVA面试常考系列一

转载自 JAVA面试常考系列一 题目一 什么是Java虚拟机&#xff1f;为什么Java被称为平台无关的编程语言&#xff1f; java虚拟机是一个可以执行字节码文件&#xff08;.class&#xff09;的虚拟机进程。 为什么java与平台无关呢&#xff1f;因为java源程序&#xff08;.java&…

转:运维监控系统-监控项及指标的梳理

转自&#xff1a; 运维监控系统-监控项及指标的梳理_程序员杂谈-CSDN博客_运维监控指标综合监控功能工具 综合监控工具完成对被管对象的集中监控、集中维护和集中管理&#xff0c;被管对象包括网络设备、服务器、PC设备、数据库、中间件、存储、备份、安全设备、应用系统等。工…

圆心角 圆弧上点坐标_数控加工中心CNC的G02/G03圆弧指令的I、J、与R的区别

G02&#xff1a;顺&#xff08;CW&#xff09;圆弧插补G03&#xff1a;逆&#xff08;CCW&#xff09;圆弧插补根据所选择的X、Y平面&#xff0c;指令格式如下两种&#xff1a;G17 G02/G03 X_ Y_ I_ J_ F_;G17 G02/G03 X_ Y_ R_ F_;定义方式&#xff1a;依右手坐标系统&#xf…

AutoMapper 使用实践

一. 使用意图 常常在开发过程中&#xff0c;碰到一个实体上的属性值&#xff0c;要赋值给另外一个相类似实体属性时&#xff0c;且属性有很多的情况。一般不利用工具的话&#xff0c;就要实例化被赋值实体B&#xff0c;然后再将实体A的字段一个个赋值给B的属性&#xff0c;单…

kafka可靠数据传递

【README】 本文阐述了kafka可靠消息传递机制&#xff1b; 本文部分内容总结于《kafka权威指南》&#xff08;一本好书&#xff0c;墙裂推荐&#xff09;&#xff0c;再加上自己的理解&#xff1b; 【1】可靠性保证 1&#xff0c;在讨论可靠性时&#xff0c;一般使用保证这个…

JAVA面试常考系列二

转载自 JAVA面试常考系列二 题目一 解释一下线程和进程 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上…

雨滴桌面时间插件_Win10美化向——如何搭配你的桌面

// 2020-02-11 //桌面这个东西大家肯定不陌生了&#xff0c;很多人的桌面都如下。_______滑动查看更多图片这多重水印是什么鬼&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;还有很多网友呢&#xff0c;也美化了一下自己的桌面。不过呢严格来说&#xff0c;这应…

python画建筑_专题 | Python 绘图入门

我的施工之路Python 绘图入门这是施工系列第18篇&#xff0c;同时也进入到一个新的阶段&#xff1a;Python绘图篇。作为绘图模块的第一篇&#xff0c;与大家一起过过最基本的Python绘图原理。掌握基本的绘图原理很有必要&#xff0c;各个常用绘图库的原理基本都是相通的。所以了…

最新版dotnet-cli下的ASP.NET Core和asp.net mvc【RC2尝鲜】

RC1是http://get.asp.net里面提供的https://docs.asp.net/en/latest/getting-started/index.html&#xff0c;使用旧的ASP.NET Core 1.0。这个版本会使用dnvm&#xff0c;dnu restore和dnx web等&#xff0c;而RC2则不需要&#xff0c;RC2只需要dotnet restore和dotnet run&…

kafka生产者开发方式

【README】 本文记录了 kafka生产者开发方式&#xff1b; 【1】生产者概览 【1.1】kafka发送消息过程 【1.2】创建kafka生产者 1&#xff09;创建kafka生产者&#xff0c; 有3个必选属性&#xff1a; bootstrap.servers&#xff1a; kakfa集群节点地址&#xff1b;key.seri…

JAVA面试常考系列三

转载自 JAVA面试常考系列三 题目一 什么是迭代器(Iterator)&#xff1f; 迭代器&#xff08;iterator&#xff09;是一种对象&#xff0c;它能够用来遍历标准模板库容器中的部分或全部元素&#xff0c;每个迭代器对象代表容器中确定的地址。迭代器提供了一种方法&#xff0c;可…

linux wait函数头文件_手把手教Linux驱动9-等待队列waitq

在上一篇《手把手教Linux驱动8-Linux IO模型》我们已经了解了阻塞、非阻塞、同步和异步等相关概念&#xff0c;本文主要讲解如何通过等待队列实现对进程的阻塞。应用场景&#xff1a;当进程要获取某些资源(例如从网卡读取数据)的时候&#xff0c;但资源并没有准备好(例如网卡还…

HoloLens开发手记-配置开发环境 Install the tools

随着Build 2016开发者大会的结束&#xff0c;HoloLens开发包也正式开放下载。Hololens没有独立的SDK&#xff0c;开发特性被集成到最新的Visual Studio Update 2中。如果你没有HoloLens真机&#xff0c;那么可以安装HoloLens模拟器。 安装清单 注意: 这里为了方便大家顺利下载安…

kafka再均衡监听器测试

【README】 本文使用的kafka是最新的 kafka3.0.0&#xff1b;本文kafka集群有3个节点分别是 centos201, centos202, centos203 &#xff1b; brokerid 分别为 1,2&#xff0c;3&#xff1b;本文主要用于测试 再均衡监听器&#xff1b;当有新消费者加入时&#xff0c;会发生分区…

java面试常考系列四

转载自 java面试常考系列四 题目一 大O符号(big-O notation)的作用是什么&#xff1f;有哪些使用方法&#xff1f; 大O符号描述了当数据结构里面的元素增加的时候&#xff0c;算法的规模或者是性能在最坏的场景下有多么好。大O符号也可用来描述其他的行为&#xff0c;比如&…

用python进行自然语言处理_Python自然语言处理示例:SVM和贝叶斯分类

❝关于自然语言处理(NLP)方面的文章、书籍非常之多&#xff0c;对于自然语言处理的上手&#xff0c;很多人是不知所措的。通过对本文的浏览&#xff0c;您应该能够对自然语言处理会有一个能够完整的有趣的基于Python的对自然语言处理的了解。❞什么是文本分类文本分类是将文本按…

Build 2016,你可能忽视的几个细节

微软公司主办的Build 2016大会尚在进程中&#xff0c;但是两场重量级的主题演讲已经结束。下面列举了我个人非常关注的几个细节&#xff0c;介绍一些背景知识以饲读者。 Bash on Windows背后的历史和未来 微软和IBM二十多年前联合开发NT内核的时候就已经为接驳多种操作系统留下…

JAVA面试常考系列五

转载自 JAVA面试常考系列五 题目一 串行(serial)收集器和吞吐量(throughput)收集器的区别是什么&#xff1f;吞吐量收集器使用并行版本的新生代垃圾收集器&#xff0c;它用于中等规模和大规模数据的应用程序。串行收集器对大多数的小应用(在现代处理器上需要大概100M左右的内存…