kafka原理看这一篇就够了

news2024/9/21 12:49:40

为何使用消息队列

  • 异步。接口方式实现多个系统协作,如图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.coloradmin.cn/o/1230864.html

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

相关文章

netty整合websocket(完美教程)

websocket的介绍: WebSocket是一种在网络通信中的协议,它是独立于HTTP协议的。该协议基于TCP/IP协议,可以提供双向通讯并保有状态。这意味着客户端和服务器可以进行实时响应,并且这种响应是双向的。WebSocket协议端口通常是80&am…

Spring源码-5.aop代理

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码🔥如果感觉博主的文章还不错的话,请👍三连支持&…

Python实现WOA智能鲸鱼优化算法优化随机森林分类模型(RandomForestClassifier算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…

nginx学习(4)Nginx 配置高可用集群(主从配置)

Nginx 配置高可用集群 Nginx的高可用集群是指由两台或多台Nginx服务器组成的集群系统,通过负载均衡和故障转移等技术,实现高可用性和可伸缩性的目标。在这种集群系统中,每个Nginx服务器都配置为主节点(master)或从节点…

阿里国际站(直通车)

1.国际站流量 2.直通车即P4P(pay for performance点击付费) 2.1直通的含义:按点击付费,通过自助设置多维度展示产品信息,获得大量曝光吸引潜在买家。 注意:中国大陆和尼日利尼地区点击不扣费。 2.2扣费规…

记一次代码审计中RCE挖掘及POC编写

文章转自先知社区:https://xz.aliyun.com/t/13008 作者:雨下整夜 声明:本文仅限于技术讨论与分享,严禁用于非法途径。若读者因此作出任何危害网络安全行为后果自负,与本号及原作者无关。 从危险的模板引入开始 在前…

网络工程师网络配置经典例题(二)

目录 1、access、trunk 2、配置终结子接口 3、DHCP接口地址池、DNS 4、静态默认路由、接口IP 5、ACL、NAT 使内网用户可以访问外网 6、VLANIF 某公司拥有多个部门且位于不同网段,各部门均有访问Internet的需求。现要求用户通过二层交换机和路由器访问外部网络…

微信可以注册小号啦,看看怎么操作

微信支持同一手机号绑定两个账号啦! 生活号和工作号可以分开啦~实用又简单! 详细步骤如下: ①点击微信-我的-设置 ②点击“切换账号” ③点击“添加账号” ④点击“注册新账号” ⑤点击“通过当前微信的手机号辅助注册” ⑥安…

系列十、ReentrantReadWriteLock

一、概述 ReentrantReadWriteLock是ReadWriteLock的一个子类,具有读锁和写锁的双重功能,通常用于做缓存。 二、案例代码 2.1、ReentrantReadWriteLockCache /*** Author : 一叶浮萍归大海* Date: 2023/11/20 17:57* Description: 使用ReentrantReadWri…

学习笔记—吴恩达《AI for everyone》

【写在前面】 学习视频来源:B站“GPT中英字幕课程资源”(见图片水印)。 此文是自学笔记,主要是截图视频课件中的一些知识点,只做自学使用。 一. AI 介绍 二. 机器学习 Machine Learning 三. 什么是数据 What is AI 四…

成为电车销量的“中坚力量”,微小型车不能只有“低价”?

日常交通中,越来越多的汽车开始“绿牌出行”,市场的最新销量也不断验证着新能源车抢占更多市场的事实。 11月初,国内多家车企公布10月销量数据,其中新能源汽车销量增长仍然亮眼。根据中国工业和信息化部数据,我国汽车…

【18年扬大真题】给定有m个整数的递增有序数组a和有n个整数的递减有序数组b,将a数组和b数组归并为递增有序的数组c

【18年扬大真题】 给定有m个整数的递增有序数组a和有n个整数的递减有序数组b&#xff0c; 将a数组和b数组归并为递增有序的数组c。 void Merge(int arr[],int m ,int brr[],int n,int crr[]) {int i 0;int j n-1;int k 0;while(i < m&&j > 0) {if (arr[i] &l…

【项目实战】多租户实现数据库动态切换

文章目录 背景多数据源准备工作整体思路 多数据源切换方式准备工作自动切换&#xff08;DS方式&#xff09;配置文件设置 手动切换配置文件设置项目启动加载数据源&#xff1a;使用注解PostConstruct添加数据源 总结 背景 最近公司项目中需要做多租户进行数据源切换的业务&…

Vue2问题:分享一个通用多文件类型预览库

前端功能问题系列文章&#xff0c;点击上方合集↑ 序言 大家好&#xff0c;我是大澈&#xff01; 本文约2000字&#xff0c;整篇阅读大约需要3分钟。 本文主要内容分三部分&#xff0c;第一部分是需求分析&#xff0c;第二部分是实现步骤&#xff0c;第三部分是问题详解。 …

UI自动化测试神器Playwright(Java版)(保存登录cookie,解决免登录)

&#x1f3ad; Playwright在称为浏览器上下文的隔离环境中执行测试。该隔离模型提高了可重复性并防止相关联的测试脚本执行失败。测试可以加载现有的已验证状态&#xff0c;比如获取已登录的状态&#xff08;Cookie&#xff09;&#xff0c;在后续脚本中复用。这消除了在每个测…

金蝶 EAS及EAS Cloud任意文件上传漏洞复现

0x01 产品简介 金蝶EAS Cloud为集团型企业提供功能全面、性能稳定、扩展性强的数字化平台&#xff0c;帮助企业链接外部产业链上下游&#xff0c;实现信息共享、风险共担&#xff0c;优化生态圈资源配置&#xff0c;构筑产业生态的护城河&#xff0c;同时打通企业内部价值链的数…

SQL 中的 NULL 值:定义、测试和处理空数据,以及 SQL UPDATE 语句的使用

SQL NULL 值 什么是 NULL 值&#xff1f; NULL 值是指字段没有值的情况。如果表中的字段是可选的&#xff0c;那么可以插入新记录或更新记录而不向该字段添加值。此时&#xff0c;该字段将保存为 NULL 值。需要注意的是&#xff0c;NULL 值与零值或包含空格的字段不同。具有 …

MR混合现实教学系统在汽车检修与维护课堂教学中的应用

传统的汽车检修与维护课堂教学主要依赖教师口头讲解和黑板演示&#xff0c;这种方式存在一定的局限性。首先&#xff0c;对于一些复杂的机械结构和操作过程&#xff0c;教师难以生动形象地展示给学生。其次&#xff0c;学生无法直接观察到实际操作中的细节和注意事项&#xff0…

WPF Button点击鼠标左键弹出菜单

目录 ContextMenu介绍WPF实现点击鼠标左键弹出菜单如何禁用右键菜单如何修改菜单样式菜单位置设置 本篇博客介绍WPF点击按钮弹出菜单&#xff0c;效果如下&#xff1a; 菜单的位置、央视可以自定义。 实现技巧&#xff1a;不在xaml里菜单&#xff0c;在按钮左键按下的点击事件里…

锚点优化步步为赢:详细解析关键知识点和最佳实践,提升网页的关联性与权威性!

为所有文本链接使用描述性锚文本。大多数搜索引擎在对网页进行排名时都会考虑输入链接的锚文本。下面是一个锚文本示例&#xff1a; <a href"otherpage.htm" title"Anchor Title">Anchor Text</a>下面列出了一些关于锚点的注意事项&#xff1…