如何计算系统设计容量

2025-06-07

如何计算系统设计容量

我读过的对编程影响最大的书籍之一是《编程珠玑》《更多编程珠玑》。在《更多编程珠玑》一书中,第七章有一句至理名言,叫做“信封回来了”。它讨论了记住某些公式的必要性,以及快速进行规模计算的能力。

作为一名软件架构师™,我构建过每天处理近十亿笔交易的系统。为了在脑海中理解这种规模,我使用了一两个小技巧,而且效果很好(对我来说)。

我总是记住我需要用两种不同的方式推理出一百万种东西:

  1. 百万规模
  2. 数量为一百万

百万规模

开发人员经常会来找我,喊着:“我们需要用这个 API 每天支持 200 万笔交易……救命!”(或者类似这样的话)。我很少感到慌乱。因为我懂规模的数学。我会直接回答:“太好了,所以我们需要每秒支持 24 次调用。没问题!”

信封背面的计算并非精确,只是近似值。我们很容易在脑海中计算出来。每天一百万笔交易是:

  • 每小时约 42k
  • 每分钟约 700 次
  • 每秒约 12 个

瓶颈很少发生在分钟或小时的尺度上。所以我唯一需要知道的数字是,100万个可扩展的事物大约每秒10-12个。就是这样。

一旦我们知道了这一点,我们就可以很容易地确定我们需要支持的规模:

  • 每天 100 万 = ~12/秒(12 * 1)
  • 每天 500 万 = ~60/秒(12 * 5)
  • 每天 3000 万 = ~360/秒(12 * 30)
  • 每天 1 亿 = ~1200/秒 (12 * 100)
  • ETC。

这只是部分现实。我们通常以用户为单位来思考。一个用户操作或会话可能会产生很多交易。因此,我们需要以稍微不同的方式思考规模。

每天一百万用户意味着:

  • 100 万 x 每个用户会话的大约交易次数

如果一个典型的用户在其会话期间生成 50 个 API 调用,那么我们可以使用我们的粗略技能来推断我们必须支持:

  • 12 * 50 = ~600 笔交易/秒。

什么时候也可以使用 ~10 作为因子。我们这里不追求工程上的精确,只是近似值。对于那些需要我过多思考的数字,我会使用 10 而不是 12 作为因子。

计算高峰时间

如果仅仅支持平均流量就足够了,我们早就把这部分帖子完成了。但我们经常需要考虑高峰时段。一天中某些时段的流量比平时更大。我们也必须支持这一点。

我个人的观点是,我们必须始终首先支持平均流量。这是通常情况。但接下来,我们需要支持预期的峰值流量。为此,我们需要记住另一个指标。我称之为“每小时 10% 规则”。记住,我们是以 100 万为单位来考虑的。如果 10% 的流量发生在 1 小时内(或者 30% 的流量发生在 3 小时内),那么每秒的流量是多少?

  • 10 万笔交易 = 30 笔/秒。

因此我们可以得出以下指标:

  • 1m/天应用程序@10%峰值持续1小时:100k规则=30/秒。
  • 1m/天应用程序@30%峰值持续1小时:100k规则=90/秒。
  • 1m/天应用程序@30%峰值持续3小时:100k规则=(30 x 3)/ 3 = 30/秒。

因此,一个每天访问量为 1 分钟的应用程序平均每秒需要维持 12 次访问,而一个小时的峰值为 10% 的应用程序平均每秒需要维持 30 次访问。以此类推。

每天有 1000 万笔交易?把这个数字乘以 10,以此类推。

快速回顾。

  • 100万/天 = ~12/秒
  • 假设用户每次会话需要 50 tns,即每天 5000 万次或每秒约 600 次

总是以每秒为单位来思考

多少 每用户 1小时峰值@10% @ 30%
1米 0 ~12 ~30 ~90
1米 10 ~120 ~300 ~900
1米 100 ~1200 ~3000 ~9000

差不多,我只需要记住这些。其他的都是10的乘法。

持续吞吐量与动态吞吐量?

规模很少能持续下去。它通常会随着潮起潮落而变化。不过,有时也不会出现峰值。它会持续一整天。例如:

  • 监控引擎
  • 监测水过滤系统
  • 飞行控制系统上的数据
  • 时间服务器
  • ETC。

你可能认为,一天中的时间只有在凌晨 1 点才会达到峰值,因为大多数计算机都会在凌晨 1 点查询它。但事实并非如此。这种服务会在 24 个时区的每个当地时区的凌晨 1 点启动。它很可能在每个小时的开始就达到峰值,因为每个新时区都会进行查询。我将其归类为持续性服务。这意味着我们必须将每个小时都视为峰值时间。

数量达一百万

数量是不同的。我们这里实际上讨论的是容量。下面是一个简单的图表,可以帮助计算不同的数量。再次强调,我们以 100 万为单位:

  • 一个 Int32 = 4 个字节。也就是 400 万字节
  • 一个 Int64 = 8 字节。也就是 800 万字节
  • 浮点数 = 4,即 8 个字节。
  • JavaScript 布尔值 = 4 个字节。
  • 对象的大小是其自身和所有成员的所有元数据的大小,+每个成员的数据大小。
  • 英文中一个UTF-8字符通常为1个字节。
  • 其他语言中,一个 UTF-8 字符占 1-3 个字节。中文字符可能占 3 个字节。因此,如果您支持其他语言,请将 UTF-8 字符视为 2 或 3 个字节。我假设是 3 个字节。
  • @ 每个字符 3 个字节,即 300 万字节。

奖励:了解你的瓶颈。

即使您确定带宽可以支持每秒 120 条连接,也不意味着您的整个系统都能支持。系统可能无法满足要求的部分包括:

  • 数据库连接数或吞吐量
  • 硬盘读写
  • 加密/解密大量数据的实用程序
  • 负载均衡器
  • 对受速率限制的第三方服务的 API 调用

系统的每个部分都需要能够支持预期的工作负载。

文章来源:https://dev.to/ievolved/how-i-calculate-capacity-for-systems-design-3477
PREV
如何从 React 18 降级到 17.0.2
NEXT
节点测试要点(节点开发人员的测试指南)