mcpField
B
back-of-the-envelope

back-of-the-envelope

github.com/proyecto26开发113314 次安装1 天前更新
代码仓库

关于 back-of-the-envelope

帮助系统设计者进行数量级估算的技能,将流量、存储和带宽等模糊规模转化为可用于架构决策的近似数字。附带 Python 计算脚本,用于核对估算链中的算术。

主要功能

  1. 01估算 QPS 与峰值负载
  2. 02计算存储量和带宽
  3. 03推算服务器数量与内存
  4. 04记录假设并统一单位
  5. 05使用脚本核验计算

适用场景

  1. 01判断单节点数据库是否够用
  2. 02评估缓存或分片需求
  3. 03估算数据保留期所需容量

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/proyecto26/system-design-skills --skill back-of-the-envelope

安装后在 Claude Code 中输入/back-of-the-envelope确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

expected_outputs/
twitter_scale.json
references/
estimation-recipes.md
numbers-to-remember.md
scripts/
botec.py
test_botec.py

详细介绍

粗略估算(BOTEC)

把模糊的规模描述(如“高流量”“海量数据”)转化为几个能够决定设计的具体数字。BOTEC 是快速、近似的计算,用于可行性检查,而非追求精确。重点在于计算过程和方向是否正确:它们能告诉你何时单个数据库不够用、何时必须缓存,以及写入峰值何时需要队列。

面向 1k QPS 的设计和面向 1M QPS 的设计是两种不同的系统。10 GB 可以放进 RAM;10 TB 则需要分布式存储。先估算,再选择。

何时使用

在任何设计的第 2 步(紧接需求之后)使用;每当某个选择取决于规模时也要使用:例如确定读写路径的容量、决定采用分片还是单节点、说明缓存的必要性,或检查拟议组件能否承受负载。

何时不使用

不要追求精确,也不要为每个微服务都建模——这与该方法背道而驰。不要估算不会影响决策的内容(YAGNI)。大胆取整:“99,987 / 9.1”就是“100,000 / 10”。务必标注单位并写明假设。

先明确条件

估算的质量取决于输入。先确定:

  • DAU/MAU,以及其中每天活跃的比例。
  • 每位用户每天的操作数(发帖、读取、消息……)。
  • 读写比例——哪条路径占主导。
  • 对象大小——每条记录和每个媒体文件的大小。
  • 保留期限——数据保存多久(决定总存储量)。
  • 峰值系数——峰值通常约为平均值的 2 倍;某些工作负载的波动更大。

核心估算(计算方法)

每项都用一组乘除法完成计算。完整的计算示例和 CPU 时间推导见 references/estimation-recipes.md。

  • QPS = DAU × actions_per_user_per_day ÷ 86,400。峰值 QPS ≈ 2 × QPS (注明峰值系数)。
  • 每日存储量 = writes_per_day × avg_object_size。总量 = storage/day × retention_days(注意十进制与二进制的区别;存储按十进制单位出售)。
  • 带宽 = QPS × payload_size(分别计算读和写;通常出口流量占主导且会产生费用)。
  • 服务器数量 = peak_QPS ÷ per_server_QPS。用下文的单服务器速率作为除数。
  • 并发连接数 / 内存 = concurrent_users × per_connection_cost; 检查工作集能否放入 RAM(否则就是受 IO 限制、依赖磁盘的设计)。

重要数值

这些是值得记住的参考值,让你无需查资料也能进行估算。延迟、服务器规格、请求类型、2 的幂次和 9 的数量等完整表格见 references/numbers-to-remember.md——需要具体数值时再查阅。

最影响决策的两个参考值:

项目经验法则
单个 SQL/RDBMS 节点~1,000 QPS
键值存储节点~10,000 QPS
缓存服务器(Redis/Memcached)~100,000–1M QPS
一个现代 CPU 核心~1,000 个简单请求/秒 → 一台 64 核机器约为 64k 请求/秒
读取 1 MB:内存、SSD、磁盘~μs vs tens–hundreds of μs vs ms(内存 ≫ SSD ≫ 磁盘)

