带你走进 字节跳动 消息队列

news2025/1/12 13:16:45

区别于#创作活动那一篇文章,这篇文章有我自己的重点内容颜色标记等注释,有注释的参加不了那个活动,所以发了两篇,不久之后那篇文章将会删除

消息队列前世今生

1.1 案例一: 系统崩溃

首先大家跟着我想象一下下面的这个的场景,

看到新出的游戏机,太贵了买不起,这个时候你突然想到,今天抖音直播搞活动,打开抖音搜索,找到直播间以后,你点开了游戏机详情页,看到价格只要500。

这个时候我们分析一下,就我们上面这几步操作,在我们的程序背后,做了什么事情

首先,请求会先到搜索商品这个服务上,并记录下你的搜索行为;

然后点击商品的时候,又记录了我们的点击商品,这些数据最终都会通过计算分析;

目的是为了下一次给你更准确的信息,这个时候问题来了,如果这个时候,负责记录存储的数据库被一个小哥删库跑路了。我们的所有操作都动不了了,这个时候我们应该怎么办,带着这个问题,我们继续往下看

1.2 案例二:服务能力有限

看到这个价格,你非常心动,商品即将在3分钟后开抢,这个价格必须要抢到啊!但此时在无数台手机的后面,藏着无数和你一样饥渴的同学,再来看看,后面的程序又做了哪些事情呢?

一堆人都发起了订单请求,可是公司给的预算不够,服务器的配置太弱,订单服务只能同时处理10个订单请求。这个时候我们又该怎么办呢。继续往下看

1.3案例三:链路耗时长尾

在我们点击提交订单之后,这个怎么一直转圈圈,卡在这个页面啊,等了半分钟后,

啊终于抢到了,不过这app也太慢了,下次不用了。我们进一步看一下这次问题出在哪里了

一通分析,发现,库存服务和订单服务都挺快的,但是后通知商家(30s)这一步咋这么慢,是不是还可以进行优化呀?

1.4 案例四:日志存储

在字节跳动的会议室里传出了悲伤的声音,因为刚刚有服务器坏掉了,我们的本地日志都丢掉了,没有了日志,我们还怎么去修复那些刚刚出现的那些问题,周围一片寂静,突然小张站出来缓缓的说了一句话,众人才露出了微笑准备下班离开,大家能猜到小张到底说的什么吗

1.1.1 案例一 解决方案

1.2.1

既然 服务器等其他原因导致 处理能力有限 ,我们可以把大量请求放到消息队列;每次拿10个处理

1.3.1

把“发起订单”请求放到《消息队列》,异步做那三个事,逻辑上在库存-1的时候就可以返回;下单成功,剩下的时候做商家通知,不用等他完事了再return 成功;

1.4.1

2.0 消息队列

2.1消息队列发展历程

消息中间件其实诞生的很早,早在1983年互联网应用还是一片荒芜的年代,有个在美国的印度小哥Vivek就设想了一种通用软件总线,世界上第一个现代消息队列软件The Information Bus(TIB),TIB受到了企业的欢迎,这家公司的业务发展引起了当时最牛气的IT公司IBM的注意,于是他们一开始研发了自己消息队列软件,于是才有了后来的wesphere mq,再后来微软也加入了战斗。

接近2000年的时候,互联网时代已经初见曙光,全球的应用程序得到了极大地丰富,对于程序之间互联互通的需求越来越强烈,但是各大IT公司之间还是牢牢建立着各种技术壁垒,以此来保证自己的商业利益,所以消息中间件在那个时候是大型企业才能够用的起的高级玩意。

但是时代的洪流不可逆转,有壁垒就有打破壁垒的后来者,2001年sun发布了JMS技术,试图在各大厂商的层面上再包装一层统一的java规范。java程序只需要针对jms api编程就可以了,不需要再关注使用了什么样的消息中间件,但是jms仅仅适用于java

2004年AMQP(高级消息队列协议)诞生了,才是真正促进了消息队列的繁荣发展,任何人都可以针对AMQP的标准进行编码。有好的协议指导,再加上互联网分布式应用的迅猛发展成为了消息中间件一飞冲天的最大动力,程序应用的互联互通,发布订阅,最大契合了消息中间件的最初的设计初衷。

除了刚才介绍过的收费中间件,后来开源消息中间件开始层出不穷,常见比较流行的有ActiveMQ、RabbitMQ 、Kafak、阿里的RocketMQ,以及目前存算分离的Pulsar,在目前互联网应用中消息队列中间件基本上成为标配。

2.1.1 业界消息队列对比

3.0 Kafka

3.1使用场景

