kafka原理看这一篇就够了

为何使用消息队列

  • 异步。接口方式实现多个系统协作,如图A系统作为用户请求接收方,需要调用多个系统的接口,这些接口还有可能是在A系统里同步调用,所以最后的接口耗时是多个系统接口耗时的总和;mq方式则可以异步发送消息给mq,mq再发送给其他多个系统,多个系统并行且异步的接收消息。当然,mq方式实现有一个前提是用户的请求不需要立即返回请求结果,例如用户发送一个查询请求就不适合mq方式。mq方式多用于传递事件,如发送优惠券、秒杀等。

  • 削峰。用户的请求大部分都集中在固定的时间段,而在晚间凌晨或者用户使用低峰期基本没什么请求。所以mq的削峰就是为了将高峰期的请求泄洪一部分到低峰期。
  • 解耦。接口方式发送消息,发送者调用接口,接收者提供接口,此时发送者作为消息生产者(如图中的A系统)作为主动的一方需要适配上游的各个类型的接口,它们的传输协议、参数、返回值等可能都不一样,同时各个接收方还不能拒收消息,这些都会带来极大的工作量;mq方式发送消息,消息发送者变成了上游,现在只需要将统一格式的消息发送给mq,由mq来控制消息的存储、容灾以及消息是否送达等。消息接收者则遵守消息的统一格式即可,如果不想接收消息可以取消订阅。这样就达到了生产者和消费者之间的解耦效果。

kafka的总体架构

  • Producer:消息的生产者,即消息的入口。
  • Broker:kafka的一个实例,一台kafka服务器上会有一个或多个实例。多台kafka服务构成了kafka的集群。
  • Topic:消息的主题,生产者按照主题发送消息,消费者按照主题接收消息,一个Broker可以有多个主题。
  • Partition:Topic的分区,一个Topic可以有多个分区,分区越多可以并行处理消息的能力越强。同一个Topic上的不同分区消息是不重复的,Partition的本质是文件夹。
  • Replication:Partition的副本,副本用来做数据备份。副本分为主分区副本(Leader)和从分区副本(Follower),它们不能同时出现在一个Broker上。主分区副本负责消息的接收并写入,从分区副本不接收生产者发来的消息,它的唯一职责就是从主分区副本同步过来消息。当主分区副本挂掉的时候,会在从分区副本中选出一个新的Leader作为主分区副本。kafka中一个Partition的最大副本数量是10个,且副本数量不能大于Broker的数量。
  • Consumer:消息的消费者,即消息的出口。
  • Consumer Group:多个消费者组成一个消费组,消费组之间可以重复消费消息。同一个消费组的某一个Partition不能同时被多个消费者消费。
  • Zookeeper:kafka集群依赖Zookeeper保存集群的元信息,以保证kafka集群的可靠性。kafka从2.8版本以后使用其内部的Quorum控制器来代替Zookeeper。

生产者写数据

生产者发送消息给Leader分区副本,并顺序写入到磁盘文件,然后Follower分区副本从Leader分区副本poll消息以保证数据是最新的。kafka将消息写入哪个分区有几下几个原则:

  • 生产者指定了分区,写入对应的分区
  • 生产者没有指定分区,但设置了数据库的key,根据key的hash值算出一个分区
  • 生产者既没有指定分区,也没有设置key,轮询出一个分区

topic本质是一个目录,而topic又是由一些Partition Logs(分区日志)组成。消息采用hash取模的分区算法有序的写入到Partitionp Log上。

producer在将消息写入partition之前会先在内存中缓存,累计到一定量后(按数量、按时间间隔或按数据大小),再批量写入。

一般一条消息大概1~10kB,推荐不要超过1MB。

kafka默认数据保留7天时间。如果数据量大可以修改配置(log.retention.hours)将时间缩短。

消费者读数据

与生产者一样,消费者主动的从Leader分区副本拉取消息。每成功拉取一条partition的消息,partition的消息游标卡尺(offset)就会加1。

partition里的offset默认配置是从最新一条开始消费,也可以配置from beginning从0开始消费。

在同一个消费组里,消费者和partition的关系是1:1或者1:n,不能出现消费者与partition是n:1的情况,意思是同一个消费组里消费者数量要小于等于parition的数量。因为不这样做就会造成多个消费者共享一个offset,从而就不能保证一个partition内的消息的顺序性,也会造成消息被重复消费的安全问题,这是一种不稳定的重复消费。

