自动扩缩容 · 云与可靠性
流量上涨时服务怎么扩容,流量下降时又怎么缩容?
课程目录为什么需要它
流量不是一条直线:午饭时间、一场促销、社交媒体上的一次提及,都可能让它翻好几倍。全天按峰值配服务器很浪费钱;配少了网站又会变慢甚至挂掉。自动扩缩容会自动调整副本数量,理解它的规则,你就知道该怎么配置它,以及它为什么有时会出乎你的意料。
直觉理解
Kubernetes 的水平 Pod 自动扩缩器(HPA)用的是一个公式(见它的官方文档):
期望副本数 = ceil( 当前副本数 × 当前指标 / 目标指标 )CPU 目标是 50% 时:4 个 Pod 平均 CPU 80% → ceil(4 × 80 / 50) = ceil(6.4) = 7 个 Pod。负载分摊到更多的 Pod 上,每个 Pod 就更接近 50%。
有两道护栏让它保持理智:
- 上下限:永远不少于
min,不多于max个副本。上限保护你的账单和数据库。 - 容差:如果比值
当前 / 目标和 1 相差不到 10%(HPA 的默认值),就什么都不做。没有它,微小的波动会让 Pod 整天加了又减(「抖动」)。
扩容需要时间:新 Pod 要启动,还要通过就绪探针。所以目标值通常远低于 100%:留出的余量用来扛住新 Pod 启动期间上涨的流量。
定义
自动扩缩容
Automatically changing the number of copies of a service based on a metric such as CPU or requests per second.根据 CPU 或每秒请求数等指标,自动改变服务的副本数量。
目标利用率
The level of a metric the autoscaler tries to keep each copy at, such as 50% CPU.自动扩缩器努力让每个副本保持的指标水平,比如 50% 的 CPU。
抖动
Scaling up and down repeatedly because of small changes. A tolerance or a cool-down prevents it.因为微小的变化反复扩容又缩容。容差或冷却时间可以防止它。
示例
公式
动手试试负载高于目标 → 更多 Pod;低于目标 → 更少。
import math
def desired(current, cpu, target):
return math.ceil(current * cpu / target)
print(desired(4, 80, 50))
print(desired(4, 50, 50))
print(desired(10, 12, 50))7 4 3
- L4向上取整:零点几个 Pod 也需要一个完整的 Pod。
- L64 × 80 / 50 = 6.4 → 7。
7 - L8安静的夜晚:10 × 12 / 50 = 2.4 → 3。
3
加上上下限
动手试试min 和 max 把结果限制在范围内。
import math
def desired(current, cpu, target):
return math.ceil(current * cpu / target)
def bounded(current, cpu, target, lo, hi):
return max(lo, min(hi, desired(current, cpu, target)))
print(bounded(4, 300, 50, 2, 10))
print(bounded(4, 5, 50, 2, 10))10 2
- L7先用 hi 封顶,再保证不低于 lo。
- L9一次尖峰要 24 个 Pod;上限只允许 10 个。
10 - L10几乎空闲时只要 1 个;为了安全至少保留 2 个。
2
常见错误
没有上限
一个吃 CPU 的 bug 或一次攻击,会把你扩到几百个 Pod,账单也随之暴涨。一定要设置上限。
目标值接近 100%
新 Pod 启动需要时间。没有余量的话,等待期间现有的 Pod 会被压垮。
扩容扩错了地方
如果瓶颈在数据库,再多的 Web Pod 只会给它发更多的查询。先找到真正的瓶颈。
小测验
1. 这段代码会输出什么?
import math
def desired(current, cpu, target):
return math.ceil(current * cpu / target)
print(desired(3, 90, 60))查看答案
答案:A
3 × 90 / 60 = 4.5,向上取整为 5。
2. 为什么自动扩缩器会忽略和目标相差不到 10% 的变化?
查看答案
答案:A
容差区间可以防止抖动。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出忙碌的早晨
准确写出它打印的内容。
- 改需求别再抖动了
这个自动扩缩器每有一点点变化就加减 Pod。加上容差:如果
cpu / target和 1 相差在 10% 以内(0.9 到 1.1,含两端),就保持current不变。 - 从零写重放一天
写一个
replay(start, readings, target, lo, hi),返回每次 CPU 读数之后的副本数。对每个读数:ratio = cpu / target;如果在 0.9 到 1.1 之间,保持当前数量- 否则取
ceil(当前数量 × ratio) - 然后限制在
lo…hi之间
replay(2, [50, 90, 300, 10], 50, 2, 8) # [2, 4, 8, 2]
本课术语
| 术语 | 中文 | 英文定义 |
|---|---|---|
| Autoscaling | 自动扩缩容 | Changing the number of copies to match load. |
| HPA | HPA 水平自动扩缩 | Kubernetes' Horizontal Pod Autoscaler. |
| Flapping | 抖动 | Scaling up and down over and over. |