八股文学习四(kafka)

news2025/1/4 16:09:22

 一. 消息中间件kafka

(1)基本概念

(2) 生产者

生产者将消息发送到topic中去,同时负责选择将message发送到topic的哪一个partition中。通过round-robin做简单的负载均衡。也可以根据消息中的某一个关键字来进行区分。通常第二种方式使用的更多。

(3)消费者

消费模式

传统的消息传递模式有2种:队列( queue) 和(publish-subscribe)

  • queue模式:多个consumer从服务器中读取数据,消息只会到达一个consumer。
  • publish-subscribe模式:消息会被广播给所有的consumer。

Kafka基于这2种模式提供了一种consumer的抽象概念:consumer group。

  • queue模式:所有的consumer都位于同一个consumer group 下。
  • publish-subscribe模式:所有的consumer都有着自己唯一的consumer group。
消费顺序
  • 一个partition同一个时刻在一个consumer group中只能有一个consumer instance在消费,从而保证消费顺序。
  • consumer group中的consumer instance的数量不能比一个Topic中的partition的数量多,否则,多出来的consumer消费不到消息。
  • Kafka只在partition的范围内保证消息消费的局部顺序性,不能在同一个topic中的多个partition中保证总的消费顺序性。
  • 如果有在总体上保证消费顺序的需求,那么我们可以通过将topic的partition数量设置为1,将consumer group中的consumer instance数量也设置为1,但是这样会影响性能,所以kafka的顺序消费很少用。

(4)rebalance

rebalance就是说如果消费组里的消费者数量有变化或消费的分区数有变化,kafka会重新分配消费者消费分区的关系。比如consumer group中某个消费者挂了,此时会自动把分配给他的分区交给其他的消费者,如果他又重启了,那么又会把一些分区重新交还给他。

如下情况可能会触发消费者rebalance

  • 消费组里的consumer增加或减少了
  • 动态给topic增加了分区
  • 消费组订阅了更多的topic

rebalance过程中,消费者无法从kafka消费消息,这对kafka的TPS会有影响,如果kafka集群内节点较多,比如数百个,那重平衡可能会耗时极多,所以应尽量避免在系统高峰期的重平衡发生。

消费者Rebalance分区分配策略:
主要有三种rebalance的策略:range、round-robin、sticky。
Kafka 提供了消费者客户端参数partition.assignment.strategy 来设置消费者与订阅主题之间的分区分配策略。默认情况为range分配策略。

(5)应用场景

日志收集:一个公司可以用Kafka收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。

消息系统:解耦和生产者和消费者、缓存消息等。

用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。

运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。

(6)高性能原因

  • 磁盘顺序读写:kafka消息不能修改以及不会从文件中间删除保证了磁盘顺序读,kafka的消息写入文件都是追加在文件末尾,不会写入文件中的某个位置(随机写)保证了磁盘顺序写。
  • 数据传输的零拷贝

(7)kafka副本的作用

副本机制(Replication)

又称为备份机制,通常是指在分布式系中在多台机器中存储相同的数据进行备份的机制,副本机制只要有3个好处。

提供数据冗余:即使部分机器出现故障,系统仍然可以提供服务,增加了整体的可用性和数据持久化。提供高伸缩性:支持横向扩展,可以通过增加副本数,来提供读性能。改善数据局部性:允许将数据放入与用户地理位置相近的地方,从而降低系统延时。但是kafka的副本机制只提供了第一个特点,即提供数据冗余的特性。

在kafka中副本是有一个leader节点和多个follower节点组成,leader节点负责接收消息和消费消息,follower既不提供写服务也不提供读服务,仅仅用于同步leader副本的消息。follower副本的唯一作用就是当leader副本出现问题时,通过ZooKeeper 提供的监控功能能够实时感知到,并立即开启新一轮的领导者选举,从追随者副本中选一个作为新的领导者。

所谓的ISR集合,就是指副本中的消息和leader副本的消息是同步的,没有落后太多的,其中集合中,是包含leader副本自身的。

ISR集合的作用主要有两个方面

leader选举范围:当leader部分挂掉后,某个follower副本会被选为新的leader副本,能够被选为leader副本的条件就是需要在ISR集合中,当然这个是可以进行参数配置的,broker有一个参数unclean.leader.election.enable ,用来进行控制是否可以从非ISR集合中的副本选为leader节点。如果设置为true,开启 Unclean 领导者选举可能会造成数据丢失,但好处是,它使得分区 Leader 副本一直存在,不至于停止对外提供服务,因此提升了高可用性。反之,禁止 Unclean 领导者选举的好处在于维护了数据的一致性,避免了消息丢失,但牺牲了高可用性。这个就是CAP原理中,C和A的取舍问题。