如果想要稳定的重复消费同一条消息,可以设置两个消费组。两个组内的消费者消费同一个partition时,offset是相互独立的。

消息的有序性

想要保证消息被消费的有序性,有以下两个方法:

  • 一个topic只设置一个partition。缺点是消费组里只能有一个消费者消费,不适用高并发场景。
  • producer将需要保证顺序的消息发送到同一个partition。两种方式指定:1、指定partition;2、不指定partition,根据key的hash值运算后得到partition。

消息的可靠性

kafka的数据是可持久化的写在Partition Log文件里。每个topic都可以设置副本数量。副本数量决定了有几个broker来存放写入的数据。

consumer和partition数量的关系是:partition数 >= 同一个消费组里的consumer数。因为一个partition只能被同一个消费组的一个consumer消费(但一个consumer可以消费多个partition)。这是为了消息在一个partition里的顺序读。

生产端消息可靠性

分区副本

所有的读写请求都发往leader副本所在的broker,follower副本不处理客户端请求,它唯一的任务就是从leader副本异步拉取消息。

Kafka默认的副本因子是3,即每个分区只有1个leader副本和2个follower副本。

同步副本(In-sync replicas)

ISR同步副本机制是用来判断follower是否同步了leader的最新数据。

ISR列表保存了与leader已经同步的副本,leader自己是长期存在于ISR列表。当follower副本超过设定的时间间隔(replica.lag.time.max.ms)没有和leader同步,就会被踢出ISR列表,反之则不会被踢出。

acks参数(生产者配置)

acks参数,表示有多少的分区副本收到消息,才能认为消息是写入成功的。

  • acks=0。不需要副本收到消息,producer就能收到broker的响应。该模式吞吐量高,但安全性低,容易丢消息。

  • acks=1(默认)。只要leader副本接收到了消息并写入到磁盘,producer就能收到broker的响应。需要注意的是这种模式依然会有丢消息的安全问题。例如,当leader副本收到消息以后还没来得及同步副本到follower就宕机了,此时producer已经收到了成功的响应,但follower变为新的leader时还未将最新的那条消息同步过来。

  • acks=all(或-1)。只有ISR列表里的所有分区副本都收到消息,producer才能收到broker的响应。该模式延迟最高。

acks=all模式下,有一个最小副本配置(min.insync.replicas)。该配置默认值是1,只在acks=all时生效。该参数控制消息最少被多少个副本写入才算成功写入。即ISR列表的副本最小数量。因为ISR列表始终要有leader副本,所以如果该配置默认是1,实际上是起不到副本作用的,所以该配置最好配置为大于1的数。

当leader副本宕机时,acks=all模式下,会在ISR列表中选举一个新的broker作为leader。

  • 增大min.insync.replicas。可以增加数据的可靠性。
  • 减小min.insync.replicas。可以增加系统的可用性。

消费端消息可靠性

要想实现消费端的消息可靠性,必须抓住两点:

  • 保证消息到达的状态(offset)和本地事务的状态保持一致。
  • 保证消费的幂等性。

要想保证消费端消息的可靠性,首先必须保证提交offset和提交本地事务要么一起成功,要么一起失败。我们以自动提交offset和手动提交offset分别举例说明。

  • 自动提交offset。消息到达消费客户端,不论本地事务是否提交成功,offset都会自动提交。一旦本地事务提交失败,就会造成消息丢失的问题。
  • 手动提交offset。有三种方法:
    • 第一种方式是消费端KafkaListener不配置本地事务,业务代码执行完后数据入库,最后再提交offset,即使offset提交失败,只要保证业务代码的幂等性,消息重复消费也可以接受。
    • 第二种方式是消费端KafkaListener配置本地事务,将offset的值写道数据库里和业务数据一起提交,这样就将业务数据和offset做了绑定关系,在消费一开始就根据业务id和offset判断消息是否消费过,如果没有消费过才执行业务代码。
    • 第三种方式是前两种方式的结合,这种方式不需要将offset入库。该方法在消费端KafkaListener配置本地事务,先执行业务代码最后执行offset提交,这样业务代码失败就不会执行提交offset的代码;而如果是最后提交offset失败,本地事务也会回滚。

在实际的运用中,考虑到数据库事务相对性能较差,可以把本地事务和offset的绑定关系用缓存来保存。

kafka优化

