一个老调优师的工作笔记
十年调优经验沉淀下来的不是参数表,而是几种判断力:什么时候该调,什么时候不该调,什么时候该换思路。一份带脾气的随笔。
做了十年性能调优,我越来越觉得:调优不是"调参数",是"调判断"。新人最爱问"这个参数调多少最好",我每次都不知道怎么回答——因为答案永远是"看场景"。本文不是参数表,是几种判断力。
判断一:先问"是不是真的慢"
很多调优需求是"伪需求"。产品说"用户反馈慢",DBA 说"DB 慢",老板说"系统感觉卡"。这些"慢"经常不是真的慢,是"感知慢"。先量化:
- 具体哪个接口慢?P50 / P99 各是多少?
- 慢的用户在哪个地域、哪个网络、哪个版本?
- 慢是持续的还是偶发的?
- 和上周 / 上月同比如何?
量化后 50% 的"慢"会变成"不慢"。剩下 50% 才是真问题。不量化就调优,等于盲调。
"系统感觉慢"不是性能问题,是沟通问题。先把它变成数字,再谈调优。
判断二:先问"是不是新问题"
新出现的慢,和一直存在的慢,是完全不同的两类问题:
- 新慢:大概率是某个变更触发——代码发布、配置变更、流量突增、依赖退化。先找变更,再调优。
- 老慢:是架构问题或长期退化。需要系统性改造,不是调参能解决。
新人常犯的错:把"新慢"当"老慢"治。调了半天参数,没找到根因——其实是昨天某个 PR 引入了一个 N+1 查询。
判断三:先问"瓶颈在哪"
调优最大的浪费是"优化非瓶颈"。CPU 80% 时间花在 GC,你去调 SQL 没用。网络占 80% 延迟,你去调应用代码没用。
找瓶颈的方法:
- 火焰图看 CPU 占用分布。
- trace 看链路各段耗时分布。
- iostat / nicstat 看 IO 与网络。
- jstat / pprof 看内存与 GC。
找到瓶颈后再动手,效率提升 10 倍。
判断四:先问"能不能不调"
调优是"用复杂度换性能"。每改一个参数,都给系统加了一份复杂度。所以最好的调优是"不调"——用更简单的方法解决:
| 问题 | 调优方案 | 更简单方案 |
|---|---|---|
| 查询慢 | 调 SQL、调 buffer pool | 加索引 |
| GC 频繁 | 调 G1 参数 | 减少对象分配 |
| 连接打满 | 调连接池大小 | 减少不必要的 RPC |
| 缓存击穿 | 调 TTL | 加 singleflight |
90% 的"慢"都有"不调优"的解法。先想这个。
判断五:先问"代价能不能承受"
每个优化都有代价:
- 加缓存 → 一致性窗口扩大。
- 异步化 → 故障时丢数据风险。
- 分库分表 → 运维复杂度暴涨。
- 降级 → 部分功能不可用。
调优前问自己:"这个代价我能不能承受 1 年?" 不能就别做。短期看似快了,长期维护成本远超收益。
判断六:先问"团队能不能 hold 住"
某次我引入了一项"高级"优化(异步事件溯源),性能提升 30%。但团队 6 个月后才真正能维护它——之前每次小问题都要我亲自排查。最后算账:维护成本 > 性能收益。
调优方案的复杂度必须匹配团队能力。一个"团队能 hold 住"的 80 分方案,胜过"只有你懂"的 95 分方案。
几条带脾气的判断
- 慢的不是系统,是你的代码。80% 的"系统慢"是应用层的问题。先查应用,再怪基础设施。
- 能加索引解决的别调 SQL。索引是 80% 慢查询的解。
- 能加缓存解决的别调数据库。缓存是 80% 高 QPS 的解。
- 能加机器解决的别调架构。钱能解决的问题别用复杂度解决。
- 不要相信"调一下参数就好"。所有"调一下"都隐藏着长期代价。
调优的反向智慧
十年下来,我越来越相信几条"反直觉"的事:
- 少调优于多调。每次调优都是给系统加一份认知负担。
- 慢调优于快调。慢慢看、慢慢验证,比急调更稳。
- 不调优于调。能不调就别调——保持系统简单比优化性能更重要。
- 调优是最后手段。先把架构、代码、监控做好,再谈调优。
给新调优师的几句话
- 别背参数表,背判断流程。
- 每次调优前问自己 6 个问题(前文 6 个判断)。
- 调完做记录——3 个月后回看,才知道这次调优有没有真的生效。
- 敬畏复杂度——你加的每个参数都是未来某天的债。
调优是一门"减法艺术"。不是把系统调得更复杂,是让它"在更简单的前提下跑得更快"。这门艺术没有捷径,只有时间。但只要认真做,十年后你会发现自己写的参数表越来越短——那才是真正的进步。