写点什么

Grab 日均 10 亿次请求换掉旧存储,P99 延迟降低 50%

作者:Leela Kumili
  • 2026-10-21
    北京
  • 本文字数:1113 字

    阅读完需:约 4 分钟

AI摘要

Grab 将反欺诈平台 Counter Service 的存储后端从宽列数据库迁移至 Aerospike,重构数据模型并采用分阶段影子流量验证,实现零停机切换。生产环境 P99 延迟降 50%,磁盘用量从 3 TB 减至 1 TB,单节点成本降低 45%–50%。

数据模型由多行时间窗口计数改为单行聚合,消除三次并行读+批量写;通过存储门面解耦业务逻辑与存储实现;采用渐进式影子读(5%→100%)验证一致性后再切流。

适合后端架构师、SRE 工程师、数据库工程师阅读。

Grab 将其 Counter Service 的存储后端从宽列数据库迁移至 Aerospike,重新设计了数据模型,并通过分阶段迁移流量避免停机。该服务为 Grab 的反欺诈平台提供支持,每秒处理数万次查询,每天处理约 10 亿次请求。Grab 报告称,生产环境中的 P99 读取延迟降低了约 50%,磁盘数据量从约 3 TB 降至 1 TB,每个节点的成本降低了 45% 至 50%。

Counter Service 负责响应基于时间窗口的查询,例如近期叫车请求或支付失败记录。原有设计将 15 分钟、每小时和每日计数分别存储为独立的行。每个传入事件都会触发三次并行读取、一次内存内递增和一次批量写入,总共需要四次网络往返。原有宽列数据模型使用聚簇列高效检索特定时间范围内的行,这是 Apache Cassandra 文档中介绍的一种模式。

Grab 没有直接替换存储实现,而是先将存储访问与 Rust 服务的业务逻辑分离。一个存储门面提供了旧存储、Aerospike 和模拟实现,配置则用于控制单后端、影子和流量拆分模式。影子读取比例从 5% 逐步提高到 20%、50% 和 100%,并通过现有指标衡量数据一致性,之后才将真实流量转移至 Aerospike。

Grab 工程负责人 Daniel Lim 在 LinkedIn 上将这种方法描述为:

将用于流量影子验证和数据一致性验证的双重读写路径,与渐进式流量迁移结合起来。

更大的架构变化在于数据模型。Grab 最初评估了为每个时间桶保留一行的方案,但 Aerospike 会为每条记录维护约 64 字节的主索引元数据。按照该服务所需的记录数量,这一开销使记录基数成为容量规划中的一个重要考虑因素。

Grab 最终将一个计数器和一种时间粒度下的所有时间桶整合到一条记录中,其中包含一个按时间戳排序的映射。写入使用 Aerospike 的原子映射递增操作,同时显式删除过期条目。据 Grab 介绍,这项重新设计使记录数量减少了一个数量级以上,也有助于降低索引和磁盘占用。

读取路径也发生了变化。原有后端返回由服务器按时间范围筛选的分页数据行。Aerospike 返回包含映射的记录,再由 Grab 在客户端进行筛选。其批处理 API 会将多条记录操作组合为发送到数据库节点的请求,从而减少该服务在多键访问模式下所需的网络请求数量。Aerospike 的文档指出,批处理可以将多条记录命令合并为发送到每个相关节点的一次请求。

在发布过程中,Grab 还遇到了 Aerospike Rust 客户端的问题,包括最初采用同步 API,以及集群替换期间的 DNS 处理问题。团队随后采用了异步客户端,并与上游维护者合作解决 DNS 问题,之后才继续推进发布。

Grab 表示,此次迁移没有造成停机或数据完整性问题。最终架构结合了存储抽象、影子验证、渐进式流量切换,以及围绕 Aerospike 记录和批量访问特性设计的数据模型。

原文链接:

https://www.infoq.com/news/2026/10/grab-counter-aerospike-migration/