生产ack为-1发送写入的数据:生产者发送消息后,消息需要写入ISR集合中全部副本,才算提交成功;ISR集合中,只有leader一个节点,那么这个时候-1就退化为了1。

副本同步机制

在kafka中,follower副本需要定期从leader部分中拉取消息,在进行消息拉取时,主要有两个概念需要弄清楚

高水位(HW):定义消息可见性,即用来标识分区下的哪些消息是可以被消费者消费的:只有在高水位以下的消息才能被消费者进行消费;并且利用次机制来完成kafka副本的消息同步。

日志末端位移(LEO):即Log End Offset,表示消息下一条消息写入的位置,注意此时这条消息是未写入到kafka中的。在kafka中每个副本都有自己的高水位和LEO信息。

高水位更新机制

在kafka中,leader副本所在的broker节点上,会保存所有follower副本的LEO值。在leader副本所在broker节点上的follower副本值,称之为远程副本(Remote Replica),kafka在运行过程中,会不断更新Broker 1 上 Follower 副本的高水位和 LEO 值,同时也会更新 Broker 0 上 Leader 副本的高水位和 LEO 以及所有远程副本的 LEO,但它不会更新远程副本的高水位值。broker0保存远程副本的信息值,就是为了leader副本来确定高水位值;leader副本的HW就是整个分区的HW值。

每个值的更新时机

Broker1上的follower副本会从leader副本拉取消息,写入到本地磁盘后,会更新其LEO的值。Broker0上的leader副本接收到生产者发送的消息,写入到本地磁盘后,会更新其LEO的值。Follower副本从leader副本拉取消失时,会告诉leader副本从哪个位置开始拉取消息。leader副本收到这个消息后,会更新本机上对应的远程副本的LEO值。Follower副本成功更新LEO值后,会比较其LEO值,和Leader副本发过来的HW的值,取两者的最小值来更新自己的HW值。当Leader副本更新完自身LEO值(或者更新了远程副本的LEO值)时,然后比较Leader副本和所有远程部分的LEO值,其最小值作为自己的HW值,并进行更新。副本同步流程解析

在初始状态下,所有值都为0

当生成者给主题发送消息后,leader分区写入消息后,leader的LEO变为1

此时follower过来拉取消息,消息拉取成功,将自身的LEO也更新为1,此时每个副本的HW还是为0,需要在下一次fetchOffset请求时,更新对应的值

当follower再次拉取消息时,follwoer副本请求拉取的值为1,Leader 副本接收到此请求后,更新远程副本 LEO 为 1,然后更新 Leader 高水位为 1。做完这些之后,它会将当前已更新过的高水位值 1 发送给 Follower 副本。Follower 副本接收到以后,也将自己的高水位值更新成 1。

高水位存在的问题:Leader 副本高水位更新和 Follower 副本高水位更新在时间上是存在错配的。这种错配是很多“数据丢失”或“数据不一致”问题的根源。为了防止,这种问题,社区在0.11版本之后,引入了Leader Epoch 概念,来规避因高水位更新错配导致的各种不一致问题。

数据丢失场景分析:因为整个消息同步过程,存在HW同步的一个延迟,当A的HW为1,B的HW为2值,此时A还没同步到B的HW值时,RelicaA发生宕机,A重启后会根据之前的HW值(保存在本地replication-offset-checkpoint中)进行日志截断,这时消息m2就会丢失,刚好此时ReplicaB发送宕机,ReplicaA被选为了Leader节点;由于follower副本的HW不能比Leader的HW值高,节点B在恢复后也会进行日志截取,消息m2就会彻底丢失掉。

Leader Epoch

可以理解为Leader的版本,由两部门组成

Epoch,一个单调递增的版本号,每当发送leader变更时,就会增加,小版本号的 Leader 被认为是过期 Leader,不能再行使 Leader 权力。起始位移(Start Offset),Leader 副本在该 Epoch 值上写入的首条消息的位移。举例说明:假设有两个Leader Epoch,Leader Epoch<0, 0> 和 <1, 120>,第一个Leader Epoch表示版本号为0,Leader 从位移 0 开始保存消息;在写了120条消息后,发生了leader变更,新的leader的版本号为1,起始位移为120。

如何防止数据丢失:此时如果A发生了宕机重启后,并不会马上进行日志截取,而是会向Leader发送一个OffsetsForLeaderEpochRequest请求,那么此时Leader返回的是2,此时该 LEO 值不比它自己的 LEO 值小,而且缓存中也没有保存任何起始位移值 > 2 的 Epoch 条目,因此 A 无需执行任何日志截断操作。

