Hacker News 中文摘要

RSS订阅

又省下100TB RAM -- Saving another 100TB of RAM

Cloudflare(Cloudflare)在全球运营数千台服务器,配备数PB内存与数百万CPU核心,全部压至极限。资源虽庞大却有限,每节点运行所有服务便无浪费余地。此规模下微小改进被放大,即便1%渐进提升也值得庆祝。某些调整累积更显:单个算法小改动大幅降低基于Pingora(Pingora)服务的内存占用,全球回收逾100TB内存,上月DNS团队还释放100TB。

正文

Cloudflare 的运行规模大到在这里干了好几年都觉得不真实。我们在全球有数千服务器、PB 级内存和数百万 CPU 核,且全部压满。资源虽巨却有限,当每个服务都要跑在每个节点上,就没有浪费空间的余地。

这种规模下小改进也被大幅放大,哪怕每次 1% 的优化都值得庆祝。有些调整累加更多:单个算法的小改动就让一个基于 Pingora 的服务内存占用显著缩小,全球收回逾 100TB RAM,继上月 DNS 团队省下 100TB 后再下一城。

杜绝浪费

Ivan 提交工单,发现 Pingora Backend Router(PBR)里的 pingora-ketama 内存使用过度。PBR 是我们的内部负载均衡服务,用了开源一致性哈希库。要谈怎么解决这看似超支的内存,得先讲什么是一致性哈希、PBR 为何用它、它怎变得这么吃内存。途中会接触一点 Rust 和数学。

一致性哈希

一致性哈希是广泛用的分配任务到多服务器的方法,增删服务器不需大变动。内部按 URL 路由可缓存请求,让每数据中心只存一份文件并有稳定查找方式。

哈希函数输出限于单个无符号整数(32/64/128 位),让任务和服务器以一致方式关联。常把输出空间想成环,但我们以 32 位输出的数字线表示。

哈希输出空间数字线示意图

设服务器 A、B、C 与任务 t-z,按代表值哈希映射上线。

服务器与任务映射示意图

分配任务即找每个任务左侧首个服务器,按颜色标出区域,C 的范围绕回起点。

服务器哈希区域着色示意图

基础就这么简单,但 A 的范围明显大于 B、C,导致负载不均。服务器处理请求比例正比于其数字线范围大小。理想是均等,但哈希本质随机,只能从统计谈区域大小。

数学与后果

用期望值和标准差量化不确定性。100 服务器时,每服务器范围期望中心在总长 0.99%,标准差约 1% 总长。换算变异系数(标准差除以期望)约 99%,意味着有的服务器可能多干 99% 的活(处理双倍请求),有的几乎闲置。

多加哈希会怎样?

一致性哈希简单是双刃剑。改进也得映射到数字线,意味着解决方案只能是“更多哈希”。为平衡负载,给每服务器加多个哈希而非一个。三服务器例各加两个随机哈希,负载更均。

每服务器增加哈希后负载更均衡示意图

NGINX 每服务器哈希硬编码 160,Pingora 同默认。100 服务器用 160 点,变异系数从约 99% 降到约 8%。

加更多哈希呢?

若不想均匀分配呢?有些服务器存储多,应按磁盘空间比例分请求。ketama 算法:若想服务器 X 比 Y 多处理 w 倍,X 哈希数需为 Y 的 w 倍。权重可设磁盘空间,PBR 多年如此;计算密集处用 CPU/GPU 数。

加还要多哈希???

实际因合规或缓存特性,仅子集服务器能处理某请求,不能靠同环加哈希解决,得加全新环,且每种特性组合可能需独立环!组合导致指数爆炸,PBR 有若干特性致许多独立一致性哈希环。有时占用 6GB 内存。Ivan 发现的过度内存使用正是为满足功能而海量哈希驻留内存。

存储改进

Zaidoon 洞察 PBR 存哈希的结构:原含 32 位哈希和 32 位索引,共 8 字节;索引用 32 位浪费,因同协调服务器不超某数,16 位够。但 Rust 对齐规则使改 16 位后仍占 8 字节。最终用 6 字节原始数组加访问方法,编译结果同,内存大降 25%。

少哈希如何?

推导每服务器多哈希的变异系数公式。图显示每降误差需近十倍哈希数,边际效益递减。基础 160 乘权重 625 得 100000 哈希,最后 90000 仅降 0.7% 误差。且 32 位哈希碰撞概率随数增(生日悖论),模拟显示 2048 服务器时误差升。决定减 90% 哈希数而无显见误差。

变异系数随哈希数下降示意图

32位哈希模拟误差上升示意图

迁移而不压垮源站

改环会让缓存请求去向变,全切等于缓存几乎全失效,源站流量灾变。PBR 同时载旧 ketama 环和新小环,按请求迁移框架决定用哪个,可干净回滚。分层滚动:先小验证点,再大数据中心组,后全球。独立控制流量比和移动位置,爆风半径小。监控后端选择、环版本、连接错误、进程内存、启动时间、缓存、源站流量。迁移满 100% 后删旧环路径。

PBR内存使用周对比图

图对比改动周与之前内存,锐降为旧大环停用日。差值显省 100TB。

内存差值示意图

自己试试

所述改动已在 pingora-ketama crate 以未宣传 cargo 特性提供。v2 环有紧凑存储格式、更快排序法、可缩放每节点基础哈希数。v1 环不变,库可同时跑两者按请求选。除试我们改动外,望你受启发去挖自己系统里藏潜力的“简单”决定。未必能用 Rust 解万难,但数学通用。

评论

社区对一篇涉及 Cloudflare 存储优化与数学推导的文章反应分化:少数人盛赞其中的技术深度并维护文章质量,另一些人则质疑 Rust 微优化的必要性或对文章生成方式提出猜测。

赞赏文章中的微积分与底层技术推导

  • 有读者表示日常编程很少用到微积分,因此文中关于推导和存储结构改进的细节令人享受,并反击了发表负面看法的人。(认可度:少数人) > 那些在这儿抱怨的人干脆吞葡萄干去吧(@agosta)

质疑 Rust 哈希存储优化节省两字节的必要性

  • 读者指出文章里唯一的 Rust 内容是用结构体存哈希省两字节,但未解释为何哈希量如此之大必须这么做,推测可能是每个任务每机都分配了哈希才合理。(认可度:少数人) > 文章没展开讲,但也许每个电脑每个任务都用一个哈希,所以确实省得多(@proc0)

对文章是否由 AI 生成持宽松或猜测态度

  • 有人猜测文章可能是靠感觉用 AI 堆出来的,因为技术内容缺乏创意但也希望模型已经好到能这样;另有用户明确表示不在乎文本是否 AI 写,只看重厂商服务。(认可度:较多人提及) > 我不在乎文本是否 AI 写的,只希望我的 AI 也能把哈希唱得这么好听(@dr_dshiv)

担忧极致优化导致代码库变成不可穿透的筒仓

  • 有人虽认可优化亮眼,但反思企业代码是否会因过度优化变成不符合直觉的孤岛;不过认为 AI 辅助探索代码能缓解该问题。(认可度:少数人) > 也许有了 AI 探索代码库快多了,这类黑箱问题没那么严重了(@ricardobeat)

有价值的补充

  • 一名开发者观察到自己的 AI 助手在本该用时间戳的场景强行使用哈希,这种反直觉的机器行为反而让人类开始怀疑自己的常规工程判断。