Kafka-4.1-工作原理综述

news2024/11/15 3:32:31

1 Kafka工作原理详解

1.1 工作流程

        Kafka集群将 Record 流存储在称为 Topic 的类中,每个记录由⼀个键、⼀个值和⼀个时间戳组成。

        Kafka 中消息是以 Topic 进⾏分类的,⽣产者⽣产消息,消费者消费消息,⾯向的都是同⼀个Topic。Topic 是逻辑上的概念,⽽ Partition 是物理上的概念,每个 Partition 对应于⼀个 log ⽂件,该log ⽂件中存储的就是 Producer ⽣产的数据。Producer ⽣产的数据会不断追加到该 log ⽂件末端,且每条数据都有⾃⼰的 Offset。消费者组中的每个消费者,都会实时记录⾃⼰消费到了哪个 Offset,以便出错恢复时,从上次的位置继续消费。

1.2 存储机制

        由于⽣产者⽣产的消息会不断追加到 log ⽂件末尾,为防⽌ log ⽂件过⼤导致数据定位效率低下,Kafka 采取了分⽚和索引机制。它将每个 Partition 分为多个 Segment,每个 Segment 对应两个⽂件:“.index” 索引⽂件和“.log” 数据⽂件。这种索引思想值得我们学习应用到平时的开发中。

        这些⽂件位于同⼀⽂件下,该⽂件夹的命名规则为:topic 名-分区号。例如,test这个 topic 有三个分区,则其对应的⽂件夹为 test-0,test-1,test-2。

$ ls /tmp/kafka-logs/test-1
00000000000000009014.index
00000000000000009014.log
00000000000000009014.timeindex
leader-epoch-checkpoint

        index 和 log ⽂件以当前 Segment 的第⼀条消息的 Offset 命名。下图为 index ⽂件和 log ⽂件的结构示意图。

        “.index” ⽂件存储⼤量的索引信息,“.log” ⽂件存储⼤量的数据,索引⽂件中的元数据指向对应数据⽂件中 Message 的物理偏移量。

        使用shell命令查看索引:

./kafka-dump-log.sh --files /tmp/kafka-logs/test-1/00000000000000000000.index

1.3 分区机制

分区原因:

  1. ⽅便在集群中扩展,每个 Partition 可以通过调整以适应它所在的机器,⽽⼀个 Topic ⼜可以有多个 Partition 组成,因此可以以 Partition 为单位读写了。
  2. 可以提⾼并发,避免两个分区持久化的时候争夺资源。
  3. 备份的问题。防止一台机器宕机后数据丢失的问题。

        分区原则:我们需要将 Producer 发送的数据封装成⼀个 ProducerRecord 对象。该对象需要指定⼀些参数:

  • topic:string 类型,NotNull。
  • partition:int 类型,可选。
  • timestamp:long 类型,可选。
  • key:string 类型,可选。
  • value:string 类型,可选。
  • headers:array 类型,Nullable。

        指明 Partition 的情况下,直接将给定的 Value 作为 Partition 的值;没有指明 Partition 但有 Key 的情况下,将 Key 的 Hash 值与分区数取余得到 Partition 值;既没有 Partition 又没有 Key 的情况下,第⼀次调⽤时随机⽣成⼀个整数(后⾯每次调⽤都在这个整数上⾃增),将这个值与可⽤的分区数取余,得到 Partition 值,也就是常说的 Round-Robin轮询算法。

1.4 生产者

        Producer⽣产者,是数据的⼊⼝。Producer在写⼊数据的时候永远的找leader,不会直接将数据写⼊follower。下图很好地阐释了生产者的工作流程。这里获取分区信息,是从zookeeper中获取的。生产者不会每个消息都调用一次send(),这样效率太低,默认是数据攒到16K或是超时(如10ms)会send()一次。注意这里发消息是异步操作。

1.5 ack机制

        producer端设置request.required.acks=0;只要请求已发送出去,就算是发送完了,不关心有没有写成功。性能很好,如果是对一些日志进行分析,可以承受丢数据的情况,用这个参数,性能会很好。

  • request.required.acks=1;发送一条消息,当leader partition写入成功以后,才算写入成功。不过这种方式也有丢数据的可能。
  • request.required.acks=-1;需要ISR列表里面,所有副本都写完以后,这条消息才算写入成功。

        设计一个不丢数据的方案:数据不丢失的方案:1)分区副本 >=2 2)acks = -1 3)min.insync.replicas >=2。

        下面给出此时leader出现故障的情况,可以看出,此时数据可能重复。

        解释上面出现的几个名词。Leader维护了⼀个动态的 in-sync replica set(ISR):和 Leader 保持同步的 Follower 集合。当 ISR 集合中的 Follower 完成数据的同步之后,Leader 就会给 Follower 发送 ACK。如果 Follower ⻓时间未向 Leader 同步数据,则该 Follower 将被踢出 ISR 集合,该时间阈值由replica.lag.time.max.ms 参数设定。Leader 发⽣故障后,就会从 ISR 中选举出新的 Leader。

        kafka服务端中min.insync.replicas。 如果我们不设置的话,默认这个值是1。一个leader partition会维护一个ISR列表,这个值就是限制ISR列表里面至少得有几个副本,比如这个值是2,那么当ISR列表里面只有一个副本的时候,往这个分区插入数据的时候会报错。

