五角钱的程序员 | Kafka 是什么?
本文来源公众号“五角钱的程序员”,仅用于学术分享,侵权删,干货满满。
原文链接:Kafka 是什么?
你是一个程序员,假设你维护了两个服务 A 和 B。B 服务每秒只能处理 100 个消息,但 A 服务却每秒发出 200 个消息,B 服务哪里顶得住,分分钟被压垮。那么问题就来了,有没有办法让 B 在不被压垮的同时,还能处理掉 A 的消息?当然有,没有什么是加一层中间层不能解决的,如果有,那就再加一层。这次我们要加的中间层是 消息队列 Kafka。
Kafka
1 什么是消息队列
为了保护 B 服务,我们很容易想到可以在 B 服务的内存中加入一个队列。
消息队列在B进程里
说白了,它其实是个链表,链表的每个节点就是一个消息。每个节点有一个序号,我们叫它 Offset,记录消息的位置。B 服务依据自己的处理能力,消费链表里的消息。能处理多少是多少,不断更新已处理 Offset 的值。
Offset是什么
但这有个问题,来不及处理的消息会堆积在内存里,如果 B 服务更新重启,这些消息就都丢了。这个好解决,将队列挪出来,变成一个单独的进程。就算 B 服务重启,也不会影响到了队列里的消息。
消息队列单独一个进程
这样一个简陋的队列进程,其实就是所谓的消息队列。而像 A 服务这样负责发数据到消息队列的角色,就是生产者,像 B 服务这样处理消息的角色,就是消费者。
生产者和消费者
但这个消息队列属实过于简陋,像什么高性能,高扩展性,高可用,它是一个都不沾。我们来看下怎么优化它。
2 高性能
B 服务由于性能较差,消息队列里会不断堆积数据,为了提升性能,我们可以扩展更多的消费者, 这样消费速度就上去了,相对的我们就可以增加更多生产者,提升消息队列的吞吐量。
增加生产者和消费者
随着生产者和消费者都变多,我们会发现它们会同时争抢同一个消息队列,抢不到的一方就得等待,这不纯纯浪费时间吗!有解决方案吗?有!首先是对消息进行分类,每一类是一个 topic,然后根据 topic 新增队列的数量,生产者将数据按 topic 投递到不同的队列中,消费者则根据需要订阅不同的 topic。这就大大降低了 topic 队列的压力。
多个topic
但单个 topic 的消息还是可能过多,我们可以将单个队列,拆成好几段,每段就是一个 partition分区,每个消费者负责一个 partition。这就大大降低了争抢,提升了消息队列的性能。
partition
3 高扩展性
随着 partition 变多,如果 partition 都在同一台机器上的话,就会导致单机 cpu 和内存过高,影响整体系统性能。
于是我们可以申请更多的机器,将 partition 分散部署在多台机器上,这每一台机器,就代表一个 broker。我们可以通过增加 broker 缓解机器 cpu 过高带来的性能问题。
broker
4 高可用
到这里,其实还有个问题,如果其中一个 partition 所在的 broker 挂了,那 broker 里所有 partition 的消息就都没了。这高可用还从何谈起?有解决方案吗?有,连你喜欢的女生都知道手机里多聊几个沸羊羊,你却不知道要给 partition 加备胎吗?我们可以给 partition 多加几个副本,也就是 replicas,将它们分为 Leader 和 Follower。Leader 负责应付生产者和消费者的读写请求,而 Follower 只管同步 Leader 的消息。
replicas
将 Leader 和 Follower 分散到不同的 broker 上,这样 Leader 所在的 broker 挂了,也不会影响到 Follower 所在的 broker, 并且还能从 Follower 中选举出一个新的 Leader partition 顶上。这样就保证了消息队列的高可用。
高可用
5 持久化和过期策略
刚刚提到的是几个 broker 挂掉的情况,那搞大点,假设所有 broker 都挂了,那岂不是数据全丢了?为了解决这个问题,我们不能光把数据放内存里,还要持久化到磁盘中,这样哪怕全部 broker 都挂了,数据也不会全丢,重启服务后,也能从磁盘里读出数据,继续工作。
持久化
但问题又来了,磁盘总是有限的,这一直往里写数据迟早有一天得炸。所以我们还可以给数据加上保留策略,也就是所谓的 retention policy
,比如磁盘数据超过一定大小或消息放置超过一定时间就会被清理掉。
6 consumer group
到这里,这个消息队列好像就挺完美了。但其实还有个问题,按现在的消费方式,每次新增的消费者只能跟着最新的消费 Offset 接着消费。如果我想让新增的消费者从某个 Offset 开始消费呢?听起来这个需求很刁钻?我举个例子你就明白了。
哪怕 B 服务有多个实例,但本质上,它只有一个消费业务方,新增实例一般也是接着之前的 offset 继续消费。假设现在来了个新的业务方,C 服务,它想从头开始消费消息队列里的数据,这时候就不能跟在 B 服务的 offset 后边继续消费了。
所以我们还可以给消息队列加入消费者组(consumer group)的概念,B 和 C 服务各自是一个独立的消费者组,不同消费者组维护自己的消费进度,互不打搅。
消费者组互相独立
7 ZooKeeper
相信你也发现了,组件太多了,而且每个组件都有自己的数据和状态,所以还需要有个组件去统一维护这些组件的状态信息,于是我们引入 ZooKeeper 组件。它会定期和 broker 通信,获取 整个 kafka 集群的状态,以此判断 某些 broker 是不是跪了,某些消费组消费到哪了。
加入ZooKeeper
Kafka 是什么
好了,到这里,当初那个简陋的消息队列,就成了一个高性能,高扩展性,高可用,支持持久化的超强消息队列,没错,它就是我们常说的消息队列 Kafka,上面涉及到各种概念,比如 partition 和 broker 什么的,都出自它。
Kafka是什么
kafka 的应用场景
消息队列是架构中最常见的中间件之一,使用场景之多,堪称万金油!比如上游流量忽高忽低,想要削峰填谷,提升 cpu/gpu 利用率,用它。又比如系统过大,消息流向盘根错节,想要拆解组件,降低系统耦合,还是用它。再比如秒杀活动,请求激增,想要保护服务的同时又尽量不影响用户,还得用它。当然,凡事无绝对,方案还得根据实际情况来定,做架构做到最后,都是在做折中。
Kafka的应用场景
总结
-
kafka 是消息队列,像消息队列投递消息的是生产者,消费消息的是消费者。增加生产者和消费者的实例个数可以提升系统吞吐。多个消费者可以组成一个消费者组,不同消费者组维护自己的消费进度,互不打搅。
-
kafka 将消息分为多个 topic,每个 topic 内部拆分为多个 partition,每个 partition 又有自己的副本,不同的 partition 会分布在不同的 broker 上,提升性能的同时,还增加了系统可用性和可扩展性。
THE END !
文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。
相关文章:

