五角钱的程序员 | 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; } 执行顺序: 如果表达式判断成立(即表达式为真),则执行语句块…...

三. TensorRT基础入门-ONNX注册算子的方法
目录 前言0. 简述1. 执行一下我们的python程序2.转换swin-tiny时候出现的不兼容op的例子3. 当出现导出onnx不成功的时候,我们需要考虑的事情4. unsupported asinh算子5. unsupported deformable conv算子总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战…...

01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?
声明:本教程不收取任何费用,欢迎转载,尊重作者劳动成果,不得用于商业用途,侵权必究!!! 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…...

答题套路2 阅读理解 说明文某个词是否能去掉
观点 回答:不能 解词 某个词什么意思需要解释一下 反证法 如果去掉了,会怎么样 总结 使用这个词体现了说明文的科学性,严谨性...

Pytorch图像分类模型模型实时在线验证代码
1.训练并保存自己的模型 保存的模型格式为:XXX.pth torch.save(model, "./weight/last.pth")if best_acc <(validation_acc / len_val):torch.save(model, "./weight/best.pth")2.转化为ONNX格式 2.1环境安装(window10&#x…...

Java高并发场景(银行转账问题)
最近面试问到了银行转账的高并发问题,回答的不是很理想,小编整理了下,题目大概如下: 有一张银行账号表(银行账号字段、金额字段),A账号要给B账号转账,A扣款,B收款&#x…...

TypeScript 工具类型
这些工具类型是 TypeScript 提供的强大功能,用于操作和转换类型。下面是每个工具类型的简要说明和示例: 1、Record let value: Record<string, any> { name: "", age: 0, desc: [] }; let value2: { [key: string]: any } { name: &…...

[Kotlin]创建一个私有包并使用
1.创建Kotlin测试项目 在Android Studio或其他IDE中选择“Create New Project”。选择Kotlin和Gradle作为项目类型和构建系统。指定项目名称和位置,完成设置。 2.创建Android Library模块 官方文档:创建 Android 库 | Android Studio | Android De…...

鸿蒙应用开发者高级认证指南及参考资料整理(含详细参考答案)
如何报名鸿蒙应用开发者高级认证 报名链接:点击这里进行报名。报名步骤: 点击上述链接进入报名页面。选择“立即报名”。在课程内容中找到“HarmonyOS应用开发者高级认证”,点击进入。点击“参加考试”,随后即可开始考试。考试注意事项 实名认证:考试前,请务必完成实名认…...

数据匿名化技术
不同的数据匿名化技术可用于多种行业,旨在从数据流中获取有用的见解,同时确保满足数据保护标准和法规的合规要求。 数据脱敏(Data Masking) 数据脱敏,又称数据漂白、数据去隐私化或数据变形,指的是对数据集…...

HTML学习笔记汇总
整理一些常见问题的Links,不定期更新。 Html生成自定义函数的图形(2024/5/10)-CSDN博客 HTML中插入图片(2024/5/10)-CSDN博客 Html给网页加icon图标_html icon-CSDN博客...