(8)kafka副本对性能的影响

(9)kafka与其他消息队列相比优势

出发点不一样,kafka定位就是处理日志和大数据 在这些业务领域,topic不会太多,延迟问题自然也就没有。

数据存储结构是主要原因,还有就是kafka只支持pull模式。而rocketmq有pull、push两种模式 (虽然这个push模式是假push),push模式延迟肯定是比pull模式延迟低。

push模式是基于pull模式的,本地有个定时线程去pull broker的消息,缓存到本地,然后push到消费线程那边。

rabbit 的push模式 是真的push 所以 延迟最低的就是兔子。 兔子不支持分布式,只支持主从模式 本身设计就是小而美的单机版。cpu消耗比kafka之类低多了。

1.是否支持延时消息

  • RocketMQ支持固定延时等级的延时消息,等级可配置
  • kafka不支持延时消息

2.消息过滤方式不同

  • RocketMQ执行过滤是在Broker端,支持tag过滤及自定义过滤逻辑
  • Kafka不支持Broker端的消息过滤,需要在消费端自定义实现

3.消息失败是否支持重试

  • Kafka不支持重试   (通过另外创建消息重试topic实现重试)
  • RocketMQ支持定时重试,每次重试间隔逐渐增加

4.事务机制不同

两个消息中心的事务机制也有所不同。RocketMq通过二阶段提交和回查机制能够实现分布式场景下的事务:两个系统进行处理同一业务流程交易时,保证生产方处理和发送消息阶段两个动作要么同时成功,要么同时失败。而Kafka则是保证生产者发送多条消息可以封装在一个事务中,形成一个原子操作

kafka & rocket mq对比(【精选】rocketMq和kafka对比_kafka和rocketmq-CSDN博客):

1. 使用场景:Kafka适合日志处理;RocketMQ适合业务处理

2. 性能:Kafka吞吐量更高,单机百万/秒;RocketMQ单机10万/秒。

  因为Kafka一个topic有很多partition,代表很多目录,每个目录下有很多segment,每个代表一个消息文件,而RocketMQ存储消息只有commitLog文件。所以Kafka可以并发写,快于RocketMQ。但同样的,当Topic增加,Kafka分区文件增多,文件刷盘时会竞争磁盘资源,而导致效率降低。

  同时,生产者有一个发送消息的缓存队列,客户端发送后,放入缓存,立刻返回成功。当缓存队列达到阈值,才真正发送给broker,此举合并了多次请求,批量发送&批量压缩,减少网络IO,但增大消息丢失风险

3. 特殊消息:Kafka不支持定时,事务消息等

4. 支持队列数:Kafka超过64个队列(partition)性能下降严重,而RocketMQ最高支持5万个队列

消息队列原理和选型:Kafka、RocketMQ 、RabbitMQ 和 ActiveMQ - 知乎

(10)kafka如何确保不丢失消息

1.生产者环节丢失
生产者环节发送失败导致的丢失,导致的原因可能是网络波动的原因,或是kafka节点故障的原因;

生产者发送消息的方式有两种: 同步 与 异步;
【解决方案】:
采用异步推送消息的方式,因为消息异步推送后,会有一个回调函数,根据回调函数的情况可以对消息进行补发;
此外,还可以设置消息重试次数;

代码如下:

2.Broker存储环节丢失
Broker存储环节,kafka对此有一个发送确认机制acks;
结合考虑kafka集群的情况下;

【解决方案】
acks发送确认机制有三种模式:

默认acks=1,只要集群leader节点,收到消息就响应成功;
acks=all,可以避免在极端情况下,消息在存储环节出现问题,但是要综合考虑其性能[不建议];

该处使用的url网络请求的数据。

刷盘机制分同步刷盘和异步刷盘:

生产者消息发过来时,只有持久化到磁盘,存储端Broker才返回一个成功的ACK响应,这就是同步刷盘。它保证消息不丢失,但是影响了性能。
异步刷盘的话,只要消息写入PageCache缓存,就返回一个成功的ACK响应。这样提高了MQ的性能,但是如果这时候机器断电了,就会丢失消息。
Broker一般是集群部署的,有master主节点和slave从节点。消息到Broker存储端,只有主节点和从节点都写入成功,才反馈成功的ack给生产者,这就是同步复制,它保证了消息不丢失,但是降低了系统的吞吐量。与之对应的就是异步复制,只要消息写入主节点成功,就返回成功的ack,它速度快,但是会有性能问题。

在kafka中避免broker宕机,可以设置多副本冗余的高可用机制
 