五角钱的程序员 | Kafka 是什么?
本文来源公众号“五角钱的程序员”,仅用于学术分享,侵权删,干货满满。 原文链接:Kafka 是什么? 你是一个程序员,假设你维护了两个服务 A 和 B。B 服务每秒只能处理 100 个消息,但 A 服务却每秒…...
C++中合成的默认构造函数的访问权限
问题 我们知道,在C中,如果没有为一个类显式定义构造函数,那么编译器会为我们隐式地定义一个默认构造函数。那么,你有没有想过,这个隐式定义的默认构造函数(合成的默认构造函数)的访问权限是什么…...

【前端】桌面版docker并部署前端项目
环境 win10专业版 2004 , 需科学 官网下载安装包并安装4.29.0版本 终端输入 wsl --installdocker桌面版和模拟器只能选一个,不然一直转圈圈 镜像配置加速,在settings—>docker engine下 {"builder": {"gc": {"defaultKee…...

发布GPT-5的方式可能会与以往不同;开源vocode使用 AI 自动拨打电话;开源gpt智能对话客服工具;AI自动写提示词
✨ 1: vocode 用AI通过声音与用户进行实时交流 Vocode是一个旨在帮助开发者快速构建基于声音的大型语言模型(LLM)应用程序的开源库。简单来说,如果你想要开发一个能够通过声音与用户进行实时交流的应用,比如电话机器人、语音助手…...
Linux 作业管理 (bg, fg, jobs, kill)
bg 和 fg 是用来管理作业(在 Unix/Linux 命令行下运行的进程)的命令。 1. bg 命令 bg 命令用于将作业(job)放到后台运行。当你在终端中运行一个命令或程序时,它会占用当前终端的控制,如果你想让这个任务在…...
springboot Redis 支持星号(*) 包括注解@Cache
通过自定义CacheManager Bean来实现 bean Autowiredprivate RedisConnectionFactory redisConnectionFactory;/*** 管理缓存** return*///缓存管理器PrimaryBeanOverridepublic CacheManager cacheManager() {// 使用自定义的缓存配置初始化一个cacheManagerreturn new Custom…...

2023.5.12 第43周周报
学习时间:2023.5.5-2023.5.12 学习内容: 1、answer question: img: 看到有论文说应该让图像和文本的潜在嵌入具有相似和合理的数值范围【-2,2】 调试发现模型的文本图像的潜在嵌入虽然符合,但相差较大。 在将文本和…...

JavaEE 多线程详细讲解(2)
1.线程不安全分析 (1)线程不安全的主要原因就是,系统的抢占式执行,对于内核设计者来说,这是非常方便的一个执行方式,但是这却却导致线程不安全的问题,也有不抢占执行的系统,但是这种…...

Flask-HTTP请求、响应、上下文、进阶实验
本节主要目录如下: 一、请求响应循环 二、HTTP请求 2.1、请求报文 2.2、Request对象 2.3、在Flask中处理请求 2.4、请求钩子 三、HTTP响应 3.1、响应报文 3.2、在Flask中生成响应 3.3、响应格式 3.4、Cookie 3.5、session:安全的Cookie 四、…...
springboot 设置response和request的默认格式 驼峰或者SNAKE_CASE
springboot 设置response和request的默认格式 驼峰或者SNAKE_CASE。 我们使用默认配置的情况下,response和request是由jackson jason序列化和解析的,因此,我们只需要配置好jackson json的默认格式就可以。 要设置 jackson json默认的更多格式…...

VR全景技术在养老院的应用优势浅析
随着时代的快速发展,人口老龄化越来越严重,如何利用VR技术提升养老服务的质量,成为了社会各界关注的焦点。为养老院拍摄制作VR全景,不仅能够为养老院的老人子女们跨越空间限制,实现与家人的情感连接,还可以…...

[Spring Cloud] (6)gateway整体加解密
文章目录 简述整体效果后端增加配置nacos增加配置GlobalConfig 添加请求整体解密拦截器DecryptionFilter添加响应整体解密拦截器EncryptionFilter 前端请求拦截器添加整体加密逻辑请求头中添加sessionId 响应拦截器添加整体解密逻辑 简述 本文网关gateway,微服务&a…...
RUST编程语言入门基础2024
庄晓立,2024年3月。 Rust简介 A language empowering everyone to build reliable and efficient software. Rust编程语言赋能所有人开发高可靠且高性能的软件。 性能 Rust is blazingly fast and memory-efficient: with no runtime or garbage collector, it can…...

Linux进程控制——Linux进程终止
前言:前面了解完前面的Linux进程基础概念后,我们算是解决了Linux进程中的一大麻烦,现在我们准备更深入的了解Linux进程——Linux进程控制! 我们主要介绍的Linux进程控制内容包括:进程终止,进程等待与替换&a…...

利用IP地址查询解决被“薅羊毛”的方法
在互联网时代,随着各种网络诈骗手段的不断更新和演变,“薅羊毛”成为了一种常见的网络犯罪行为。其中,利用查询IP地址进行欺诈活动已经成为一种普遍的手段。当个人或组织的IP地址被不法分子查询后,可能会面临虚假注册、盗取个人信…...

Tomcat7+ 弱口令 后台getshell漏洞
1 漏洞背景 Tomcat 是一个流行的开源Web应用服务器,用于部署和运行Java Web应用程序。Tomcat 7 版本中存在一个安全隐患,即默认的管理员密码可能较弱或者未被修改,攻击者可以利用这一漏洞登录到Tomcat的管理后台,并上传恶意的WAR…...

香港虚拟主机哪里可以试用?用于企业建站的
香港虚拟主机适合个人、企业建站,包括外贸企业网站、个人博客网站、中小企业官网等,那么作为新手不知道哪家香港虚拟主机好用的时候,该如何找到可以试用的香港虚拟主机呢? 香港虚拟主机也称作香港空间、香港虚拟空间,…...
C# 集合(四) —— Set类
总目录 C# 语法总目录 集合四 Set 1. Set 1. Set 有 HashSet 和 SortedSet, 它们都不包含重复元素忽略添加重复值的请求无法根据位置访问元素使用Contains方法均使用散列查找,所以速度快 SortedSet 按照一定顺序保存元素,使用红黑树实现&a…...

C#实现多线程的几种方式
前言 多线程是C#中一个重要的概念,多线程指的是在同一进程中同时运行多个线程的机制。多线程适用于需要提高系统并发性、吞吐量和响应速度的场景,可以充分利用多核处理器和系统资源,提高应用程序的性能和效率。 多线程常用场景 CPU 密集型任务…...

C语言—控制语句
控制语句就是用来实现对流程的选择、循环、转向和返回等控制行为。 分支语句 if语句 基本结构 if(表达式) { 语句块1; } else { 语句块2; } 执行顺序: 如果表达式判断成立(即表达式为真),则执行语句块…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...