kafka削峰的几种方法:

  • 增加分区。增加分区数可以提高消息并行处理的能力。当然也会增加集群的维护成本,需要权衡。
  • 使用消费组。使用消费组可以让多个消费者并行消费一个partition的消息,因为每个消费组在同一个partition的offset不是共享的。但是为了避免重复消费消息,需要为不同消费组上的多个消费者指定所消费消息的key。
  • 增加副本数。可以提高kafka的吞吐量,提升kafka的可靠性和容错性。

此外,修改一些kafka配置参数也能达到一定的优化效果。例如,

  • 为了减少每次发送/拉取消息的次数,可以提高消息发送/拉取的消息数量/数据大小的阈值,或者增加时间间隔。减少消息发送/拉取的次数意味着一次发送/拉取的量比较大,所以还要注意提高会话超时、拉取超时的时间间隔,以免触发rebalance。
  • 减小并行度(concurrency)。当concurrency=3时,就会有4*3=12个Consumer线程,12个Listener线程。减小concurrency可以减少客户端线程数量。

kafka和rocketmq

目前消息队列用的比较多的就是kafka和rocketmq了。我们可以比较一下这两种消息队列的优缺点。

  • 适用场景

topic较多时推荐使用rocketmq;topic少时kafka性能更佳。因为kafka一个topic一个partition文件,rocketmq是多个topic一个文件。

kafka适合日志处理、大数据领域;rocketmq适合业务处理。

  • 性能

kafka的tps在百万条/秒;rocketmq大约10万条/秒。

  • 可靠性

kafka异步刷盘,异步副本;recketmq异步/同步刷盘,异步/同步副本。

  • 支持队列数量

kafka单机最大支持64个队列/分区,增加分区性能降低严重;rocketmq单机最大支持5w队列,性能稳定。

  • 消息顺序性

kafka在同一个partition下支持消息顺序性,但如果一台broker宕机会打乱顺序;rocketmq支持消息顺序性,一台broker宕机消息会发送失败,但顺序性依然可以保证。

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

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

相关文章

解决ubuntu23.10 wifi不能使用的问题

解决ubuntu23.10 wifi不能使用的问题 今天升级到了ubuntu23.10之后,wifi不能使用。 参考此视频解决了问题: https://www.youtube.com/watch?appdesktop&vn92O8rNKVb0 sudo lshw -class networkcd /etc/pm/sleep.dlssudo touch configsudo gedit co…

Java制作俄罗斯方块

Java俄罗斯方块小游戏 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.List; imp…

C#,怎么修改(VS)Visual Studio 2022支持的C#版本

一些文字来自于 Microsoft . (只需要读下面的红色文字即可!) 1 C# 语言版本控制 最新的 C# 编译器根据项目的一个或多个目标框架确定默认语言版本。 Visual Studio 不提供用于更改值的 UI,但可以通过编辑 .csproj 文件来更改值。…

1688阿里巴巴官方开放平台API接口获取商品详情、商品规格信息列表、价格、宝贝详情数据调用示例说明

商品详情API接口在电商平台和购物应用中的作用非常重要。它提供了获取商品详细信息的能力,帮助用户了解和选择合适的商品,同时也支持开发者进行竞品分析、市场研究和推广营销等工作,以提高用户体验和促进销售增长。 1688.item_get-获得1688商…

单链表的实现(Single Linked List)---直接拿下!

单链表的实现(Single Linked List)—直接拿下! 文章目录 单链表的实现(Single Linked List)---直接拿下!一、单链表的模型二、代码实现,接口函数实现①初始化②打印链表③创建一个结点④尾插⑤尾…

Unity 场景烘培 ——unity Post-Processing后处理1(四)

提示:文章有错误的地方,还望诸位大神不吝指教! 文章目录 前言一、Post-Processing是什么?二、安装使用Post-Processing1.安装Post-Processing2.使用Post-Processing(1).添加Post-process Volume&#xff08…

Flutter 3.16 中带来的更新

Flutter 3.16 中带来的更新 目 录 1. 概述2. 框架更新2.1 Material 3 成为新默认2.2 支持 Material 3 动画2.3 TextScaler2.4 SelectionArea 更新2.5 MatrixTransition 动画2.6 滚动更新2.7 在编辑菜单中添加附加选项2.8 PaintPattern 添加到 flutter_test 3. 引擎更新&#xf…

文件隐藏 [极客大挑战 2019]Secret File1