一般是 离线的消息处理、Metrics(程序运行当中程序状态的采集)数据、用户行为

3.2 如何使用

引入Kafka 的SDK 实现上游的生产逻辑,消费者拉取

第一步:首先创建一个Kafka集群,但如果你在字节工作,恭喜你这一步消息团队的小伙伴已经帮你完成了

第二步:需要在这个集群中创建一个Topic,并且设置好分片数量

第三步:引入对应语言的SDK,配置好集群和Topic等参数,初始化一个生产者,调用Send方法,将你的Hello World发送出去

第四步:引入对应语言的SDK,配置好集群和Topic等参数,初始化一个消费者,调用Poll方法,你将收到你刚刚发送的Hello World

3.3 基本概念

Topic:Kakfa中的逻辑队列,可以理解成每一个不同的业务场景就是一个不同的topic,对于这个业务来说,所有的数据都存储在这个topic中

Cluster:Kafka的物理集群,每个集群中可以新建多个不同的topic

Producer:顾名思义,也就是消息的生产端,负责将业务消息发送到Topic当中

Consumer:消息的消费端,负责消费已经发送到topic中的消息

Partition:通常topic会有多个分片,不同分片直接消息是可以并发来处理的,这样提高单个Topic的吞吐,对于每一个Partition来说,每一条消息都有一个唯一的Offset,消息在partition内的相对位置信息,并且严格递增

3.3.2 Offset

3.3.3 Replica:分片的副本,分布在不同的机器上,可用来容灾

Leader对外服务,Follower异步去拉取leader的数据进行一个同步,尽量保持同步

如果leader挂掉了,可以将ISR的Follower提升成leader再对外进行服务

ISR(In-Sync Replicas):

意思是同步中的副本,对于Follower来说,始终和leader是有一定差距的,但当这个差距比较小的时候,我们就可以将这个follower副本加入到ISR中;差距大就提出ISR;不在ISR中的副本是不允许提升成Leader的

3.4 数据复制

下面这幅图代表着Kafka中副本的分布图。

图中Broker代表每一个Kafka的节点,所有的Broker节点最终组成了一个集群。

整个图表示,图中整个集群,包含了4个Broker机器节点,集群有两个Topic,分别是Topic1和Topic2,Topic1有两个分片,Topic2有1个分片,每个分片都是三副本的状态。

这里中间有一个Broker同时也扮演了Controller的角色,

Controller是整个集群的大脑,负责对副本和Broker进行分配,再告诉各个Broker怎么去处理

3.5 Kafka架构

集群的基础上,还有一个模块是ZooKeeper,这个模块其实是存储了集群的元数据信息,和Controller配合

比如副本的分配信息等等,Controller计算好的方案都会放到这个地方

3.6 一条消息的自述

一条消息的视角来看看完整的处理流程,了解一下Kafka为什么可以支撑如此高的吞吐

一秒几千万条数据 吞吐量达不到要求 不能等

3.7.1 Producer-批量发送

3.7.2 Producer-数据压缩

默认选择 Snappy压缩算法;当前 经过测试 ZSTD算法在计算性能、压缩率等更加优秀

3.8 Broker-数据存储

如何写入到磁盘呢,我们先来看一下Kafka最终存储的文件结构是什么样子的

在每一个Broker,都分布着不同Topic的不同分片,不同副本以Log形式 写入磁盘;Log会切分成不同的有序的LogSegment;.log存真实数据;.index 日志具体位置的映射;

只看一个盘面,磁头->磁道->扇区 寻道成本高

3.8.2 顺序写

采用顺序写的方式进行写入,以提高写入效率

3.8.3如何找到消息

此时我们的消息写入到Broker的磁盘上了,那这些数据又该怎么被找到然后用来消费呢

3.8.4偏移量索引文件

介绍文件:文件名是文件中第一条消息的offset

第一步,通过二分找到小于目标文件的最大文件

通过二分找到小于目标offset最大的索引位置,再遍历找到目标offset

3.8.5 时间戳文件索引

如果我们需要使用时间戳来寻找的时候,和offset相比只是多加了以及索引,也就是通过二分找到时间戳对应的offset,再重复之前的步骤找到相应的文件数据

3.8.6 传统数据拷贝& 零拷贝

磁盘读到内核态 再拷贝到用户态的应用空间 然后 网卡发送到 消费者

零拷贝 :直接从内核空间 传到NIC网卡 ;减少三次传统拷贝

3.9 Consumer—消息的接收端

对于一个Consumer Group来说,多个分片可以并发的消费,这样可以大大提高消费的效率

