Cloudflare 最近公开的一个优化案例很值得一读:他们在一个基于 Pingora 的后端路由器上,把内存占用削掉了相当于 100TB 的量级,而使用的手段既不是换硬件,也不是重写整个系统,而是先用统计学算清楚 "需要多少",再动手改数据结构。

一、起点只是一张工单

事情的开始很平淡:一位工程师提交工单,指出 pingora-ketama 这个组件在这类服务上占用了过多内存。这套路由依赖一致性哈希(consistent hashing)来把请求分配到后端:把每台后端映射成哈希环上的若干 "点",请求落在哪个点,就发给哪台机器。

暗光下发亮的电路板走线

二、关键判断:点数不是越多越好

一致性哈希的经典取舍是:每台后端给的哈希点越多,负载越均匀,但内存占用越高。工程里的习惯做法是 "多给一点,保险",于是点数被随手设成一个大数字,没人算过它到底需要多少。

Cloudflare 这一步做的是把 "手感" 换成 "计算"。他们推导出负载分布不均匀程度的解析表达式——在 N 台机器、总量 m 个点的情况下,每台机器点数的期望是 m/N,而变异系数只取决于机器数量:CV = sqrt((N-1)/(N+1)),与点数总量无关。这个结论很反直觉也很实用:点数减少并不会让 "相对不均" 变差,只会让每个点上承担的流量变多。也就是说,点数存在一个由后端数量决定的可计算下界,超出这个下界再加点,只能花内存买心理安慰。

三、第二刀:每个点省两个字节

算清下界之后,他们顺手改了数据结构。原来每个哈希点的定义是两个 32 位字段——一个是哈希值,一个是后端索引;而后端数量事实上远小于 65536,用 16 位绰绰有余。于是结构从一个 u32 加一个 u32,变成一个 u32 加一个 u16。单看是 "省两个字节",但哈希点是百万、千万级的,规模一乘就变成了可观的数字。

最后一环是迁移。改哈希环意味着流量会重新分配,处理不好就会把源站一次性压垮。他们采用渐进式迁移,控制重新映射的速度,让后端有足够的时间消化——这一步没有数学技巧,只有工程纪律。

四、这个案例最值钱的地方

第一,先量化必要性,再写代码。如果一开始就去做 "更省内存的哈希结构",方向可能完全相反:真正需要的是证明 "点数可以更少"。优化工作中,最贵的往往不是实现,而是确认目标本身是否成立。

第二,规模会放大一切。同样的改动放在一台服务器上不值一提,乘以几十万台就是 100TB。这也是为什么大厂的经验不能照抄:你要先确认自己的 "规模乘数" 是多少。

第三,这套思路可以直接搬到小团队。日志采样率设多少才够判断故障、监控打点密度多高才有意义、数据库索引精度要不要到毫秒——这些都是同一个问题:用统计判断 "够了没",而不是凭感觉多加。多出来的那部分,平时看不见,只在账单和事故现场才现身。