阿里内部性能优化方法论
《阿里内部性能优化方法论》共 0.5 万字,通篇围绕 缓存、架构、数据库、日志 展开,归在「推理、部署与算力」这一层。
适合要把模型跑起来,还得跑得起的人
目录骨架(8 节)
- 性能优化的根本目的是什么?
- 出现性能问题的主要原因
- 性能优化的核心环节
- 寻找性能瓶颈
- 增加资源
- 减少耗时操作
- 提高资源利用率
- 增加机器
分享内容
- 性能优化的本质
- 性能优化的核心思想(增加资源、减少耗时操作、提高资源利用率)
- 总结
一、性能优化的本质
性能优化的根本目的是什么?
可能很多人没有认真思考过:“为什么我们需要进行性能优化?”这个问题。
在我看来,性能优化是为了”解决良好的用户体验和资源的有限性之间的矛盾”。
首先,我们性能优化一般都是追求更快的响应速度,通常最终目的是为了获得更好的用户体验。
这里所说的资源是指广义上的资源,“资源的有限性”包括:资金成本的有限性,人力资源的有限性,服务器等硬件资源的有限性,时间的有限性等。
如果资源是无限的,如开发周期很长,投入的人力很多,服务器资源充足,甚至服务器内存是无限大的,那么设计出来的产品可能就不需要花费太多精力去优化。
出现性能问题的主要原因
通常,产品发布早期由于用户量较少,不太容易出现性能问题或者通常不会太去关注性能问题;但随着业务的不断发展,性能问题就逐渐暴露出来。
导致性能问题的原因有很多,常见的原因有:
- 项目工期紧张,设计阶段技术方案考虑不充分;
- 项目中使用了不合理的数据结构或算法;
- 系统架构设计不合理;
- 同步执行耗时任务;
- …
性能优化的核心环节
不知道大家有没有深入思考过,我们平时写代码到底在写什么? 可能有些人会调侃地说:“无非就是 CURD”。
其实我们编码都是围绕着输入、处理和输出三个主要环节展开的。

因此,性能优化也要着重从这三点进行考虑。
如考虑如何更快地查询出数据,更快地对数据进行处理,更快地传输数据等。 通常来说,处理部分是其中最核心的环节,也是优化的重点。
寻找性能瓶颈
性能优化的前提是要找到性能瓶颈,通常需要通过自测、压测、耗时告警日志、数据库慢查询日志、调用链路追踪技术等手段,发现性能瓶颈。
通常在实际开发中,某个接口的响应时间过长影响用户体验,如果条件允许,就要考虑优化。
通常 2C 的业务更关注性能优化,2B 的业务相较于 2C 的业务通常来说性能问题只要不是太严重, 通常没那么紧迫。
产生性能瓶颈的原因有很多,如使用的算法时间复杂度较高、数据库查询语句没有覆盖到索引、调用链路过长等。
二、性能优化的核心思想
首先,建议大家采用先猜想后验证的方式进行学习。即看到下面标题或者文章目录时,先猜想一下该标题下大概会包括哪些案例,然后和给出的条目进行对比,学习效果更好。
增加资源
增加机器
比如由单个 WEB 服务器来响应用户请求,改为通过 Nginx 等负载均衡工具将请求分发到多台服务器。

这就相当于原本店铺里只有一个服务员,一个服务员同时只能接待 5 位客人,现在又多招聘几个服务员,这样能够同时接待顾客数量会更多一些。

或者为集群添加更多机器。

通常很多站点都会在某些大型活动(如限时秒杀、微博热帖、高考查成绩、热门直播等)前或过程中,通过手动或者自动”扩容” 增加更多机器的方式来支撑更多流量。
升级配置
增加配置,通常是更换性能更好的 CPU、增加内存、增加宽带、使用固态硬盘、增加磁盘空间等。下图为阿里云购买服务器页面的截图,其中的选项就是配置相关的关键指标。

减少耗时操作
要提高性能,通常需要减少操作的耗时。想要减少耗时,就要了解常见传输媒介的耗时情况。 下图为各种操作的时间量级参考表:

图片来源:《性能之巅》
这张图是我们后续很多性能优化方法的主要依据。
合并操作(化零为整)
合并操作是性能优化非常典型和重要的思想。
比如渲染某个前端页面,前端需要请求多个 js 文件,可以将多个 js 文件合并成一个,来减少向服务端发起请求的次数。
比如后端服务在某个请求中需要构造不同的请求,多次调用同一个二方接口,此时,可以使用批量查询接口,而不是 for 循环中执行单个请求再去处理。
如下图所示,某个功能,需要在循环中请求十几次甚至几十次二方或者三方接口:

假设每次耗时 100ms, 请求 20 次,就是 2 秒钟。
如下图所示,可以通过调用批量接口,发起一次网络请求获取十几条数据或者几十条数据:

同样的功能,可能 100 ms 更多一点就搞定了。很多中间件在设计时,也会提供一些批量接口。比如 Redis 中的 mget 命令,可以批量获取 key 的值;ES 中也提供了 mget 批量查询 api。
大家都知道 IO 操作通常和读写内存、CPU 缓存等相比非常耗时,如果想进行性能优化,就要考虑减少 IO 操作。
