使用 etcd 路由亚太地区视频流量

一家服务于亚太地区八个市场的视频流媒体平台通过将特定区域的配置迁移到 etcd,解决了反复出现的路由错误。路由变更的传播时间降至约一秒。编辑现在可以在不改动代码的情况下,在几小时内提升某个音乐池的热度,而且平台不再向韩国观众发送东京的流媒体。

为什么旧方法会失效

每个路由器在每次请求时都会读取三个值:热门池(trending pool)、特定语言的分词器(tokenizer)以及回退链(fallback chain)。驱动这些值的不是代码变更,而是业务决策——例如推广新艺人、应对区域性故障或测试推荐算法。

最初,每次部署都会附带一个包含路由表的 JSON 文件。在一次事故期间,一名值班工程师在其中一个节点上编辑了该文件,将流量指向备份池,但从未更新其他七个节点。配置漂移(Config drift)随之出现:八个国家运行着不同的路由表,且没有单一的事实来源(single source of truth)来验证“真相”。由于代码保持不变,只有隐藏的配置存在差异,导致将首尔观众发送到东京的错误持续存在。

选择 etcd 作为单一事实来源

团队对比了三个选项:

  • SQLite/MySQL – 会迫使每个路由器轮询数据库,从而增加延迟或导致查询泛滥。
  • Consul – 一个可靠的服务发现工具,但该平台并不需要其完整的服务网格(mesh)功能。
  • etcd – 一个强一致性的键值存储,具有 watch 原语,可以在键发生变化时立即通知客户端。

watch 功能成为了决定性因素。路由器不再需要反复询问“有变化吗?”,而是处于空闲状态,直到 etcd 推送更新。不必要的网络流量消失了,每个实例都能同时获知变更。

保持系统安全的模式

单靠 etcd 并不能解决所有风险。工程师增加了三个互补模式:

  1. Leases(租约) – 编辑可以设置临时提升(例如,在六小时内增加韩流音乐池的权重)。租约会自动过期,因此提升效果会自动消失,无需手动回滚。
  2. Compare-and-swap (CAS,比较并交换) – 当两个人同时编辑同一个设置时,CAS 会让其中一人操作失败并报错,从而防止静默覆盖。
  3. Sidecar 进程 – PHP 在处理长连接方面比较吃力。每个节点上运行着一个微小的 Go sidecar,它监听 etcd 并将路由表的快照写入共享内存文件 (/dev/shm)。PHP 读取该本地文件,从而在处理请求期间避免任何网络往返。

架构内置的韧性

新设计增加了几个安全网:

  • 零延迟读取 – PHP 热路径(hot path)从本地内存读取,因此请求永远不会因为等待远程存储而停顿。
  • 优雅降级 – 如果 etcd 宕机,路由器将继续使用最后一次已知的良好配置,防止突发性故障。
  • 可靠更新 – Sidecar 处理重连逻辑,并保证即使 etcd 连接暂时中断,也不会错过任何变更。

实际落地后的变化

迁移后,由于陈旧或不匹配的路由数据导致的事故大幅减少。现在,单个控制台即可显示当前配置,任何编辑都会在一秒内传播到所有八个区域。临时提升会在租约到期时自动清理,消除了以往因人工清理而导致的人为错误。

反方观点:Sidecar 的成本

增加 sidecar 意味着每台服务器都要运行第二个进程,并且在以 PHP 为核心的技术栈中引入了 Go 运行时。一些运维人员担心额外的内存占用以及监控另一个二进制文件的需求。在实践中,sidecar 的占用非常小,而且可靠性的提升——尤其是保证 PHP 永远不会因网络调用而阻塞——远超其运维开销。

后续关注点

管理多区域服务的团队应监控:

  • etcd 健康指标 – 路由层依赖于单一存储;需密切关注法定人数(quorum)状态和延迟。
  • 租约过期处理 – 将租约时间与业务窗口匹配;租约过长会导致陈旧的提升效果持续存在。
  • 扩展 watch 负载 – 随着路由器数量增加,watch 连接也会增加;应据此规划 etcd 服务器的容量。

总结

对于任何需要在多个地域之间进行快速、协同配置变更的服务,etcd 的 watch、lease 和 transaction 原语提供了一种轻量级、强一致性的方案,可以作为基于文件的配置或重量级服务网格(meshes)的替代方案。将配置转变为推送驱动、自动清理的存储模式,消除了一整类故障,并使平台能够对其路由逻辑进行实时控制。