如何计算系统设计容量
我读过的对编程影响最大的书籍之一是《编程珠玑》和《更多编程珠玑》。在《更多编程珠玑》一书中,第七章有一句至理名言,叫做“信封回来了”。它讨论了记住某些公式的必要性,以及快速进行规模计算的能力。
作为一名软件架构师™,我构建过每天处理近十亿笔交易的系统。为了在脑海中理解这种规模,我使用了一两个小技巧,而且效果很好(对我来说)。
我总是记住我需要用两种不同的方式推理出一百万种东西:
- 百万规模
- 数量为一百万
百万规模
开发人员经常会来找我,喊着:“我们需要用这个 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