在互联网业务进入实时化和个性化时代后,传统的存储系统面临前所未有的压力。Airbnb 内部的键值存储 Mussel 从诞生之初就被定位为承接离线与在线工作负载的桥梁:既能支撑海量批量导入,又要保证单次读写的毫秒级响应。随着实时风控、个性化推荐、动态定价等新需求的出现,Mussel 从最初的 v1 演进为全新的 Mussel v2,是一次系统性、工程化的重构,既是技术能力的升级,也是可运维性和成本透明度的提升。本文围绕为何改造、核心架构、迁移策略与工程经验展开,旨在为构建类似系统的团队提供可借鉴的思路。 为何要从 v1 迈向 v2 Mussel v1 在多年运行中证明了其可靠性,但随着业务规模和场景多样性增长,它的局限逐步显现。运维复杂度高是首要痛点:扩容或替换节点需要基于 EC2 的多步骤脚本,人工干预多且耗时。
静态哈希分片带来的热点问题逐渐突出,节点负载不均会导致延迟骤升。一致性控制能力有限,无法满足对延迟与数据新鲜度有严格 SLA 的服务。资源使用情况不透明,无法为不同团队提供清晰的配额与成本追踪。在这样的背景下,Mussel v2 被设计为云原生、易自动化、可预测性能且易于运维的下一代平台,目标是在保障功能覆盖的同时大幅降低操作与维护成本。 全新架构的核心思路 Mussel v2 的架构围绕可伸缩性、可观测性与灵活一致性展开。关键组件包括无状态的 Dispatcher、基于 NewSQL 的后端存储、Kafka 驱动的写入流水线与分布式批量导入机制。
Dispatcher 作为入口面向客户端提供统一 API,将请求翻译为后端查询或变更操作,并实现了 dual-write(双写)和 shadow-read(影子读)两种迁移模式,便于在迁移期间进行灰度与验证。Dispatcher 的无状态化与 Kubernetes 化部署,使得滚动升级与自动回滚成为常态运维能力。 读写路径的设计体现了工程化权衡。读取场景被简化为按 dataname 映射逻辑表、点查、范围/前缀查询以及允许从本地副本读取较陈旧数据以换取更低延迟。读请求在 Dispatcher 层可以进行动态限流与优先级调度,在突发流量下保证 p99 延迟可控。写路径采用"先持久化到 Kafka 再写后端"的事件驱动模型,通过 Replayer 和 Write Dispatcher 将消息按序应用到后端数据库。
Kafka 在这里不仅承担了写入缓冲,还为升级、回放与迁移提供了可靠中间层,简化了对后端数据库直接承担瞬时吞吐的需求。 大规模批量导入与兼容性 批量导入长期是 Mussel 的刚需,v2 在保留 v1 语义(merge 与 replace)基础上,重构了批量导入流程以适配云原生环境。Airflow 仍然是上游数据管道的入口,离线数据被规范化后上传到 S3,然后由 Kubernetes 上的分布式有状态 worker(StatefulSet)并行拉取 S3 数据进行写入。为保证高吞吐,导入过程中使用去重、增量合并和插入时忽略重复键等策略,处理不同表的语义要求。批量导入在设计上注重可观测性与安全回滚,通过 stateless 控制器编排任务并在失败时自动重试或回退。 TTL 与数据治理的可扩展实现 数据过期是影响存储成本与合规性的关键功能。
v1 的过期机制依赖后端存储的压缩周期,难以在大规模表上保持效率。v2 引入了拓扑感知的过期服务:命名空间按范围划分为多个子任务,由多台 worker 并行扫描与删除过期记录。任务调度考虑到实时查询负载,以限制对生产流量的影响。写密集型表则采用基于版本的最大保留策略与有针对性的删除操作,从而在保证数据保洁的同时降低对在线性能的干扰。 从 v1 到 v2 的迁移策略 把一套线上关键基础设施替换为新系统,既要保证零数据丢失,又要避免对线上可用性造成影响,因此 Mussel 的迁移采用了蓝绿(blue/green)策略,并在此基础上增加了可逐表回滚与分阶段验证的能力。由于 v1 不支持原生的表级快照或 CDC,工程团队构建了定制化的迁移流水线,能够在保证数据一致性的前提下把表逐步移到 v2。
迁移分阶段进行:起始阶段全部流量仍由 v1(蓝区)承载,v2 在后台完成数据引导与校验并进入影子模式(绿区),此阶段 v2 会接收并记录读写请求但不返回结果,用于性能与正确性验证。验证通过后进入反向阶段,让 v2 承担主动流量,而 v1 保持待命,结合自动熔断与回退逻辑可以在 v2 出现异常时即时切回。最终在单个 dataname 级别完成切换,Kafka 贯穿整个过程,确保写入的可靠性与可回放性。 迁移流水线的工程细节 将表从 v1 引导到 v2 的过程由一系列步骤组成,以降低单次操作风险并提高可监控性。先对 v1 的数据做采样分析以估算分布,再在 v2 上创建预分片的表结构以避免后期重分布。引导阶段通常是最耗时的,借助 Kubernetes StatefulSet 保留本地进度与周期性 checkpoint,可以在节点重启或升级后快速恢复。
校验阶段对比 v1 备份与 v2 写入结果以确保数据完整性,随后通过处理 Kafka 中累积的滞后消息实现 catch-up,最终切入双写并将读流量逐步迁移到 v2。 工程经验与关键教训 在迁移与重构过程中,团队总结了若干普适性较强的经验教训。首先,从 eventual consistency(最终一致)到 strong consistency(强一致)的转变,会带来冲突处理与重复写去重等复杂性,需要在系统设计中预留相应机制,例如写去重、热点键阻塞与延迟修复策略。其次,预分片在基于 range 的分区方案中至关重要:若不在入库前对数据空间做合理切分,大量连续写入会在少数节点上聚集成为热点,从而严重影响迁移与写入性能。因此准确的数据采样与基于采样结果的 presplit 策略必须是迁移流水线的一部分。 查询模型方面,v2 在某些场景下对范围过滤的下推能力不及 v1,需要在客户端实现分页或额外的过滤逻辑来弥补。
另一个重要的权衡是数据新鲜度与成本:不同应用对延迟与一致性的要求不同,系统需要提供灵活的读取策略,例如通过命名空间级别的 stale-read 配置让部分业务使用副本以减少成本。Kafka 在整个迁移过程中发挥了不可替代的作用,其稳定的 p99 毫秒级延迟为双写与回放提供了坚实保障。 实践成果与运营收益 在严格的蓝绿迁移、双写与自动回退保证下,Airbnb 成功将上千张表、超过 PB 级的数据从 v1 平滑迁移到 v2,期间无数据丢失且未对用户可用性产生影响。Mussel v2 能够同时实现大规模批量导入与高吞吐的流写入场景,系统在单集群内支持每秒十万级别的写入并维持 p99 读延迟低于 25 毫秒,满足了多样化业务的低延迟与高可用要求。运维角度的改进也显著:基于 Kubernetes 的部署与自动滚动升级将人工干预时间从数小时缩短至数分钟,命名空间租户、配额与仪表盘提高了成本透明度并便于团队间资源分配。 未来方向与可持续发展 Mussel v2 的设计既解决了当下问题,也为未来演进铺平了道路。
短期内,团队将继续优化服务质量管理(QoS),把更多的策略与调度逻辑上升到 Dispatcher 层,以实现更细粒度的重试、限流与优先级控制。批量加载的性能优化仍有空间,特别是在减少数据预处理与分片决策的时间上。长期来看,目标是将更多的摄取与复制责任下沉到分布式后端数据库本身,简化外部流水线与降低整体延迟,使系统架构更为扁平与高效。 对于关注构建可扩展分布式存储系统的工程师与架构师,Mussel 从 v1 到 v2 的实践提供了若干可借鉴的原则:以控制平面实现云原生运维能力、用事件驱动设计隔离突发负载、通过预分片与采样缓解迁移热点、在迁移中保留渐进式回退能力以降低风险。业务方则能从平台化的存储服务中直接受益,不再需要为每个项目单独设计缓存与队列体系,从而把精力更多投入到产品创新上。 如果你对大规模分布式系统和数据基础设施充满热情,并希望参与类似 Mussel 这样具有挑战性的工程项目,Airbnb 正在持续招聘有志之士加入基础设施团队,共同推进数据平台的下一轮升级与优化。
。