线上出了个诡异的事故:一台网关机器 CPU 跑满,报警刷屏,可负责的同事查了半天,发现流量并没有暴涨——总量跟平时差不多。最后抓包一看,全网 1000 多个接口里,有 3 个接口扛走了 82% 的请求,而其中 1 个接口自己就占了一半。平时没人细看,因为总量不大;可一旦那几个热点接口抖动,整台机器就跟着抖。

这不是偶然,而是一条反复出现的规律:少数的东西,总是贡献了大部分的结果。

一、它从哪来

1896 年前后,意大利经济学家 维尔弗雷多·帕累托(Vilfredo Pareto) 在研究财富与土地分配时发现:意大利大约 20% 的人口拥有约 80% 的土地。他把这个"少数占大头"的观察推广到更多领域,后人便称其为帕累托法则(Pareto Principle),俗称二八定律

真正把它带进工程与管理世界的,是质量大师约瑟夫·朱兰(Joseph Juran)。1951 年他在《质量控制手册》中提出"关键少数与琐碎多数"(vital few and trivial many)的思想:质量缺陷并非均匀分布,少数几种缺陷类型造成了大部分损失——所以改进要集中火力打那"关键少数"。他还戏称这是帕累托留下的"非均衡原则",并发明了用于排序的帕累托图(Pareto Chart):按影响从大到小排柱子,再画累计占比折线。

此后人们发现同样的形状反复出现在各种系统里:图书借阅量、网页访问量、文件被引用次数……20 世纪语言学家**乔治·齐普夫(George Zipf)**总结出词频服从幂律(少数词被频繁使用,绝大多数词难得一见),即 Zipf 定律——它是二八定律在"排名-频率"坐标下的精确版本,也是理解互联网流量、缓存收益的数学底座。

二、为什么需要它

假设资源无限、时间无限,二八定律毫无意义——每个请求都全力服务、每行代码都精心优化就是了。可现实是:缓存空间有限、人力有限、算力有限。既然有限,就必须回答一个问题:把资源投到哪里收益最大?

如果错误地假设"所有东西同等重要",会得到两个典型恶果:

  • 平均用力,热点失守:给 1000 个接口配同样的缓存、同样的限流、同样的监控阈值。结果热点接口打爆了缓存,冷门接口的缓存却在浪费内存——资源被均匀地浪费掉了。
  • 优化没有优先级:性能优化时从第一个函数优化到最后一个函数,把力气花在只占 1% 执行时间的长尾代码上,真正占 90% 时间的热点函数反而没碰。

二八定律给出的回答是:不均匀才是常态,均匀才是例外。与其跟分布较劲,不如顺着分布做资源分配——这正是缓存的命中率、索引的收益、CDN 的加速比全部建立在这条规律之上的原因。

三、本质一句话

系统的产出与消耗天然不均匀:少数"关键少数"贡献了大部分价值(或大部分问题),优化的第一性原理就是先找到那 20%,再动手。

帕累托图:20% 的项目贡献 80% 的结果 1 5 10 15 20% 100% 项目 贡献占比 前 20% 项目 累计 80% 贡献从高到低排序

四、它有什么用

二八定律在计算机系统里几乎是"隐形地基"——凡是带缓存、带索引、带优先级的地方,背后都是它在起作用。

  • Redis 缓存热点数据:互联网访问服从 Zipf 分布,通常 20% 不到的"热 key"扛走绝大部分流量。于是缓存只存热 key、给热 key 单独调大容量,冷 key 直接穿透到数据库也扛得住。反过来说,缓存未命中率高的系统,十有八九是没先做"热点统计"就盲目全量缓存。
  • 数据库索引与慢查询:为什么 MySQL 里 EXPLAIN 一定要看 rows?因为一条 SQL 能不能走索引,决定了它是扫 100 行还是扫 1000 万行——而线上 90% 的慢查询,往往集中在少数几张表和少数几条 SQL 上。先 SHOW GLOBAL STATUSCom_select 类计数、或开慢查询日志按耗时排序,抓的就是那 20% 的语句。
  • 性能剖析 perf 的热点函数perf topperf record 跑一会儿,排在前面的几个函数往往就占了 70% 以上的 CPU。优化只做前几名,收益立竿见影;从第 50 名开始优化,纯属感动自己。这就是"先剖析、后优化"这一铁律背后的数学。
  • 分代垃圾回收:JVM/Go 的 GC 之所以分"新生代/老年代",正是因为观察到大部分对象朝生夕死——少数长寿对象占住了大部分堆。把新对象集中在一个小空间快速回收,正是顺着二八定律设计。
  • 日志与监控的采样:全量日志写不下时,按错误码、按耗时区间聚合,先处理"数量最多 + 影响最大"的那几类——告警分级、SRE 的"错误预算"分配,本质都是帕累托排序。
  • CDN 与存储分级:文件访问热度同样服从幂律,于是有了热/温/冷分层存储(如对象存储按访问频率自动降冷),把贵的高速介质只给那 20% 的热文件。
1
2
# 一个 5 分钟的"找关键少数"示范:统计访问日志里 Top 10 请求路径
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -10

五、反例与边界

二八定律是经验法则,不是物理定律——用错地方会得出危险结论。

  • 比例不是恒定的 80/20:有的场景是 90/10,有的更极端是 99/1(超级热点),有的接近 60/40(相对均匀)。所以正确用法不是背数字,而是先统计、后排序,用数据找出你那个系统里真实的"关键少数"。
  • 长尾不是没价值:二八定律告诉你热点集中,但没告诉你长尾可以丢弃。搜索引擎、推荐系统恰恰靠长尾内容差异化取胜;"只服务头部"会毁掉这类产品。二八定律指导的是资源分配优先级,不是业务取舍清单
  • 安全与合规场景不可只护热点:攻击者专挑没人看护的冷门接口下手——薄弱环节往往藏在长尾里。安全领域的正确姿势与缓存相反:热点要护,长尾更要扫,两者都要,只是手段不同。
  • 别把"帕累托法则"和"帕累托最优"搞混:帕累托最优(Pareto Optimality)是博弈论/多目标优化里的概念,指"无法在不损害任何一方的前提下让某人变得更好"的分配状态。两者同名不同物——一个描述"分布不均"的事实,一个描述"无可改进"的边界。
  • 优化热点过头同样有害:当热点函数已经优化到只剩 1% 时间,继续抠它收益趋近于零,此时瓶颈早已转移——二八定律只是起点,不是终点,每轮优化后都要重新做一次帕累托排序。

六、对比表 + 🐾小结

维度 均匀假设(错误直觉) 二八定律(现实)
请求分布 1000 个接口各扛 0.1% 少数接口扛走 80% 流量
资源分配 平均分配缓存/限流 按热度分层分配
性能优化 从头到尾逐个优化 先剖析,只优化 Top 热点
代码缺陷 均匀散布在各模块 集中在少数模块(朱兰:关键少数)
GC 设计 所有对象一视同仁 分代:朝生夕死 vs 长寿
数据价值 每个文件一样重要 20% 热数据支撑主要访问
易混概念 是什么 区别
帕累托法则(二八定律) 少数项目贡献大部分结果 描述"分布不均匀"的事实
帕累托最优 无法再让任何人变好而不损害他人 描述"无可改进"的边界状态

🐾 小结:二八定律是系统设计者的"第一直觉校正器"——看到缓存、索引、GC、监控、优化,先问一句"那 20% 在哪",再决定资源往哪儿放。它不替你做取舍,但帮你把取舍做在数据上:先找关键少数,再谈优化;先护热点,再补长尾。