但需要解决的问题是,Consumer和Partition的分配问题, 也就是对于每一个Partition来讲,该由哪一个Consumer来消费的问题。

对于这个问题,我们一般有两种解决方法,手动分配和自动分配

3.9.1 Consumer—Low Level

第一,手动分配,也就是Kafka中所说的Low Level消费方式进行消费

这种分配方式的一个好处就是启动比较快,因为对于每一个Consumer来说,启动的时候就已经知道了自己应该去消费哪个消费方式,好比图中的Consumer Group1来说,Consumer1去消费Partition 1,2,3 Consumer2,去消费456, Consumer3去消费78。

这些Consumer在启动的时候就已经知道分配方案了,但这样这种方式的缺点又是什么呢,想象一下,如果我们的Consumer3挂掉了,我们的7,8分片是不是就停止消费了。

又或者,如果我们新增了一台Consumer4,那是不是又需要停掉整个集群,重新修改配置再上线,保证Consumer4也可以消费数据

其实上面两个问题,有时候对于线上业务来说是致命的。

3.9.1 Consumer—High Level

所以Kafka也提供了自动分配的方式,这里也叫做High Level的消费方式,

简单的来说,就是在我们的Broker集群中,对于不同的Consumer Group来讲,都会选取一台Broker当做Coordinator(协调者),

而Coordinator的作用就是帮助Consumer Group进行分片的自动分配,也叫做分片的rebalance,

使用这种方式,如果ConsumerGroup中有发生宕机,或者有新的Consumer加入,整个partition和Consumer都会重新进行分配来达到一个稳定的消费状态

3.10 Consumer Rebalance

3.11 Kafka—数据复制问题

通过前面的介绍我们可以知道,对于Kafka来说,

每一个Broker上都有不同topic分区的不同副本,而每一个副本,会将其数据存储到该Kafka节点上面,对于不同的节点之间,通过副本直接的数据复制,来保证数据的最终一致性,与集群的高可用。

3.12 Kafka—重启操作

举个例子来说,如果我们对一个机器进行重启;

首先,我们会关闭一个Broker,此时如果该Broker上存在副本的Leader,那么该副本将发生leader切换,切换到其他节点上面并且在ISR中的Follower副本,

可以看到图中是切换到了第二个Broker上面 而此时,因为数据在不断的写入,对于刚刚关闭重启的Broker来说,和新Leader之间一定会存在数据的滞后,此时这个Broker会追赶数据,重新加入到ISR当中 当数据追赶完成之后,我们需要回切leader,

这一步叫做prefer leader,目的是为了避免:在一个集群长期运行后,所有的leader都分布在少数节点上,导致数据的不均衡

通过上面的一个流程分析,我们可以发现对于一个Broker的重启来说,需要进行数据复制,所以时间成本会比较大,比如一个节点重启需要10分钟,一个集群有1000个节点,如果该集群需要重启升级,则需要10000分钟,那差不多就是一个星期,这样的时间成本是非常大的。

有同学可能会说,老师可以不可以并发多台重启呀,问的好,不可以。

为什么呢,在一个 两副本(一个分片 有两个副本)的集群中,重启了两台机器,对某一分片来讲,可能两个分片都在这两台机器上面,则会导致该集群处于不可用的状态(影响整个Topic)。这是更不能接受的。

3.13-替换,扩容,缩容操作

如果是替换,和刚刚的重启有什么区别?

其实替换,本质上来讲就是一个需要 追 更多数据的重启操作,因为正常重启只需要追一小部分,而替换,则是需要复制整个leader的数据,时间会更长

扩容呢,当分片分配到新的机器上以后,也是相当于要从0开始复制一些新的副

缩容,缩容节点上面的分片也会分片到集群中剩余节点上面,分配过去的副本也会从0开始去复制数据

以上三个操作均有数据复制所带来的时间成本问题,所以对于Kafka来说,运维操作带来的时间成本是不容忽视的

3.14 负载不均衡

这个场景当中,同一个Topic有4个分片,两副本,

可以看到,对于分片1来说,数据量是明显比其他分片要大的,当我们机器IO达到瓶颈的时候,可能就需要把第一台Broker上面的Partition3 迁移到其他负载小的Broker上面,接着往下看

但我们的数据复制又会引起Broker1的IO升高,所以问题就变成了,我为了去解决IO升高,但解决问题的过程又会带来更高的IO,所以就需要权衡IO设计出一个极其复杂的负载均衡策略

问题总结

我们对以上两个问题进行总结,

第一,因为有数据复制的问题,所以Kafka运维的时间成本和人力人本都不低