1.6 消费者

        Consumer 采⽤ Pull(拉取)模式从 Broker 中读取数据。Pull 模式则可以根据 Consumer 的消费能⼒以适当的速率消费消息。Pull 模式不⾜之处是,如果Kafka 没有数据,消费者可能会陷⼊循环中,⼀直返回空数据。因为消费者从 Broker 主动拉取数据,需要维护⼀个⻓轮询,针对这⼀点, Kafka 的消费者在消费数据时会传⼊⼀个时⻓参数 timeout。如果当前没有数据可供消费,Consumer 会等待⼀段时间之后再返回,这段时⻓即为 timeout。

1.6.1 分区分配策略

        ⼀个Consumer Group中有多个Consumer,⼀个Topic有多个Partition。不同组间的消费者是相互独立的,相同组内的消费者才会协作,这就必然会涉及到Partition的分配问题,即确定哪个Partition由哪个Consumer来消费。

        Kafka 有三种分配策略:

  1. RoundRobin
  2. Range,默认为Range
  3. Sticky

        当消费者组内消费者发⽣变化时,会触发分区分配策略(⽅法重新分配),在分配完成前,kafka会暂停对外服务。注意为了尽量确保消息的有序执行,一个分区只能对应一个消费者,这也说明消费者的数量不能超过分区的数量。

1.6.1.1 range方式

        Range ⽅式是按照主题来分的,不会产⽣轮询⽅式的消费混乱问题,但是也有不足。

        注意图文不符,图片是一个例子,文字再给一个例子,以便理解。假设我们有10个分区,3个消费者,排完序的分区将会是0,1,2,3,4,5,6,7,8,9;消费者线程排完序将会是C1-0,C2-0,C3-0。然后将partitions的个数除以消费者线程的总数来决定每个消费者线程消费⼏个分区。如果除不尽,那么前⾯⼏个消费者线程将会多消费⼀个分区。

        在我们的例⼦⾥⾯,我们有10个分区,3个消费者线程, 10/3 = 3,⽽且除不尽,那么消费者线程 C1-0将会多消费⼀个分区:C1-0 将消费 0, 1, 2, 3 分区;C2-0将消费 4,5,6分区;C3-0将消费 7,8,9分区。

        假如我们有11个分区,那么最后分区分配的结果看起来是这样的:

  • C1-0将消费 0,1,2,3分区;
  • C2-0将消费 4,5,6,7分区;
  • C3-0 将消费 8, 9, 10 分区。

        假如我们有2个主题(T1和T2),分别有10个分区,那么最后分区分配的结果看起来是这样的:

  • C1-0 将消费 T1主题的 0, 1, 2, 3 分区以及 T2主题的 0, 1, 2, 3分区
  • C2-0将消费 T1主题的 4,5,6分区以及 T2主题的 4,5,6分区
  • C3-0将消费 T1主题的 7,8,9分区以及 T2主题的 7,8,9分区

        这就可以看出,C1-0 消费者线程⽐其他消费者线程多消费了2个分区,这就是Range strategy的⼀个很明显的弊端。如下图所示,Consumer0、Consumer1 同时订阅了主题 A 和 B,可能造成消息分配不对等问题,当消费者组内订阅的主题越多,分区分配可能越不均衡。

