EP15:横向扩容和低延迟的关系¶
| 上集回顾 | EP14《节点池管理:把资源边界放进调度器》 |
|---|---|
| 下集预告 | EP16《如何应对突发性高并发场景》 |
0. 本集目标¶
看完这一集,观众应该能做到四件事:
- 破除一个最常见的误解:在节点空载、路径和媒体参数不变时,横向扩容通常不降低单流时延;它主要买到容量,并能避免过载导致时延恶化。
- 说清楚"容量"在这套系统里怎么被度量和调度:
capacity/pipelines、剩余容量优先、以及为什么容量阈值是软准入而不是硬件保证。 - 理解扩容对上游的影响:Origin 出站应按实际回源的 Edge 逐项求和;预推 fanout 和按需 pull 的成本不能混算。
- 知道现状的边界:容量告警已经可用,但自动扩容执行器还没实现,扩容目前是一套人工流程。
1. 开场钩子(逐字稿要点)¶
一个常见问题是:多买几台机器,单路播放会不会更快?条件要先说完整:当节点未过载、网络路径、协议缓冲和媒体参数都不变时,加机器通常不会缩短单流管线;当原节点已经排队、丢包或 CPU 饱和时,分流当然可能恢复时延。横向扩容主要改变容量和高负载稳定性,而不是凭空改变健康空载路径的时延。
2. 先破一个误解:延迟下限不是"算力不够"¶
端到端时延由采集与编码、网络传播、协议缓冲、排队、解码和渲染共同组成。横向扩容只直接处理资源竞争与排队,不会自动缩短传播距离,也不会改小既有的 jitter buffer 或 GOP。缓冲越大通常越稳,但代价是更高时延;具体数值必须按协议、配置和负载实测,不能设一个跨场景的固定地板。
所以结论很直接:
- 健康空载条件下,加 Edge、加 Origin 不会让既定缓冲自动变小。单条管线的串行开销不会因为并行铺了更多节点而缩短。
- 已有过载或路由不佳时,扩容并重新调度可以减少排队、丢包和重传,或者把用户放到更近的节点,因此观测时延可能下降。这里改善的是拥塞或路径,不是节点数量本身。
- PPCDN 的一次真实 P2P 跑通约为 70ms;这是换了媒体路径的案例,不是横向扩容的效果,也不能外推成全网 SLA。
一句话总结这一节:横向扩容解决的是"能不能扛住更多人",不是"能不能更快"。 这两件事经常被混为一谈。
3. 横向扩容真正买到的:容量,以及"在高负载下守住延迟"¶
既然加机器不能降延迟,那它到底买到了什么?答案是容量——以及一个容易被忽略的间接收益:让延迟在负载上来的过程中不恶化。
- 一台 Edge 能同时服务的观众/并发连接是有限的。两台 Edge 的并发上限大致翻倍,而且单台过载不会拖垂全局——这正是 EP02 讲的"Edge 层不是单点"的容量版本。
- 调度器按"剩余容量最大"选节点,把新流量导向更空闲的那台。节点不被压到过载线以上,延迟就不会因为排队、丢包、重传而恶化。
- 换句话说:横向扩容不是把延迟曲线压低,而是把延迟曲线在更高负载处拉平。这是 EP09"时延稳定性比平均延迟更重要"在容量维度上的延伸——你真正要守的是"人多时别变差"。
4. 容量是怎么度量的:capacity / pipelines¶
节点侧的容量模型很简单,两个数:
capacity:这个节点配置的并发槽上限(比如 Edge 配mmxNodeCapacity: 12)。pipelines:当前占用的媒体管线数。它是实现定义的调度计数,不等于 viewer 数;一条共享回源管线可服务多个 viewer,而不同协议、编码轨或转发目标也可能各占管线。- 剩余容量
free = capacity − pipelines:调度器就按这个值在池内降序选点(EP14 讲了"先按池过滤",这里补上池内这条排序维度)。
两个必须讲清楚的现实:
第一,capacity 是调度准入门槛,不是硬件能力保证。
调度器可以在 pipelines >= capacity 时把节点排除出新请求候选,但这只说明"不再接新管线",不证明节点在门槛以内一定健康。配置过高、已有会话瞬时膨胀或 CPU/网卡先到瓶颈,仍会丢包或异常;配置过低则会浪费资源。因此它必须由压测校准,并与 CPU、内存、带宽和丢包监控一起使用。
第二,告警是给人看的,不是给机器看的。 所以系统用三级软阈值来提前提示扩容:
| 阈值 | 默认值 | 含义 |
|---|---|---|
alarm.capacityWarning |
0.80 | 到 80% → warning,"开始准备加节点" |
alarm.capacityCritical |
0.95 | 到 95% → critical,"很危险了" |
alarm.capacityResolve |
0.70 | 回落到 70% 以下 → 自动清除告警 |
管线数是整数,阈值也应落实为整数比较。例如采用向上取整时,capacity=12 的 warning 为 ceil(12×0.80)=10 条,critical 为 ceil(12×0.95)=12 条,不能说在 9.6 或 11.4 条管线时触发。取整规则必须在实现和监控查询中保持一致。调度器会把新请求引向其它有余量的节点,但它不会替你加机器。
5. 最反直觉的一课:Edge 越加,Origin 越忙¶
到这里,"加机器 = 加容量"看起来已经很直白了。但这套架构里有一个非常容易踩的坑:给 Edge 扩容,会顺手把负载推给 Origin。
原因取决于分发模式,不能只按已部署 Edge 总数机械相乘:
Origin 出站带宽 = Σ(每条流实际发往每个下游目标的码率)
在 push fanout(预推) 模式下,每个配置的下游都持续收流,新增 Edge 会立即增加 Origin 出站。在 on-demand pull(按需拉流) 模式下,只有真正承载该流观众的 Edge 才回源;新增但空闲的 Edge 不产生这一路媒体出站。同一 Edge 上的多个 viewer 若共享回源,也不能按 viewer 重复计算。
所以当新增 Edge 实际开始回源时,Origin 会增加:
- 一条新的转发链路(出口带宽),
- 一路新的解码前的媒体转发会话(会话数、内存),
- 这些成本随实际回源的 Edge/Recorder 等下游目标逐项叠加,而不是随部署清单里的 Edge 总数必然增长。
工程教训:不能把
capacity当成"这台机器保证能跑的路数",更不能用"流数 × 固定目标数"代替流量测量。应按每条流的实际码率和实际下游连接求和,在压测中同时找出 CPU、内存、网卡和丢包的拐点,再给准入门槛留余量。这不是假设——2026-09-20 的一次生产容量评估(评估/建模口径,未做实时数据核验)就按这条公式算过 Origin 当时mmxNodeCapacity=100的风险:100 路 × 单路约 5Mbps × 2 个转发目标(record + 1 台 edge)≈ 1~1.5Gbps 聚合出站,比部署方案里唯一经过验证的"舒适区"锚点(单路 15Mbps、三层同播、"2vCPU 上是零头")高出两个数量级。结论是把mmxNodeCapacity先保守下调,而不是先加 Edge 再看 Origin 扛不扛得住。
这一节的结论:横向扩容不是"哪里不够加哪里",而是要顺着数据流看清——你加的每一台机器,会不会把压力转移到它的上游。 在这套架构里,Edge 的上游就是 Origin。
6. 让边缘扩容变便宜的机制:按需回源¶
既然 Origin 是瓶颈,那"每加一台 Edge 都必然给它加压"吗?不一定——关键看 Edge 是否预先回源。
这套系统用的是按需回源(sourceOnDemand):Edge 在观众到来之前,跟 Origin 之间没有任何管线。流程是:
- 观众发起 WHEP 播放请求;
- 这台 Edge 才去 Origin 拉这一路流;
- 同一台 Edge 上、同一路流的多个观众共享同一条回源链路。
这带来两个直接好处:
- 一台没有观众的 Edge,对 Origin 的额外负载接近 0。 你可以提前铺很多台边缘机器"待命",它们不占 Origin 的带宽,直到真的有观众落上来。
- 边缘扩容不需要动推流侧。 加 Edge 只是加了一个潜在的回源点,推流端完全无感。
代价与边界也要讲诚实:按需回源意味着冷启动会增加建链和首帧等待。当前的回退不是"P2P 与 Edge 并行竞速",而是服务端按编码格式提前分支后的顺序模型——H264 客户端先单独尝试 P2P,失败或超时才改用随决策一起下发的 Edge 地址(HEVC 客户端一开始就直接走 Edge,不尝试 P2P);具体的超时/宽限时长应来自真实网络分布校准,不能写成跨环境固定常数(见 EP13)。
7. 诚实的现状¶
- 容量告警已落库、可发 webhook,但自动扩容执行器还没实现。 扩容目前是一套人工 7 步流程:新建机器 → 部署 mmx → 配置节点 ID 和容量 → 开防火墙、配 TLS → 在 Origin 的
forwardMmxTargets追加新节点的私有 IP 并 reload → 若有 region 映射再更新一次 → 在 ppcenter 确认节点 online 并拉一路 WHEP 验证。 - 节点数上来之后,人工流程会成为瓶颈。 这也是为什么商业规划里把"脚本化扩容/节点加入"列为下一阶段的重点——边际运维成本吃毛利,是自建 CDN 最现实的一项挑战。
- 起步阶段 Edge 只有一台,这不是延迟问题,是可用性问题。 单台 Edge 故障等于全部观众中断。在低负载阶段,"再加一台做 N+1 冗余"的优先级,其实高于"再加一点容量"。
- 单机
capacity目前取值偏乐观、待压测校准。 2026-09-20 的容量评估(评估口径,非实时实测)之后,生产三节点mmxNodeCapacity已从 origin=100/record=50 下调为 origin=48、record=48、edge=12(edge 未实机复核):edge=12 与"按 3TB/月流量配额反推"的经济性推导吻合,相对最接近实测;但 origin=48 按上面的出站公式估算仍约 720Mbps 聚合吞吐,是已验证安全区的 48 倍;record=48 更没解决问题——60GB 盘在 7 天保留策略下,48 路并发全程录制只能撑约 24~30 分钟,和 50 时几乎没差异。这仍是文档里明确写下的待办:要找可控窗口用真实推流打到拐点,再回填一个贴近实测的容量值——而不是拍一个看起来很大的数。
8. 框图¶
8.1 单流时延 vs 容量天花板:两件不同的事¶
时延(每一条流) 容量(节点数量)
───────────────────────── ─────────────────────────────
采集/网络/缓冲/解码 ┌────┐ ┌────┐ ┌────┐
在健康空载、路径不变时, │Edge│ │Edge│ │Edge│ ← 加机器
加节点通常不缩短这些串行开销 └────┘ └────┘ └────┘
│ │ │ │
└─ 若原节点过载,分流可减少排队 └──────┼──────┘
▼
提高并发与冗余能力
8.2 Origin 出口随 Edge 数线性增长¶
ppobs ──(一路流)──▶ Origin
│
┌──────────────┼──────────────┬──▶ record
▼ ▼ ▼
Edge-1 Edge-2 Edge-3
(每台各一条独立回源链路)
Origin 出站 = 对实际回源的 Edge/Recorder 等目标逐项求和
→ push fanout 按配置目标计;on-demand pull 按活跃回源 Edge 计
8.3 按需回源:没人看的 Edge 不吃 Origin 带宽¶
观众到来前: 观众到来后:
Edge ──✗── Origin Edge ──▶ Origin ──▶ 流
(无管线) ↑
多个观众共享同一条 Edge→Origin 回源链路
空闲 Edge 对 Origin 的额外负载 ≈ 0;
代价:冷启动增加建链/首帧等待 → P2P 优先尝试、失败顺序回退 Edge 可降低影响(非并行竞速)
9. 结尾与下集预告(逐字稿要点)¶
这一集把"加机器"和"降时延"拆开了:在健康空载且路径不变时,横向扩容主要增加容量;在过载时,它可以通过减少排队和丢包恢复时延。
capacity是要靠压测校准的准入门槛,pipeline也不等于 viewer。计算 Origin 出站时必须区分预推 fanout 与按需 pull,并按实际下游连接求和。下一集,我们把这个话题再推一步:当流量不是缓慢上涨,而是突然爆发——你要应对突发性高并发,手里只有软阈值告警和一套人工扩容流程,这时候会发生什么、该怎么办。