第二,对于负载不均衡的场景,我们需要有一个较为复杂的解决方案进行数据迁移,从而来权衡IO升高的问题

除了以上两个问题以外,Kafka自身还存在其他的问题

比如,Kafka没有自己的缓存,在进行数据读取的时候,只有Page Cache可以用,所以不是很灵活

另外在前面的介绍当中,相信大家也了解到了,Kafka的Controller(负责分片方案)和Coordinator都是和Broker部署在一起的,Broker因为承载大量IO的原因,会导致Controller和Coordinator的性能下降,如果到一定程度,可能会影响整个集群的可用性

4.0 BMQ

字节自研的消息队列,ByteMQ,简称BMQ

BMQ兼容Kafka协议,存算分离,云原生消息队列,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群,我们来了解一下BMQ的架构特点

非常感谢您阅读到这里,如果这篇文章对您有帮助,希望能留下您的点赞👍 关注💖 收藏 💕评论💬感谢支持!!!

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

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

相关文章

(2023)Linux安装pytorch并使用pycharm远程编译运行

(2023)Linux安装pytorch并使用pycharm远程编译运行 安装miniconda 这部分参考我这篇博客的前半部分Linux服务器上通过miniconda安装R(2022)_miniconda 安装r_Dream of Grass的博客-CSDN博客 创建环境 创建一个叫pytorch的环境…

Nodejs-nrm:快速切换npm源 / npm官方源和其他自定义源之间切换

一、理解 Nodejs nrm Nodejs nrm 是一个管理 npm 源的工具。由于 npm 在国内的速度较慢,很多开发者会使用淘宝的 npm 镜像源,但是也会遇到一些问题,例如某些包在淘宝镜像源中不存在,或者淘宝镜像源本身也会有问题。 Nodejs nrm …

【C++ 学习 ⑯】- 继承(上)

目录 一、继承的概念和定义 1.1 - 概念 1.2 - 定义 二、继承时的对象内存模型 三、向上转型和向下转型 四、继承时的名字遮蔽问题 4.1 - 有成员变量遮蔽时的内存分布 4.2 - 重名的基类成员函数和派生类成员函数不构成重载 一、继承的概念和定义 1.1 - 概念 C 中的继承…

java八股文面试[java基础]——浅拷贝和深拷贝