1.6.1.2 RoundRobin

        RoundRobin 轮询⽅式将所有分区作为⼀个整体进⾏ Hash 排序,消费者组内分配分区个数最⼤差别为 1,是按照组来分的,可以解决多个消费者消费数据不均衡的问题。

        轮询分区策略是把所有partition和所有consumer线程都列出来,然后按照hashcode进⾏排序。最后通过轮询算法分配partition给消费线程。如果所有consumer实例的订阅是相同的,那么partition会均匀分布。

        在上面的例⼦⾥⾯,假如按照 hashCode排序完的topic-partitions组依次为T1-5,T1-3,T1-0,T1-8,T1-2,T1-1,T1-4,T1-7,T1-6,T1-9,我们的消费者线程排序为C1-0,C1-1,C2-0,C2-1,最后分区分配的结果为:

  • C1-0将消费 T1-5,T1-2,T1-6分区;
  • C1-1将消费 T1-3,T1-1,T1-9分区;
  • C2-0将消费 T1-0,T1-4分区;
  • C2-1将消费 T1-8,T1-7分区。

        图文不符。

        但是,当消费者组内订阅不同主题时,可能造成消费混乱,如下图所示,Consumer0 订阅主题A,Consumer1 订阅主题 B。

        将 A、B 主题的分区排序后分配给消费者组,TopicB 分区中的数据可能分配到 Consumer0 中。

        因此,使⽤轮询分区策略必须满⾜两个条件:

  1. 每个主题的消费者实例具有相同数量的流;
  2. 每个消费者订阅的主题必须是相同的。

        注意,其实对于生产者而言,可以自定义push但哪个分区中,也可以使用如hash等方法。

1.6.1.3 Sticky

        前两种rebalance方式需要重新映射,代价较大,特别是由于rebalance期间会暂停服务,这就要求该过程尽量短。Sticky在没有rebalance时采用轮询方式,发生rebalance时,尽量保持原映射关系,只是改变与宕机相关的映射,依然采用轮询的方式。

1.6.2 可靠性保证

        在前面ack保障消息到了broker之后,消费者也需要有⼀定的保证,因为消费者也可能出现某些问题导致消息没有消费到。

        这里介绍一下偏移量。每个consumer内存里数据结构保存对每个topic的每个分区的消费offset,定期会提交offset,0.9版本以后,提交offset发送给kafka内部额外生成的一个topic:__consumer_offsets,提交过去的时候, key是group.id+topic+分区号,value就是当前offset的值,每隔一段时间,kafka内部会对这个topic进行compact(合并),也就是每个group.id+topic+分区号就保留最新数据。

        这里引入enable.auto.commit,默认为true,也就是⾃动提交offset,⾃动提交是批量执⾏的,有⼀个时间窗⼝,这种⽅式会带来重复提交或者消息丢失的问题,所以对于⾼可靠性要求的程序,要使⽤⼿动提交。对于⾼可靠要求的应⽤来说,宁愿重复消费也不应该因为消费异常⽽导致消息丢失。当然,我们也可以使用策略来避免消息的重复消费与丢失,比如使用事务,将offset与消息执行放在同一数据库中。

        最后再简单介绍一个应用。kafka可以用在分布式延时队列中。创建一个额外的主题和一个定时进程,检测这个主题中是否有消息过期,过期后放在常规的消息队列中,消费者从这个常规的队列中获取消息来消费。

1.7 Kafka配额限速机制(Quotas)

        生产者和消费者以极高的速度生产/消费大量数据或产生请求,从而占用broker上的全部资源,造成网络IO饱和。有了配额(Quotas)就可以避免这些问题。Kafka支持配额管理,从而可以对Producer和Consumer的produce&fetch操作进行流量限制,防止个别业务压爆服务器。

  • 配额限速
    • 可以限制Producer、Consumer的速率
    • 防止Kafka的速度过快,占用整个服务器(broker)的所有IO资源

1.7.1 限制producer端速率

        为所有client id设置默认值,以下为所有producer程序设置其TPS不超过1MB/s,即1048576‬/s,命令如下:

bin/kafka-configs.sh 
  --zookeeper bigdata-pro-m07:2181 
  --alter 
  --add-config 'producer_byte_rate=1048576' 
  --entity-type clients 
  --entity-default

        运行基准测试,观察生产消息的速率

bin/kafka-producer-perf-test.sh 
  --topic test 
  --num-records 500000 
  --throughput -1 
  --record-size 1000 
  --producer-props bootstrap.servers=bigdata-pro-m07:9092,bigdata-pro-m08:9092,bigdata-pro-m09:9092 acks=1

结果:

50000 records sent, 1108.156028 records/sec (1.06 MB/sec)

1.7.2 限制consumer端速率

        对consumer限速与producer类似,只不过参数名不一样。

        为指定的topic进行限速,以下为所有consumer程序设置topic速率不超过1MB/s,即1048576/s。命令如下:

bin/kafka-configs.sh 
  --zookeeper bigdata-pro-m07:2181 
  --alter 
  --add-config 'consumer_byte_rate=1048576' 
  --entity-type clients 
  --entity-default

运行基准测试:

bin/kafka-consumer-perf-test.sh 
  --broker-list bigdata-pro-m07:9092,bigdata-pro-m08:9092,bigdata-pro-m09:9092 
  --topic test 
  --fetch-size 1048576 
  --messages 500000