3.消费者环节丢失
该环节丢失原因: 节点重平衡 和 偏移量自动提交导致的;
【消费者节点重平衡】可以简单的理解为,一个消费者组中,有一个消费者挂了,接着另一个消费者会接班之前的消费工作;
【偏移量自动提交】:每次poll数据之后,消费者默认每隔5s就会提交一次已消费的偏移量;

会导致一下情况:
【重复消费】: 消费者节点宕机之前,还未来得及提交偏移量,重平衡之后,新分配的消费者,按照之前的偏移量进行消费从而导致了重复消费;
【消费丢失】:消费者节点宕机之前,提交了偏移量,但是实际的消费偏移量还未到达提交的偏移量,从而导致了消费丢失;

【解决方案】:
禁用自动提交偏移量,改为手动:
enable-auto-commit:false

代码如下:
【扩展】为什么采用了 异步 +同步的方式?
因为 同步提交的时候,消费端的程序会处于阻塞状态,进而会影响系统数据的吞吐量;
而 异步提交方式,虽然解决了提交偏移量阻塞的问题,但是是没有自动重试机制的,会出现一定的风险,
所以二者相组合使用,进行互补;

kafka消息丢失解决方案_勤天的博客-CSDN博客

【348期】面试官:Kafka和RocketMQ有什么区别? - 知乎

https://zhuanlan.zhihu.com/p/423309452rocketmq 与 kafka 对比漫谈 - 简书

Spring Cloud(十二):消息中心篇-RocketMq与Kafka选型(四) - 墨天轮

kafka和rocketmq区别对比_—Phoenix的博客-CSDN博客

Kafka基础原理 - 简书

美团面试官让我聊聊kafka的副本同步机制,我忍不住哭了_wx646db0e245a37的技术博客_51CTO博客

kafka副本机制

浅析操作系统和Netty中的零拷贝机制

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

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

相关文章

this指向输出题

&#x1f197;先简简单单来看一个小代码 var name "windowsName"console.log(this.name, 222)function fn() {var name Cherryconsole.log(this.name, 444);innerFunction()console.log(this.name, 333)function innerFunction() {console.log(this.name, 111)}}fn…

8年测试老鸟总结,APP自动化测试思路整理,跟着步骤快速撸码...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、开发语言选择 …

STM32 Debug查看const变量 在flash中存储地址

1.下面const数组&#xff0c;存储在flash中&#xff0c;通过map文件获取CH_value的数组首地址0x080014c8&#xff0c;或者debug中在函数中添加CH_value到Memory&#xff0c;获取数组在flash中存储的位置。

C++对象模型(17)-- 构造函数语义学:成员初始化列表

1、必须用初始化列表的场景 &#xff08;1&#xff09;成员变量是引用类型&#xff0c;必须在初始化列表中初始化。 &#xff08;2&#xff09;成员变量是const类型&#xff0c;必须在初始化列表中初始化。 &#xff08;3&#xff09;如果类继承自一个父类&#xff0c;并且父…

跨境商城源码部署(无货源模式,多语言,多货币)

在互联网发展的背景下&#xff0c;跨境电商成为了全球贸易的重要形式之一。跨境商城源码部署是指将跨境电商平台的源代码部署到服务器上&#xff0c;以便搭建一个完整的跨境商城网站。通过部署源码&#xff0c;可以实现无货源模式、多语言和多货币等功能&#xff0c;为用户提供…

Flutter的Constructors for public widgets should have a named ‘key‘ parameter警告

文章目录 问题描述问题原因修改方法详细解释 问题描述 Constructors for public widgets should have a named ‘key’ parameter. 如下图&#xff1a; 原本的代码 class MyTabPage extends StatefulWidget {override_MyTabPageState createState() > _MyTabPageState(…

多测师肖sir_高级金牌讲师___ui自动化之selenium001

一、认识selenium &#xff08;1&#xff09;selenium是什么&#xff1f; a、selenium是python中的一个第三方库 b、Selenium是一个应用于web应用程序的测试工具&#xff0c;支持多平台&#xff0c;多浏览器&#xff0c;多语言去实现ui自动化测试&#xff0c;我们现在讲的Sel…

软件工程与计算总结(二十)软件交付

软件交付是软件项目的结束阶段 &#xff0c;标志着软件开发任务的完成——其作为一个分水岭&#xff0c;区分了软件开发与软件维护两个既连续又不同的软件产品生存状态~ 在经历连续的辛苦工作之后&#xff0c;开发人员在胜利曙光之前难免会忽视软件交付阶段的一些工作——在准…

