![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
系统性能调优
文章平均质量分 94
系统性能调优
_Rye_
左手代码右手诗
一行代码一行诗
展开
-
深入剖析HTTP/3协议
自 2017 年起,HTTP/3 协议已发布了 29 个 Draft,推出在即,Chrome、Nginx 等软件都在跟进实现最新的草案。那它带来了哪些变革呢?我们结合 HTTP/2 协议看一下。2015 年,HTTP/2 协议正式推出后,已经有接近一半的互联网站点在使用它:HTTP/2 协议虽然大幅提升了 HTTP/1.1 的性能,然而,基于 TCP 实现的 HTTP/2 遗留下 3 个问题:有序字节流引出的),使得 HTTP/2 的多路复用能力大打折扣;,建链时长还有 1 倍的下降空间;原创 2024-01-23 11:13:28 · 1288 阅读 · 1 评论 -
分布式系统的本质是什么?
假如以你所在的团队中对重大技术升级的频率来作为参考的话,做可供 2 个升级周期的设计,花一个升级周期的时间先实现第一阶段,下个阶段可以选择直接实现剩下的部分,也可继续进行 2 个升级周期设计,开启一个循环,持续迭代,并且不断修正方向以更贴近现实的发展,就如下图这样。比如,大部分的飞机和直升机的发动机都是偶数的,汽车中的电子控制系统的冗余机制等。人们发现,用廉价机器的集合组成的分布式系统,除了可以获得超过 CPU 发展速度的性能外,花费更低,具有更好的性价比,并且还可以根据需要增加或者减少所需机器的数量。原创 2024-01-23 10:44:21 · 817 阅读 · 0 评论 -
如何理解分布式系统?
咱们目前正在学习的这一模块叫“分布式系统优化”,讲了监控、CAP、负载均衡、一致性哈希,说实话,这些知识都不简单,你如果觉得有点难,那也别气馁,因为它确实得多琢磨,一开始学习的时候也是这样。不过,在这个模块中,很多同学似乎对分布式有什么误解,有的人说分布式就是多台机器,有的人说分布式就是微服务,总之,大家各有自己的理解。于是,就想着来系统聊聊这个话题。如果现在让你阐述一下什么是“分布式系统”,你脑子里第一下跳出来的是什么?原创 2024-01-23 10:03:56 · 941 阅读 · 0 评论 -
那些年,影响我们达到性能巅峰的常见绊脚石(下)
结合上一期的分享,我们一共总结了 7 种常见“绊脚石”及其应对策略,那通过了解它们,我们是否就有十足的信心能达到性能巅峰了呢?其实在实践中,我们往往还是很难的,特别是当前微服务大行其道,决定我们系统性能的因素往往是下游微服务,而下游微服务可能来源于不同的团队或组织。这时,已经不再单纯是技术本身的问题了,而是沟通、协调甚至是制度等问题。原创 2024-01-22 21:12:15 · 868 阅读 · 0 评论 -
那些年,影响我们达到性能巅峰的常见绊脚石(上)
其实说起性能调优,我们往往有很多理论依据可以参考,例如针对分布式系统的 NWR、CAP 等,也有很多实践的“套路”,如绘制火焰图、监控调用链等。当然,这些内容多多少少陶辉老师都有讲到。实际上,不管方式、方法有多少,我们的终极目标都是一致的,那就是在固定的资源条件下,将系统的响应速度调整到极致。但是在严谨地评价一个系统性能时,我们很少粗略地使用这种表述:在压力 A(如 1000 TPS)下,基于软硬件配置 B,我们应用的 C 操作响应时间是 D 毫秒。原创 2024-01-22 20:28:41 · 779 阅读 · 0 评论 -
百万并发下Nginx的优化之道
还可以提高硬件资源的利用效率,比如当你在 listen 指令后加入 defer 选项后,就使用了 TCP_DEFER_ACCEPT 功能,这样 epoll_wait 并不会返回仅完成三次握手的连接,只有连接上接收到的 TCP 数据报文后,它才会返回 socket,这样 Worker 进程就将原本 2 次切换就降为 1 次了,虽然会牺牲一些即时性,但提高了 CPU 的效率。Nginx 将其改到进程内部,由 epoll 切换 ngx_connection_t 连接的处理,成本会非常低。原创 2024-01-22 19:01:24 · 1584 阅读 · 0 评论 -
与程序员相关的SSD性能知识
各种存储系统的基础是传统硬盘或者固态硬盘,固态硬盘 SSD 的 IO 性能比传统硬盘高很多。如果系统对 IOPS 或者延迟要求很高,一般都采用 SSD。现在已经有很多专门针对 SSD 来设计的文件系统、数据库系统和数据基础架构,它们的性能比使用 HDD 的系统都有了很大的提升。SSD 有不同于 HDD 工作原理,所以在进行应用程序设计的时候,如果可以做到对 SSD 友好,那么就可以充分发挥 SSD 的全部性能潜能,应用程序的性能会进一步提高。你可以参考我们今天总结的四个设计原则进行实践。原创 2024-01-22 18:34:09 · 881 阅读 · 0 评论 -
高并发场景下如何优化微服务的性能?
把“基础设施优化”这一部分中讲到的一些抽象的概念和方法,用举例子的方式来梳理一遍。总结下的话,就是帮你理清这些问题:线程到底是如何在 CPU 中执行的?线程上下文切换为什么会影响性能?为什么说异步比同步的性能好?BIO、NIO、AIO 到底有什么区别?原创 2024-01-22 18:05:20 · 1166 阅读 · 0 评论 -
大厂面试到底在考些什么?
相信绝大多数同学都经历过技术面试,你肯定发现,小厂与大厂的面试题差距很大,其中,大厂特别关注程序性能,为什么呢?在我看来有这样 3 个原因:首先,大厂产品的用户基数大,任何微小的性能提升都会被庞大的用户数放大。因此,员工具备性能优先的思维,有利于提升产品竞争力。其次,大厂经常会重新造轮子,不管原因是什么,造轮子都需要深厚的底层知识,而性能是其中的核心要素。而且,愿意花时间去掌握底层知识的候选人,学习动力更强,潜力也会更好。最后,大厂待遇好,成长空间大,是典型的稀缺资源,大家都打破了头往里挤。原创 2024-01-22 17:44:42 · 842 阅读 · 0 评论 -
30 | 如何权衡关系数据库与NoSQL数据库?
由于不同的数据间具有了关系,关系数据库还提供了“原创 2024-01-22 17:14:41 · 827 阅读 · 0 评论 -
29 | 流式计算:如何通过集群实现实时计算?
上节课我们介绍了在有边界的存量数据上进行的 MapReduce 离线计算,这节课我们来看看对于无边界数据,怎样实时地完成流式计算。对于不再变化的存量数据,可以通过分而治之的 MapReduce 技术将数据划分到多台主机上并行计算,由于待处理的数据量很大,我们只能获得分钟级以上的时延。当面对持续实时产生动态数据的场景时,业务上通常需要在秒级时延中及时地拿到运算结果。比如,商家为了拉新促活,会为特定的用户群体(比如新用户或者不活跃用户)推出优惠活动,为了防止“羊毛党”通过大量主机并行地“原创 2024-01-22 16:38:48 · 874 阅读 · 0 评论 -
28 | MapReduce:如何通过集群实现离线计算?
接下来的 2 节将介绍如何通过分布式集群优化计算任务。这一讲我们首先来看对于有边界静态数据的离线计算,下一讲再来看对无边界数据流的实时计算。对大量数据做计算时,我们通常会采用分而治之的策略提升计算速度。比如单机上基于递归、分治思想实现的快速排序、堆排序,时间复杂度只有 O(N*logN),这比在原始数据集上工作的插入排序、冒泡排序要快得多(O())。然而,当单机磁盘容量无法存放全部数据,或者受限于 CPU 频率、核心数量,单机的计算时间远大于可接受范围时,我们就需要在分布式集群上使用分治策略。原创 2024-01-22 16:07:34 · 1101 阅读 · 0 评论 -
27 | 消息队列:如何基于异步消息提升性能?
在前 26 讲中我们介绍了许多异步实现机制,这节课我们来看看如何通过提升分布式系统的性能。异步通讯是最常用的性能提升方式,比如 gRPC 提供的异步 API,或者基于 write-back 模式向缓存写入数据时,系统性能都可以提高。然而,对于复杂的大规模分布式系统,这些分散、孤立的异步实现机制,无法解决以下问题:组件间耦合在一起,不只迭代变更时更为困难,而且当它们之间的性能有差异时,吞吐量较低的组件就会成为系统瓶颈;当业务在时间上具有明显的峰谷访问差异时,实现需要一定的开发成本;原创 2024-01-22 15:20:35 · 1541 阅读 · 0 评论 -
26 | 应用层多播:如何快速地分发内容?
第 7 讲] 我们曾介绍了网络层的 IP 协议是如何支持多播的,这节课我们再来从应用层看看如何实现多播功能。当你的分布式集群只有十多个节点时,每次发布版本时,尽可以从发布服务器,将新版本的安装包通过 ftp、scp、wget 等工具分发到各个节点中。可是,一旦集群规模达到成千上万个节点时,再这么做就会带来很大的问题,文件分发的时长高达几个小时,甚至会打挂文件源终止分发流程。在微服务环境中这点尤为明显, 毕竟每个 Docker 镜象的体积动辄就在数百兆字节以上。原创 2024-01-22 14:26:43 · 877 阅读 · 0 评论 -
25 | 过期缓存:如何防止缓存被流量打穿?
这一讲我们将对一直零散介绍的缓存做个全面的总结,同时讨论如何解决缓存被流量打穿的场景。在分布式系统中,缓存无处不在。比如,浏览器会缓存用户 Cookie,CDN 会缓存图片,负载均衡会缓存 TLS 的握手信息,Redis 会缓存用户的 session,MySQL 会缓存 select 查询出的行数据,HTTP/2 会用动态表缓存传输过的 HTTP 头部,TCP Socket Buffer 会缓存 TCP 报文,Page Cache 会缓存磁盘 IO,CPU 会缓存主存上的数据,等等。原创 2024-01-22 10:30:23 · 888 阅读 · 0 评论 -
24 | 一致性哈希:如何高效地均衡负载?
还记得我们在[第 22 讲] 谈到的 Cassandra 数据库吗?它将服务器节点组成一个环来存储数据,所使用的就是一致性哈希算法。那这一讲,我们就来看看一致性哈希算法是怎样工作的。使用哈希算法扩展系统时,最大的问题在于代表哈希桶的服务器节点数发生变化时,哈希函数就改变了,数据与节点间的映射关系自然发生了变化,结果大量数据就得在服务器间迁移。特别是含有多份冗余数据的系统,迁移工作量更是会成倍提高。原创 2024-01-22 09:58:29 · 852 阅读 · 0 评论 -
23 | 负载均衡:选择Nginx还是OpenResty?
在[第 21 讲] 介绍 AKF 立方体时,我们讲过只有在下游添加负载均衡后,才能沿着 X、Y、Z 三个轴提升性能。这一讲,我们将介绍最流行的负载均衡 Nginx、OpenResty,看看它们是如何支持 AKF 扩展体系的。负载均衡通过将流量分发给新增的服务器,提升了系统的性能。因此,我们对负载均衡最基本的要求,就是它的吞吐量要远大于上游的应用服务器,否则扩展能力会极为有限。因此,目前性能最好的 Nginx,以及在 Nginx 之上构建的 OpenResty,通常是第一选择。原创 2024-01-22 09:08:05 · 3483 阅读 · 0 评论 -
22 | NWR算法:如何修改读写模型以提升性能?
前两讲我们介绍数据库的扩展时,写请求仍然在操作中心化的 Master 单点,这在很多业务场景下都是不可接受的。这一讲我将介绍对于无单点的去中心化系统非常有用的 NWR 算法,它可以灵活地平衡一致性与性能。最初我们仅在单机上部署数据库,一旦性能到达瓶颈,我们可以基于 AKF Y 轴将读写分离,这样多个 Slave 从库将读操作分流后,写操作就可以独享 Master 主库的全部性能。然而主库作为中心化的单点,一旦宕机,未及时同步到从库的数据就有可能丢失。而且,这一架构下,主库的故障还会导致整个系统瘫痪。去中心化原创 2024-01-19 23:00:58 · 827 阅读 · 0 评论 -
21 | AKF立方体:怎样通过可扩展性来提高性能?
上一讲我们谈到,调低一致性可以提升有状态服务的性能。这一讲我们扩大范围,结合无状态服务,看看怎样提高分布式系统的整体性能。当你接收到运维系统的短信告警,得知系统性能即将达到瓶颈,或者会议上收到老板兴奋的通知,接下来市场开缰拓土,业务访问量将要上一个大台阶时,一定会马上拿起计算器,算算要加多少台机器,系统才能扛得住新增的流量。然而,有些服务虽然可以通过加机器提升性能,但可能你加了一倍的服务器,却发现系统的吞吐量没有翻一倍。甚至有些服务无论你如何扩容,性能都没有半点提升。原创 2024-01-19 20:33:34 · 971 阅读 · 0 评论 -
20 | CAP理论:怎样舍弃一致性去换取性能?
如下图所示:write through 的一致性非常好,它常常是我们的首选设计。然而,一旦缓存到源数据的路径很长、延时很高的时候,就值得考虑 write back 模式,此时一致性模型虽然复杂了许多,但可以带来显著的性能提升。比如机械磁盘相对内存延时高了很多,因此磁盘高速缓存会采用 write back 模式。虽然缓存也可以在一定程度上增加系统的并发处理连接,但这更多是缘于缓存采用了更快的算法以及存储介质带来的收益。原创 2024-01-19 17:25:12 · 867 阅读 · 0 评论 -
19 | 如何通过监控找到性能瓶颈?
从这一讲开始,我们将进入分布式系统层面,站在更宏观的角度去探讨系统性能的优化。如果优化系统性能时,只是依据自己的经验,对感觉存在性能提升空间的代码,无一例外地做一遍优化,这既是一件事倍功半的事,也很容易遗漏下关键的优化点,无法大幅提升系统的性能。根据帕累托法则(也叫二八定律),然而,找到性能瓶颈却不是一件容易的事。我们通常会采用各种监控手段来发现性能瓶颈,但这一讲,我将介绍 2 个简单而又行之有效的方案,分别从微观上快速地找出进程内的瓶颈函数,以及从宏观上找出整个分布式系统中的瓶颈组件。原创 2024-01-19 16:52:51 · 848 阅读 · 0 评论 -
答疑精选:这些问题你都清楚吗?
1. 这段话的上下文,是指单次获取网络事件时,可以理解为调用 epoll_wait 系统调用,它的速度与并发连接总数无关,相对于之前的 select/poll 系统调用(它们都与并发连接总数相关),因此 epoll_wait 速度很快,这是实现高吞吐量的关键。”这里的逻辑无法理解。我们集群有一个问题,某一台物理机的 CPU 会被 Hadoop yarn 的查询任务打满,并且占用最多的 pid 在不停的变化,我查看了 TIME_WAIT 的个数好像也不是很多,在顶峰的时候还没达到一万,能够持续一两个小时。原创 2024-01-19 16:32:23 · 330 阅读 · 0 评论 -
18 | 如何通过gRPC实现高效远程过程调用?
这一讲我们将以一个实战案例,基于前两讲提到的 HTTP/2 和 ProtoBuf 协议,看看 gRPC 如何将结构化消息编码为网络报文。直接操作网络协议编程,容易让业务开发过程陷入复杂的网络处理细节。RPC 框架以编程语言中的本地函数调用形式,向应用开发者提供网络访问能力,这既封装了消息的编解码,也通过线程模型封装了多路复用,对业务开发很友好。原创 2024-01-19 15:52:27 · 1088 阅读 · 0 评论 -
17 | Protobuf是如何进一步提高编码效率的?
上一讲介绍的 HTTP/2 协议在编码上拥有非常高的空间利用率,这一讲我们看看,相比其中的 HPACK 编码技术,Protobuf 又是通过哪些新招式进一步提升编码效率的。Google 在 2008 年推出的 Protobuf,是一个针对具体编程语言的编解码工具。它面向 Windows、Linux 等多种平台,也支持 Java、Python、Golang、C++、Javascript 等多种面向对象编程语言。原创 2024-01-19 15:17:20 · 1113 阅读 · 0 评论 -
16 | HTTP/2是怎样提升性能的?
上一讲我们从多个角度优化 HTTP/1 的性能,但获得的收益都较为有限,而直接将其升级到兼容 HTTP/1 的 HTTP/2 协议,性能会获得非常大的提升。HTTP/2 协议既降低了传输时延也提升了并发性,已经被主流站点广泛使用。多数 HTTP 头部都可以被压缩 90% 以上的体积,这节约了带宽也提升了用户体验,像 Google 的高性能协议 gRPC 也是基于 HTTP/2 协议实现的。原创 2024-01-19 14:45:22 · 1089 阅读 · 0 评论 -
15 | 如何提升HTTP/1.1性能?
上一讲介绍了为应用层信息安全保驾护航的 TLS/SSL 协议,这一讲我们来看看最常用的应用层协议 HTTP/1.1 该如何优化。由于门槛低、易监控、自表达等特点,HTTP/1.1 在互联网诞生之初就成为最广泛使用的应用层协议。然而它的性能却很差,最为人诟病的是 HTTP 头部的传输占用了大量带宽。由于 HTTP 头部使用 ASCII 编码方式,这造成它往往达到几 KB,而且滥用的 Cookie 头部进一步增大了体积。原创 2024-01-19 11:47:59 · 922 阅读 · 0 评论 -
14 | 优化TLS/SSL性能该从何下手?
从这一讲开始,我们进入应用层协议的处理。信息安全在当下越来越重要,绝大多数站点访问时都使用 https:// 替代了 http://,这就是在用 TLS/SSL 协议(下文简称为 TLS 协议)来保障应用层消息的安全。但另一方面,你会发现很多图片类门户网站,还在使用 http://,这是因为 TLS 协议在对信息加解密的同时,必然会降低性能和用户体验,这些站点在权衡后选择了性能优先。实际上,TLS 协议由一系列加密算法及规范组成,这些算法的安全性和性能各不相同,甚至与你的系统硬件相关。原创 2024-01-19 11:10:56 · 1096 阅读 · 0 评论 -
13 | 实战:单机如何实现管理百万主机的心跳服务?
这一讲我们将结合前 12 讲,以一个可管理百万主机集群的心跳服务作为实战案例,看看所有高性能服务的设计思路。首先解释下什么是心跳服务。集群中的主机如果宕机,那么管理服务必须及时发现,并做相应的容灾处理,比如将宕机主机的业务迁移到新的虚拟机上等等。怎么做到及时发现呢?可以要求每台主机定时上报心跳包,考虑到网络报文的延迟,如果管理服务在几个上报周期内未收到心跳,则认为主机宕机。当新主机加入集群后,心跳服务也可以及时识别并告知管理服务。原创 2024-01-19 10:33:24 · 844 阅读 · 0 评论 -
12 | 如何调整TCP拥塞控制的性能?
上一讲我们谈到接收主机的处理能力不足时,是通过滑动窗口来减缓对方的发送速度。这一讲我们来看看,当网络处理能力不足时又该如何优化 TCP 的性能。如果你阅读过 TCP 协议相关的书籍,一定看到过慢启动、拥塞控制等名词。这些概念似乎离应用开发者很远,然而,如果没有拥塞控制,整个网络将会锁死,所有消息都无法传输。而且,如果你在开发分布式集群中的高并发服务,理解拥塞控制的工作原理,就可以在内核的 TCP 层,提升所有进程的网络性能。原创 2024-01-19 09:24:20 · 1023 阅读 · 0 评论 -
11 | 如何修改TCP缓冲区才能兼顾并发数量与传输速度?
我们在[第 8 课] 中讲了如何从 C10K 进一步到 C10M,不过,这也意味着 TCP 占用的内存翻了一千倍,服务器的内存资源会非常紧张。如果你在 Linux 系统中用 free 命令查看内存占用情况,会发现一栏叫做 buff/cache,它是系统内存,似乎与应用进程无关。但每当进程新建一个 TCP 连接,buff/cache 中的内存都会上升 4K 左右。而且,当连接传输数据时,就远不止增加 4K 内存了。这样,几十万并发连接,就在进程内存外又增加了 GB 级别的系统内存消耗。原创 2024-01-18 17:23:16 · 1901 阅读 · 0 评论 -
10 | 如何提升TCP四次挥手的性能?
上一节,我们介绍了建立连接时的优化方法,这一节课再来看四次挥手关闭连接时,如何优化性能。close 和 shutdown 函数都可以关闭连接,但这两种方式关闭的连接,不只功能上有差异,控制它们的 Linux 参数也不相同。close 函数会让连接变为孤儿连接,shutdown 函数则允许在半关闭的连接上长时间传输数据。TCP 之所以具备这个功能,是因为它是全双工协议,但这也造成四次挥手非常复杂。四次挥手中你可以用 netstat 命令观察到 6 种状态。其中,你多半看到过 TIME_WAIT 状态。原创 2024-01-18 16:46:54 · 848 阅读 · 0 评论 -
09 | 如何提升TCP三次握手的性能?
上一讲我们提到 TCP 在三次握手建立连接、四次握手关闭连接时是怎样产生事件的,这两个过程中 TCP 连接经历了复杂的状态变化,既容易导致编程出错,也有很大的优化空间。这一讲我们看看在 Linux 操作系统下,如何优化 TCP 的三次握手流程,提升握手速度。TCP 是一个可以双向传输的全双工协议,所以需要经过三次握手才能建立连接。原创 2024-01-18 16:09:20 · 954 阅读 · 0 评论 -
08 | 事件驱动:C10M是如何实现的?
上一讲介绍了广播与组播这种一对多通讯方式,从这一讲开始,我们回到主流的一对一通讯方式。早些年我们谈到高并发,总是会提到 C10K,这是指服务器同时处理 1 万个 TCP 连接。随着服务器性能的提升,近来我们更希望单台服务器的并发能力可以达到 C10M,也就是同时可以处理 1 千万个 TCP 连接。从 C10K 到 C10M,实现技术并没有本质变化,都是用事件驱动和异步开发实现的。[第 5 讲] 介绍过的协程,也是依赖这二者实现高并发的。原创 2024-01-18 14:45:27 · 903 阅读 · 0 评论 -
07 | 性能好,效率高的一对多通讯该如何实现?
从这一讲开始,我们将从单机进入网络层面的性能优化。我们接触过的绝大多数通讯方式,无论是面向连接的 HTTP 协议,还是无连接的 DNS 协议,都是一对一收发消息的。其实,除了一对一,还有一对多的通讯方式,它在网络资源的利用上效率要比一对一高得多。这种一对多的通讯方式,在局域网中有很广泛的应用,常见的 ARP 欺骗、泛洪攻击等,都是通过一对多通讯进行的。当应用场景中用一对多代替一对一通讯时,发送方性能会获得很大的提升,整个局域网的效率也会提高。原创 2024-01-18 09:47:50 · 1214 阅读 · 0 评论 -
06 | 锁:如何根据业务场景选择合适的锁?
上一讲我们谈到了实现高并发的不同方案,这一讲我们来谈谈如何根据业务场景选择合适的锁。我们知道,多线程下为了确保数据不会出错,必须加锁后才能访问共享资源。我们最常用的是互斥锁,然而,还有很多种不同的锁,比如自旋锁、读写锁等等,它们分别适用于不同的场景。比如高并发场景下,要求每个函数的执行时间必须都足够得短,这样所有请求才能及时得到响应,如果你选择了错误的锁,数万请求同时争抢下,很容易导致大量请求长期取不到锁而处理超时,系统吞吐量始终维持在很低的水平,用户体验非常差,最终“高并发”成了一句空谈。原创 2024-01-17 19:14:30 · 943 阅读 · 0 评论 -
05 | 协程:如何快速地实现高并发服务?
上一讲谈到,零拷贝通过减少上下文切换次数,提升了文件传输的性能。事实上高并发服务也是通过降低切换成本实现的,这一讲我们来看看它是如何做到的。如果你需要访问多个服务来完成一个请求的处理,比如实现文件上传功能时,首先访问 Redis 缓存,验证用户是否登陆,再接收 HTTP 消息中的 body 并保存在磁盘上,最后把文件路径等信息写入 MySQL 数据库中,你会怎么做?原创 2024-01-17 14:41:59 · 971 阅读 · 0 评论 -
04 | 零拷贝:如何高效地传输文件?
上一讲我们谈到,当索引的大小超过内存时,就会用磁盘存放索引。磁盘的读写速度远慢于内存,所以才针对磁盘设计了减少读写次数的 B 树索引。因此,针对磁盘的优化技术层出不穷,比如零拷贝、直接 IO、异步 IO 等等。这些优化技术为了降低操作时延、提升系统的吞吐量,围绕着内核中的磁盘高速缓存(也叫 PageCache),去减少 CPU 和磁盘设备的工作量。这些磁盘优化技术和策略虽然很有效,但是理解它们并不容易。只有搞懂内核操作磁盘的流程,灵活正确地使用,才能有效地优化磁盘性能。原创 2024-01-17 10:14:36 · 958 阅读 · 0 评论 -
03 | 索引:如何用哈希表管理亿级对象?
上一讲我们谈到,Ptmalloc2 为子线程预分配了 64MB 内存池,虽然增大了内存消耗,但却加快了分配速度,这就是的思想。在内存有限的单片机上运行嵌入式程序时,我们会压缩数据的空间占用,;但在面向海量用户的分布式服务中,,则是我们管理大数据的常用手段。比如现在需要管理数亿条数据,每条数据上有许多状态,有些请求在查询这些状态,有些请求则会根据业务规则有条件地更新状态,有些请求会新增数据,每条数据几十到几百字节。如果需要提供微秒级的访问速度,该怎么实现?原创 2024-01-17 09:17:20 · 901 阅读 · 0 评论 -
02 | 内存池:如何提升内存分配的效率?
上一讲我们提到,高频地命中 CPU 缓存可以提升性能。这一讲我们把关注点从 CPU 转移到内存,看看如何提升内存分配的效率。或许有同学会认为,我又不写底层框架,内存分配也依赖虚拟机,并不需要应用开发者了解。如果你也这么认为,我们不妨看看这个例子:在 Linux 系统中,用 Xmx 设置 JVM 的最大堆内存为 8GB,但在近百个并发线程下,观察到 Java 进程占用了 14GB 的内存。为什么会这样呢?原创 2024-01-16 18:33:20 · 1030 阅读 · 0 评论 -
01 | CPU缓存:怎样写代码能够让CPU执行得更快?
我们先从主机最重要的部件 CPU 开始,聊聊如何通过提升 CPU 缓存的命中率来优化程序的性能。任何代码的执行都依赖 CPU,通常,使用好 CPU 是操作系统内核的工作。然而,当我们编写计算密集型的程序时,CPU 的执行效率就开始变得至关重要。由于 CPU 缓存由更快的 SRAM 构成(内存是由 DRAM 构成的),而且离 CPU 核心更近,如果运算时需要的输入数据是从 CPU 缓存,而不是内存中读取时,运算速度就会快很多。所以,了解 CPU 缓存对性能的影响,便能够更有效地编写我们的代码,优化程序性能。原创 2024-01-16 17:36:59 · 852 阅读 · 0 评论