结果为:

MB.sec:1.0743

1.7.3 取消Kafka的Quota配置

        使用以下命令,删除Kafka的Quota配置

bin/kafka-configs.sh 
  --zookeeper bigdata-pro-m07:2181 
  --alter 
  --delete-config 'producer_byte_rate' 
  --entity-type clients 
  --entity-default bin/kafka-configs.sh 
  --zookeeper bigdata-pro-m07:2181 
  --alter 
  --delete-config 'consumer_byte_rate' 
  --entity-type clients 
  --entity-default

参考链接

Kafka超全精讲(一)_kafka精析_<一蓑烟雨任平生>的博客-CSDN博客

Kafka超全精讲(二)_kafka 函数库-CSDN博客

【精选】Kafka基本原理详解_昙花逐月的博客-CSDN博客

这是最详细的Kafka应用教程了 - 掘金

Kafka : Kafka入门教程和JAVA客户端使用-CSDN博客

简易教程 | Kafka从搭建到使用 - 知乎

【精选】kafka简介_唏噗的博客-CSDN博客

Kafka 架构及基本原理简析

kafka详解(一)--kafka是什么及怎么用

再过半小时,你就能明白kafka的工作原理了

Kafka 设计与原理详解

Kafka【入门】就这一篇! - 知乎

kafka简介_kafka_唏噗-华为云开发者联盟

kafka详解

kafka 学习 非常详细的经典教程-CSDN博客

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

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

相关文章

1964实验室

不知道为什么&#xff0c;我总对51单片机情有独钟&#xff0c;可能因为是启蒙的技术是从51单片机开始的&#xff0c;至于后面我看到了很多更加便宜的、更加牛逼的芯片出来之后&#xff0c;我依然觉得如果是初学者还是要从51单片机开始。 还记得大学时候&#xff0c;我们老师为了…

EMQX vs Mosquitto | MQTT Broker 对比

物联网开发者需要为自己的物联网项目选择合适的 MQTT 消息产品或服务&#xff0c;从而构建可靠高效的基础数据层&#xff0c;保障上层物联网业务。目前市面上有很多开源的 MQTT 产品&#xff0c;在性能功能等方面各有优点。本文将选取目前最为流行的两个开源 MQTT Broker&#…

【从入门到起飞】JavaSE—IO流(2)字符输入流字符输出流

&#x1f38a;专栏【JavaSE】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f33a;字符输入流&#x1f384;空参read方法&#x1f6f8;分…

SVG图片在HTML页面中的四种加载方法

HTML专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简…

OpenAI前CEO萨姆·阿尔特曼可能重返CEO职位;用LoRA微调LLM的实用技巧

&#x1f989; AI新闻 &#x1f680; OpenAI前CEO萨姆阿尔特曼可能重返CEO职位 摘要&#xff1a;据报道&#xff0c;OpenAI前CEO萨姆阿尔特曼有望重新担任CEO职位&#xff0c;并对公司董事会进行重大改变。微软等投资人正努力恢复阿尔特曼的职位&#xff0c;尽管董事会仍然是…

nginx静态网站部署

Nginx是一个HTTP的web服务器&#xff0c;可以将服务器上的静态文件&#xff08;如HTML、图片等&#xff09;通过HTTP协议返回给浏览器客户端 案例&#xff1a;将ace-master这个静态网站部署到Nginx服务器上 通过Xftp将ace-master到linux服务器/opt/static目录下&#xff0c;为…

Vue2基础-Vue对象进阶介绍1

文章目录 一、绑定样式绑定class样式绑定style样式总结 二、渲染条件渲染列表渲染语法key详解 三、Vue检测数据原理问题解决 四、收集表单数据五、过滤器定义语法: 六、内置指令回顾v-text指令:v-htmlcookie问题 v-clock指令v-oncev-pre 一、绑定样式 绑定class样式 <!-- …

什么是媒体见证?媒体宣传有哪些好处?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 一&#xff0c;什么是媒体见证&#xff1f; 媒体见证是指企业举办活动&#xff0c;发布会&#xff0c;邀请媒体现场采访的一种宣传方式&#xff0c;媒体到场后&#xff0c;对其进行记录…

108.firefly-sdk下生成recovery.img

本文主要讲的是如何用命令生成recovery.img sdk本身可以自己生成recovery.img&#xff0c;在sdk的目录下&#xff0c;直接运行build.sh recovery&#xff0c;就可以生成了。 本文一则是想研究一下生成的过程&#xff0c;二则主要的就是要能够自己掌控&#xff0c;能够灵活编译出…

