扩展到每秒 100 万请求:来自一线的经验教训
深入解析我们如何扩展 Virex 的基础设施,使其能够承载每秒超过 100 万个请求,同时将响应时间保持在 50 毫秒以内。
上个月,Virex 跨越了一个重要里程碑:如今我们的全球边缘网络每秒处理的请求已超过 100 万个。走到这一步并不容易,一路上我们收获了许多经验。
本文将分享支撑这一规模的关键架构决策与优化措施。
我们的起点
两年前,我们的架构非常简单:几台服务器位于负载均衡器之后,搭配一个 PostgreSQL 数据库和 Redis 缓存。对于最初的一千名客户来说,这套架构运转良好。
但随着业务增长,问题开始显现:
- 数据库查询成为瓶颈
- 缓存失效变得越来越复杂
- 单区域部署意味着国际用户面临高延迟
我们需要重新思考整体方案。
边缘优先架构
我们的解决方案是把计算迁移到边缘。不再把所有请求路由到中心数据中心,而是在离每位用户最近的节点处理请求。
全球分布
我们在全球部署了 200 多个边缘节点。每个节点运行:
- 轻量容器中的应用代码
- 本地缓存层
- 到区域数据库的连接池
这让大多数用户的平均延迟从 200 毫秒降低到了 50 毫秒以内。
智能缓存
并非所有数据都需要实时新鲜。我们实施了分层缓存策略:
边缘缓存(TTL:1—60 秒)
- 静态资源
- 公开的 API 响应
- 已渲染的页面
区域缓存(TTL:5—15 分钟)
- 用户会话数据
- 高频访问的数据库查询结果
源站(始终新鲜)
- 写操作
- 敏感数据
- 实时功能
这使源站流量降低了 85%。
数据库分片
单一数据库无法承载每秒 100 万个请求。我们按照客户 ID 实施了水平分片:
- 每个分片大约承载 10000 名客户
- 分片分布在多个区域
- 由只读副本承担查询负载
最棘手的部分是跨分片查询。我们通过一个查询路由层来解决,在需要时可以将请求扇出到多个分片。
性能优化
除了架构层面,我们还做了无数细小的优化:
连接池将数据库连接开销降低了 90%。
Protocol Buffers取代 JSON 用于内部通信,使序列化时间减少了一半。
预计算聚合消除了昂贵的实时计算。
懒加载推迟了非关键数据的获取。
大规模监控
无法度量就无法优化。我们构建了完善的可观测性体系:
- 实时仪表盘展示每秒请求数、延迟分位数和错误率
- 当指标偏离基线时自动告警
- 通过分布式追踪定位瓶颈
这种可见性对于快速发现并解决问题至关重要。
下一步规划
我们的扩展之路尚未结束。路线图包括:
- 新增 50 个边缘节点
- 基于流量模式实施预测性扩缩容
- 进一步缩短冷启动时间
关键要点
如果你正在扩展自己的基础设施,以下是我们的经验:
-
**让计算更靠近用户。**边缘计算已不再只服务于 CDN。
-
**积极缓存,谨慎失效。**大多数数据并不需要实时性。
-
**尽早投入可观测性。**当系统在大规模下出问题时,你会需要它。
-
**面向失败而设计。**在大规模下,总有某些地方在发生故障。
对系统扩展有疑问?欢迎加入我们的 Discord 社区,我们的工程团队就在那里。