2022年亚太杯APMCM数学建模大赛C题全球变暖与否全过程文档及程序

2022年亚太杯APMCM数学建模大赛 C题 全球变暖与否 原题再现&#xff1a; 加拿大的49.6C创造了地球北纬50以上地区的气温新纪录&#xff0c;一周内数百人死于高温&#xff1b;美国加利福尼亚州死亡谷是54.4C&#xff0c;这是有史以来地球上记录的最高温度&#xff1b;科威特53…

Shiro安全框架登录验证实例解析

一、Shiro框架简单介绍 Apache Shiro是Java的一个安全框架&#xff0c;旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证&#xff0c;授权&#xff0c;企业会话管理和加密等。Shiro的具体功能点如下&#xff1a; &#xff08;1&#…

即刻报名,企业服务与新经济论坛亮点提前揭秘!

峰会官网已上线&#xff0c;最新议程请关注&#xff1a;doris-summit.org.cn 即刻报名 Doris Summit 是 Apache Doris 社区一年一度的技术盛会&#xff0c;由飞轮科技联合 Apache Doris 社区的众多开发者、企业用户和合作伙伴共同发起&#xff0c;专注于传播推广开源 OLAP 与实…

每日一题 1726. 同积元组(中等,计数)

直接统计数组中的数字两两组合可以得到的乘积求将相同乘积的组合再两两组合的数量最后由于abcd的值可以互换&#xff0c;每一个组合通过呼唤位置可以得到8种不同的组合&#xff0c;所以最后乘以8 class Solution:def tupleSameProduct(self, nums: List[int]) -> int:d de…

【财政金融】全国各地区财政收入与支出面板数据合集(2000-2022年)

数据简介&#xff1a;2000年到2022年中国经历了快速的经济发展和城市化进程&#xff0c;各地区的财政收入和支出也呈现出显著的增长和变化&#xff0c;全国各地区财政收入与支出的面板数据可用于评估经济发展水平和区域差距&#xff0c;通过比较不同地区之间的财政收入和支出水…

MySQL 从一个表中查出数据并插入到另一个表处理方案(详细)

PS&#xff1a;来源表&#xff1a;t_source、目标表&#xff1a;t_target 第一种 来源表和目标表字段完全一致 insert into t_target select * from t_source; 第二种 来源表和目标表字段部分一致&#xff0c;只想导入来源表部分字段到目标表 insert into t_target(字段1,字…

详解自定义类型:结构体,位段,枚举,联合

目录 1.结构体 1.1 结构的基础知识 1.2 结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的定义和初始化 1.6 结构体内存对齐 1.7 修改默认对齐数 1.8 结构体传参 2. 位段 2.1 什么是位段 2.2 位段的内存分配 2.3 位段的跨平台问题 2.4 位段的应用 3. 枚举…

2023年中国恋爱社区未来发展趋势分析:多元化盈利模式实现可持续发展[图]

恋爱社区指满足情侣之间互动、记录及娱乐需求&#xff0c;以维护情侣恋爱关系的虚拟社区。恋爱社区行业主要以线上APP的虚拟形式为用户提供相关服务&#xff0c;其业务包括情侣记录、情侣互动、情侣娱乐、公共社区、线上购物、增值服务。 恋爱社区主要业务 资料来源&#xff1…

【LeetCode】47. 全排列 II

1 问题 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2], [1,2,1], [2,1,1]] 示例 2&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1…

新手如何学习嵌入式Linux?

今日话题&#xff0c;新手如何学习嵌入式Linux&#xff1f;嵌入式底层开发是一项至关重要的技能&#xff0c;广泛应用于各种嵌入式系统中&#xff0c;已经成为我们生活中不可或缺的一部分。因此&#xff0c;学习嵌入式开发变得愈发重要。我这里提供了一份嵌入式学习资料&#x…

ASO优化之增加应用APP安装量的技巧2

我们需要更新应用程序&#xff0c;并且最好以用户会注意到的方式进行更新&#xff0c;季节性或节日的更新非常适合这种情况&#xff0c;例如主题的改变&#xff0c;活动的推出或者是某种折扣。活动是能够让用户相信产品是高质量的关键。 1、应用描述也是优化的一部分。 它是应…

磁珠元器件:微小却强大的科技奇迹 | 百能云芯

在现代科技的背后&#xff0c;有着许多微小而强大的元器件&#xff0c;其中之一是磁珠元器件。尽管它们可能不如计算机芯片或太阳能电池板那样广为人知&#xff0c;但磁珠元器件在各种应用中扮演着重要角色。本文将深入探讨什么是磁珠元器件&#xff0c;它们的工作原理以及在科…