关注数量级,而非精确数值。 CPU 密集型操作耗时约为基准的 1 倍,内存密集型约为 10 倍,IO 密集型约为 100 倍。影响架构选择的是这个比例,而非小数点后的数值。

注意事项

根据这些示例以及估算容易产生误导的方式提炼而成。

应该

  • 应该将数字四舍五入到 1 位有效数字,并按数量级进行推理——比例(1× / 10× / 100×)才会影响架构,而不是小数位。
  • 应该按峰值而非平均值进行容量规划。 在选择容量前,先说明峰值倍数(≈2× 是常见默认值;突发性工作负载的倍数会更高)。
  • 应该分别估算读和写——95% 的读请求比例与写入峰值会将设计引向截然不同的方向。
  • 应该标注单位并写下假设,避免“GB”含义不明,并确保输入变更时能够重新核对整个计算过程。

不应该

  • 不要保留虚假的精度。 小数位暗示了输入数据无法支撑的置信度;“99,987”就是“100,000”。
  • 不要把单台服务器的处理速率当成通用标准。“SQL 每秒 1k 次查询”是针对点查询的经验法则;范围扫描、连接和较大的负载可能会差 10×——可用它估算数量级,之后再用实际基准测试验证。
  • 不要混淆二进制与十进制。 RAM 使用二进制单位;存储和网络的营销标示使用十进制单位——用于估算时两者足够接近,但前提是明确标注单位。
  • 不要计算那些不会影响决策的内容。 如果一个数字不会改变架构,就跳过它(YAGNI)。

图示

估算通常用表格呈现,而不是图示——将数字和假设直接列出。当推导出的数字迫使结构发生变化时(例如,“300k QPS > 单个 DB → 分片 / 添加副本”),应将其纳入架构图本身;绘制这些数字所支持的设计时,请使用 architecture-diagram 技能。

相关构建模块

  • requirements-scoping — 本技能依赖它提供输入(DAU、操作速率、比例、SLA),并将这些输入转化为数字。
  • data-storage — 本技能的结果会输入到它:此处计算的存储总量和分片数会影响它对 SQL/NoSQL 和分区方式的选择。
  • caching — 本技能的结果会输入到它:此处估算出的高读请求比例或热点工作集,是使用缓存的理由。
  • scaling-evolution — 本技能的结果会输入到它:当估算值超过单节点上限时,该上限就是接下来需要规划应对的瓶颈。
  • system-design — 推理循环的所属概念在此处;它负责协调,并在第 2 步调用本技能。

参考资料

  • references/numbers-to-remember.md — 速查表:延迟表、典型服务器规格、单服务器 QPS 速率、受 CPU/内存/IO 限制的请求类型、2 的幂次、可用性 9。需要具体数值时查阅。
  • references/estimation-recipes.md — 完整示例(Twitter 规模的 QPS + 存储、64 核 → 64k req/s 的 CPU 时间推导、带宽和服务器数量估算)。可查看完整的端到端推导过程。

脚本

如需确定性地检查容量规划计算链(精确计算真正派上用场的地方),请运行计算器,而不是手动计算:

  • scripts/botec.py — python3 scripts/botec.py --dau 150e6 --actions 2 --peak 2 --obj-bytes 1e6 --media-frac 0.10 --retention-days 1825 --server-qps 1000 --json → QPS、峰值、每日及总存储量、带宽、服务器数量。每服务器 QPS 的默认值遵循上述经验法则(可通过 --server-qps 覆盖)。
  • scripts/test_botec.py — 断言计算器的结果与 expected_outputs/twitter_scale.json(完整的 Twitter 示例)一致,确保说明中的计算方法与数学计算结果不会偏离。

评论

支持 Markdown