软通动力赋能触觉智能打造嵌入式鸿蒙原生系统应用标杆

11月16日&#xff0c;由华为主办的生态伙伴赋能闭门交流会在鸿蒙之城深圳成功举办&#xff0c;触觉智能及众多企业伙伴、华为公司技术及运营专家与开发者朋友们&#xff0c;共同探讨鸿蒙原生应用和元服务带来纯国产化的创新应用变革。会议中&#xff0c;软通动力与深圳触觉智能…

redis五大常见数据结构的操作命令(string, hash, list, set和zset)

string redis的string&#xff0c;直接按照二进制&#xff08;不做任何的转换&#xff0c;存的是什么取出来的依旧是什么&#xff09;的方式存储。所以string不仅仅可以存储文本数据&#xff0c;还可以存储整数&#xff0c;JSON&#xff0c;xml甚至音视频。但是string的大小最…

智达方通EPM,解决企业经营分析和管理难题

随着我国企业的不断发展&#xff0c;其战略目标也不断壮大&#xff0c;在企业经营活动和战略执行方面遇到的挑战随之增多&#xff0c;面临着业务、财务和企业目标不对等&#xff0c;工作执行力度不够、流程难跟踪&#xff0c;相关数据无法共享、信息闭塞等痛点。在此现状下&…

振弦式渗压计的安装方式及注意事项

振弦式渗压计的安装方式及注意事项 振弦式渗压计是一种常用的测量土壤水位的仪器&#xff0c;可以用于监测地下水位、土壤含水量、岩层渗透系数等参数。其原理是依靠振弦的共振频率变化来测量介质中的压力变化。 安装方式&#xff1a; 1.适当选取安装点&#xff1a;振弦式渗压…

STM32存储左右互搏 SPI总线FATS文件读写FLASH W25QXX

STM32存储左右互搏 SPI总线FATS文件读写FLASH W25QXX FLASH是常用的一种非易失存储单元&#xff0c;W25QXX系列Flash有不同容量的型号&#xff0c;如W25Q64的容量为64Mbit&#xff0c;也就是8MByte。这里介绍STM32CUBEIDE开发平台HAL库实现FATS文件操作W25Q各型号FLASH的例程。…

C++ 十进制与十六进制转换

文章作者&#xff1a;里海 来源网站&#xff1a;里海C\C专栏 十进制与十六进制转换 #include <iostream> #include <string> using namespace std;//十进制整数转十六进制字符串 string DecimalToHex(long long decimal) {string hex "";while (de…

buildadmin+tp8表格操作(3)----表头上方按钮绑定事件处理,实现功能(选中或取消指定行)

在buildAdmin的表格中&#xff0c;通过按钮来选中和取消某一行 这种情况&#xff0c;只适合表格行的单选 在elementplus是这样说的 我们所使用的就是这个方法 看一下buildAdmin中的用法 highlight-current-row 是element-plus 中表格的属性 因为 buildadmin 中的table是对 el…

ModuleNotFoundError: No module named ‘pycocotools‘

cuda 12.1 pytorch 2.0.1 python 3.11 运行代码&#xff0c;报该错误&#xff0c;尝试了以下方法解决&#xff1a; 方法一 # step 1: 安装cython pip install Cython# step 2: 安装pycocotools pip install githttps://github.com/philferriere/cocoapi.git#eggpycocotools…

商业园区的万能管理法,还怪高级的咧!

随着社会的不断发展和科技的飞速进步&#xff0c;视频监控技术已经成为维护安全、提高效率以及实现智能化管理的关键工具。 在这个信息时代&#xff0c;人们对于安全和管理的需求不断提升&#xff0c;而视频监控系统作为一种强大而灵活的解决方案&#xff0c;正日益受到各行各业…

性格急躁怎么办?如何改变急躁的性格?

性格急躁很多人可能都有&#xff0c;有的人只是有过&#xff0c;而有些人持续的有&#xff0c;而且越来越频繁&#xff0c;要说偶尔出现性格急躁也算不上什么大问题&#xff0c;可是当急躁成了一种人格特征&#xff0c;或者说急躁是在一段时间内持续的&#xff0c;那么这问题就…

【漏洞复现】浙大恩特CRM大客户系统sql注入0day(三)

漏洞描述 杭州恩软信息技术有限公司(浙大恩特)提供外贸管理软件、外贸客户管理软件等外贸软件,是一家专注于外贸客户资源管理及订单管理产品及服务的综合性公司。 浙大恩特客户资源管理系统中的T0140_editAction.entweb接口存在SQL注入漏洞,攻击者可通过此漏洞获取企业数…