如果要换掉一座繁忙机场的调度系统,最稳妥的测试不是让几架空飞机按固定路线起降,而是复刻某个真实工作日的航班、间隔和突发情况。数据库升级也一样:平均每秒发出多少条请求,只能说明一小部分问题。真正决定系统会不会出故障的,还有查询种类、参数、先后顺序、并发程度和读写比例。
Airbnb Engineering 介绍了一套数据库流量捕获与离线重放系统。它先记录生产环境里的真实查询,再让隔离的数据库按相近的顺序和节奏重新执行。这样,数据库升级、容量规划和负载测试就能面对真实业务留下的“考卷”,而不是只做人工编写的模拟题。
需要先说明:现有材料全部来自 Airbnb Engineering,没有论文、代码、完整测试数据或第三方测评。原文也在新系统目标列表处截断。因此,本文可以讲清它为什么要重建这套能力,以及真实回放发现过什么问题,但不能据此判断新系统的完整架构、性能开销或覆盖率。
合成压测为什么不够
Airbnb 称,其在线数据库基础设施以 MySQL-compatible databases——与 MySQL 协议或行为兼容的数据库——为关键支柱,包含数百个集群,支持数千个用例,整体负载达到每秒数百万次查询。这里的 QPS,即 Queries Per Second,表示数据库每秒处理多少次查询。
但 QPS 相同,不等于压力相同。读取一条简单记录和执行复杂的聚合、排序或多表连接,消耗可能差很多。合成压测通常会挑选一些典型查询,再按设定速度重复发送。它适合回答“机器大致能扛多少”,却容易漏掉生产系统长期积累的特殊查询、调用顺序和应用假设。
真实流量重放补的是这块缺口。所谓 capture and replay,就是先捕获线上查询的形状、顺序与节奏,再在离线环境重新执行。测试不能触碰真实用户,因此通常还要对用户标识和业务敏感值做脱敏,并确保测试流量无法写回线上数据库。材料没有披露 Airbnb 在这两方面的具体实现。
旧系统能记录,却拼不回完整现场
Airbnb 原来已经具备回放能力。不同编程语言的数据库绑定——应用连接数据库所用的软件接口——通过各自的日志框架记录查询轨迹,再把数据写入 Kafka。Kafka 可以理解为一条高速消息传送带:它接收持续产生的记录,并交给后续程序处理。之后,系统按不同用例加工轨迹,再由定制的 replayer 执行回放。
这套方案借用了原有的可观测性流水线。可观测性系统主要帮助工程师从日志和指标中判断线上系统发生了什么。把它改造成回放工具,早期启动很快,但规模扩大后,边界开始显露。
首先,捕获逻辑放在客户端,而且每种语言各做一套,维护成本高,责任归属也不清楚。其次,Airbnb 采用 SOA,即面向服务的架构:大型产品被拆成许多相互调用的服务。语言、客户端和用例越多,分散的捕获方式越难统一扩展。
更关键的问题是事务不完整。事务是数据库把一组操作视为一个整体的机制;例如一次预订可能包含检查状态、写入记录和更新库存,几步之间的顺序与成败关系不能随意拆开。旧系统没有记录足够的信息来还原事务全貌,因此无法准确重放,也无法验证同一批查询换到新数据库后是否得到相同结果。这正是 Airbnb 决定重建捕获与回放系统的直接动机。
真实回放会抓到什么
Airbnb Engineering & Data Science 披露的 MySQL 5.7 升级到 8.0 案例,展示了真实流量的价值。旧版 query cache——数据库把查询结果暂存起来、遇到重复请求时直接返回的缓存——长期掩盖了应用发送大量重复查询的问题。普通基准测试很可能看不到这笔“隐形债务”。
工程师先比较开启和关闭缓存的 MySQL 5.7,再把关闭缓存的 5.7 与 8.0 对照,以便把缓存影响和版本差异分开。一个突出的查询模式中,延迟从 0.03 秒升至 2.6 秒,每次 join——把多张表中的相关记录连接起来——读取的数据量从 5 MB 增至 273 MB。团队最终把问题追到 MySQL 8.0.20 之后排序读行方式的变化。
回放还暴露了应用自己的隐含假设。一些查询没有使用 ORDER BY,或排序字段不足以唯一确定顺序,却在 LIMIT 限制返回数量后,默认数据库总会给出固定的那几行。换到 MySQL 8.0,同一份数据可能返回另一组同样符合查询条件的结果。团队据此找到相关负责人,为确实依赖固定顺序的查询补上明确排序;据 Airbnb 介绍,这次升级最终没有造成重大生产事故。
容量规划也能从“估算增长”变成“提前试演”。Airbnb Engineering & Data Science 称,团队曾把一个大型集群的真实写入流量加速到约 1.8 倍。平均提交延迟随之从约 6 毫秒升至 34 毫秒,涨幅接近 500%。这让团队可以在旅游旺季或大型发布前发现容量悬崖,也能识别配置过剩、可能合并以节省成本的集群。
为什么值得关注
这项工作的意义不只是让压测更猛烈,而是让测试更像真实世界。合成负载回答的是设计者预先想到的问题;真实回放还会带回那些没人意识到需要提问的细节,例如重复查询、缺失的排序条件,以及只有特定事务顺序才会出现的差异。
它也改变了数据库变更的证据基础。团队不必等用户在生产环境里撞上极限,才知道一次升级改变了查询行为,或者未来流量会把延迟推过临界点。隔离环境里的重放,提供了一次成本更低、风险更可控的预演。
局限与未知
- 现有摘录没有包含新系统的架构和实现细节,也未说明如何捕获完整事务、维持时间节奏或比较查询结果。
- 材料没有披露捕获带来的线上开销、流量覆盖率、脱敏与隔离方案,以及哪些查询不能安全重放。
- “数百个集群”“数千个用例”和“每秒数百万次查询”都是 Airbnb 给出的量级描述,没有精确数字、统计时间点及峰值或均值口径;相关效果也尚无外部交叉验证。