自验证:创建Class Student两个类, Student中含有Class对象 public class Class implements Cloneable {public String getName() {return name;}public void setName(String name) {this.name name;}private String name;public Class(String name) {t…

无涯教程-PHP - IntlChar类

在PHP7中&#xff0c;添加了一个新的 IntlChar 类&#xff0c;该类试图公开其他ICU函数。此类定义了许多静态方法和常量&#xff0c;可用于操作unicode字符。使用此类之前&#xff0c;您需要先安装 Intl 扩展名。 <?phpprintf(%x, IntlChar::CODEPOINT_MAX);print (IntlCh…

构建智慧停车场:4G DTU实现无线数据高速传输

物联网技术的快速发展使得各种设备能够实现互联互通&#xff0c;无线网络技术给我们的日常生活带来了极大的便利。其中的网络技术如无线WiFi及4G网络已经成为了物联网应用中不可或缺的组成部分。而在工业领域中对4G无线路由器的应用是非常广泛的&#xff0c;人们通过4G工业路由…

python中 * 的用法,超详细教程

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 python中 * 是非常常见的一个运算符&#xff0c;它主要有以下几个功能&#xff1a; 乘法运算符&#xff1b; 函数形参表示可变参数&#xff1b; 函数实参代表tuple&#xff1b; 序列解包为tuple&#xff1b; zip解包运算&…

知识蒸馏Demo,非常详细,适合入门

文章来自&#xff1a;Ai浩的“知识蒸馏实战&#xff1a;使用CoatNet蒸馏ResNet”&#xff0c;文章地址为&#xff1a;知识蒸馏实战&#xff1a;使用CoatNet蒸馏ResNet_知识蒸馏实例_AI浩的博客-CSDN博客 感谢作者&#xff01;&#xff01;&#xff01; 摘要 知识蒸馏&#xf…

nvm安装使用教程

文章目录 下载配置安装最新稳定版 node安装指定版本查看版本切换版本删除版本 常见问题安装node后 显示拒绝访问的问题使用cnpm会报错的问题降低cnpm版本npm镜像 下载 NVM for Windows 下载地址&#xff1a;https://link.juejin.cn/?targethttps%3A%2F%2Fgithub.com%2Fcoreyb…

《动手学深度学习》-19卷积层

沐神版《动手学深度学习》学习笔记&#xff0c;记录学习过程&#xff0c;详细的内容请大家购买书籍查阅。 b站视频链接 开源教程链接 卷积 使用一个12M像素的相机采集图片&#xff0c;因为是RGB图片所以有36M元素。 使用MLP来做分类会遇到的问题&#xff1a; 参数太大&#…

goland 中的调试器 -- Evaluate

今天一个好朋友 找到我&#xff0c;问我关于goland中Evaluate 小计算器的使用方式&#xff0c;说实话&#xff0c;我在此之前也没用过这个东西&#xff0c;然后我就找一些相关文档&#xff0c;但是这类文档少的可怜&#xff0c;所以我就稍微研究一下&#xff0c;找找材料&#…

【附安装包】Vero visi2021安装教程

软件介绍 Vero visi是世界领先的CAD/CAM解决方案&#xff0c;又简称为visi&#xff0c;由多个模块组成&#xff0c;包括VISI Modelling、VISI Analysis、VISI Mould、VISI Flow、VISI Electrode、VISI Progress、VISI Multi-Slides、VISI Machining 2D、VISI PEPS-Wire、WorkX…

《操作系统真象还原》学习笔记:第七章 中断

由于 CPU 获知了计算机中发生的某些事&#xff0c;CPU 暂停正在执行的程序&#xff0c;转而去执行处理该事件的程序&#xff0c;当这段程序执行完毕后&#xff0c;CPU 继续执行刚才的程序。整个过程称为中断处理&#xff0c;也称为中断。 把中断按事件来源分类&#xff0c;来自…

nginx:正向代理与反向代理

所谓代理服务器&#xff0c;就是位于发起请求的客户端与原始服务器端之间的一台跳板服务器&#xff0c; 正向代理可以隐藏客户端&#xff1a;想要实现正向代理&#xff0c;得配置一台转发请求的跳板服务器&#xff0c;同时客户端还得配置跳板服务器的代理地址。 我的电脑访问这…

5大轻量开源的项目管理软件推荐,更适合中小团队!

随着互联网的发展&#xff0c;项目管理软件越来越受到企业和团队的重视。不仅可以提高工作效率&#xff0c;还可以帮助团队协作、进度跟踪和资源管理等方面&#xff0c;简化复杂的项目管理流程。那么&#xff0c;对于中小团队来说&#xff0c;有没有一款轻量易上手的适合他们的…

网络防御与蓝队实践:探讨网络防御策略、入侵检测系统、安全事件响应等蓝队方面的实际案例和方法

第一章&#xff1a;引言 网络安全一直是当今信息社会中至关重要的话题。随着技术的不断发展&#xff0c;网络威胁也愈发复杂和隐匿。在这样的背景下&#xff0c;网络防御变得尤为重要&#xff0c;蓝队作为网络防御的重要一环&#xff0c;起着至关重要的作用。本文将深入探讨网…

libdrm全解析一 —— 总述

本文参考以下博文&#xff1a; Linux libdrm代码完全解析 LIBDRM使用 最简单的DRM应用程序 &#xff08;single-buffer&#xff09; Linux libdrm库入门教程 10. DRM图形显示框架 LIBDRM 特此致谢&#xff01; 一、介绍 BLFS中给出的介绍 libdrm提供了一个用户空间库&…

2023年湖北中级工程师职称申报专业有哪些?甘建二告诉你

中级职称职称申报专业&#xff1a;环境工程、 土木建筑、土建结构、土建监理、土木工程、岩石工程、岩土、土岩方、风景园林、园艺、园林、园林建筑、园林工程、园林绿化、古建筑园林、工民建、工民建安装、建筑、建筑管理、建筑工程、建筑工程管理、建筑施工、建筑设计、建筑装…

36k字从Attention解读Transformer及其在Vision中的应用(附pytorch代码)

文章目录 0.卷积操作1.注意力1.1 注意力概述&#xff08;Attention&#xff09;1.1.1 Encoder-Decoder1.1.2 查询、键和值1.1.3 注意力汇聚&#xff1a; Nadaraya-Watson 核回归 1.2 注意力评分函数1.2.1 加性注意力1.2.2 缩放点积注意力 1.3 自注意力&#xff08;Self-Attenti…

舍不得跳过的广告?900万播放冲上B站热门

8月17日&#xff0c;B站官方公布了2023年第二季度财报。 B站在用户增长方面又创新高&#xff0c;本季度财报显示&#xff0c;B站日均活跃用户达9650万&#xff0c;同比增长15%。用户日均使用时长94分钟&#xff0c;创同期历史新高成为一大亮点。 除此之外&#xff0c;B站还放…