打开题目 查看源代码发现有一个可疑的php 访问一下看看 点一下secret 得到如下页面 响应时间太短我们根本看不清什么东西,那我们尝试bp抓包一下看看 提示有个secr3t.php 访问一下 得到 我们看见了flag.php 访问一下可是什么都没有 那我们就进行代码审计 $file$_…

Servlet---上传文件

文章目录 上传文件的方法上传文件的示例前端代码示例后端代码示例 上传文件的方法 上传文件的示例 前端代码示例 <body><form action"upload" method"post" enctype"multipart/form-data"><input type"file" name&qu…

2023年中国地产SaaS分类、产业链及市场规模分析[图]

SaaS是一种基于云计算技术&#xff0c;通过订阅的方式向互联网向客户提供访问权限以获取计算资源的一项软件即服务。地产SaaS则是SaaS的具体应用&#xff0c;提供了一个线上平台&#xff0c;用于协助房地产供应商与购房者、建筑承建商、材料供应商及房地产资产管理公司之间的协…

【Linux网络】详解使用http和ftp搭建yum仓库,以及yum网络源优化

目录 一、回顾yum的原理 1.1yum简介 yum安装的底层原理&#xff1a; yum的好处&#xff1a; 二、学习yum的配置文件及命令 1、yum的配置文件 2、yum的相关命令详解 3、yum的命令相关案例 三、搭建yum仓库的方式 1、本地yum仓库建立 2、通过http搭建内网的yum仓库 3、…

Sentinel 热点规则 (ParamFlowRule)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 SpringbootDubboNacos 集成 Sentinel&…

Navicat for mysql 无法连接到虚拟机的linux系统下的mysql

原创/朱季谦 最近在linux Centos7版本的虚拟机上安装了一个MySql数据库&#xff0c;发现本地可以正常ping通虚拟机&#xff0c;但Navicat则无法正常连接到虚拟机里的MySql数据库&#xff0c;经过一番琢磨&#xff0c;发现解决这个问题的方式&#xff0c;很简单&#xff0c;总共…

Appium移动自动化测试--安装Appium

Appium 自动化测试是很早之前就想学习和研究的技术了&#xff0c;可是一直抽不出一块完整的时间来做这件事儿。现在终于有了。 反观各种互联网的招聘移动测试成了主流&#xff0c;如果再不去学习移动自动化测试技术将会被淘汰。 web自动化测试的路线是这样的&#xff1a;编程语…

springboot--单元测试

单元测试 前言1、写测试要用的类2、写测试要用的类3、运行测试类4、spring-boot-starter-test默认提供了以下库4.1 junit54.1.1 DisplayName:为测试类或者测试方法设置展示名称4.1.2 BeforeAll&#xff1a;所有测试方法运行之前先运行这个4.1.3 BeforeEach&#xff1a;每个测试…

2023.11.17-hive调优的常见方式

目录 0.设置hive参数 1.数据压缩 2.hive数据存储格式 3.fetch抓取策略 4.本地模式 5.join优化操作 6.SQL优化(列裁剪,分区裁剪,map端聚合,count(distinct),笛卡尔积) 6.1 列裁剪: 6.2 分区裁剪: 6.3 map端聚合(group by): 6.4 count(distinct): 6.5 笛卡尔积: 7…

如何挖掘xss漏洞

如何挖掘xss漏洞 对于如何去挖掘一个xss漏洞我是这样理解的 在实战情况下不能一上来就使用xss语句来进行测试很容易被发现 那这种情况该怎么办呢 打开准备渗透测试的web网站&#xff0c;寻找可以收集用户输入的地方比如搜索框&#xff0c;url框等 发现后寻找注入点 选在输入…

从一到无穷大 #19 TagTree,倒排索引入手是否是优化时序数据库查询的通用方案?

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 文章主旨时序数据库查询的一般流程扫描维度聚合时间聚合管控语句 TagTree整体结构索引…

壹基金为爱同行到余村,以一步步健行换一滴滴净水

为帮助乡村儿童喝上干净的、足量的饮用水,壹基金联合可口可乐中国发起为爱同行2023安吉余村公益健行活动。本次活动得到了湖州市安吉县天荒坪镇人民政府、湖州市安吉县天荒坪镇余村村村民委员会的大力支持,由深圳市登山户外运动协会、文益社、悦跑圈联合主办。参与健行不仅能感…

【PCB学习】几种接地符号

声明 该图并非原创&#xff0c;原文出处不可考&#xff0c;因此在这里附加说明。 示意图