美团KV存储系统:万亿级数据处理架构剖析

在互联网的世界里,数据是金矿,而 KV 存储就是我们挖矿用的铲子。

KV 存储,说白了就是 Key-Value 存储系统:给个 Key,就能快速拿到 Value。

比如用户登录信息、缓存数据、热点配置......都离不开它。

那你想过没有,当你的业务从几千并发涨到几百万甚至上亿并发时,这个"铲子"还能扛得住吗?

今天就来讲讲------美团万亿级 KV 存储系统的架构演化史------从最开始的"小作坊"一步步走向"分布式王者"的全过程。

一、KV 存储发展历程

️ 第一代:Memcached + 一致性哈希

还记得那个年代吗?美团用的是 Memcached,客户端自己做一致性哈希,后端部署一堆 Memcached 实例。

听起来是不是很熟悉?没错,这就是很多公司最初使用的 KV 存储架构

但问题也很明显:

  • 节点宕机 → 数据丢失;
  • 扩容 → 数据重分布,可能丢数据;
  • 客户端复杂度高;
  • 没有自动故障转移机制;
  • 没有持久化能力......

这就像是你家里搭了个简易书架,刚开始还能应付,书一多就开始摇晃,动不动就倒。

第二代:Redis 主从架构 + 哨兵机制

随着 Redis 社区逐渐成熟,也引入了 Redis,架构升级为:

客户端\] → \[一致性哈希\] → \[Redis [主从集群](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D260370939%26content_type%3DArticle%26match_order%3D1%26q%3D%25E4%25B8%25BB%25E4%25BB%258E%25E9%259B%2586%25E7%25BE%25A4%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=260370939&content_type=Article&match_order=1&q=%E4%B8%BB%E4%BB%8E%E9%9B%86%E7%BE%A4&zhida_source=entity")

这时候,Redis 哨兵机制可以实现 Failover,解决了节点宕机的问题,读写分离也更容易。

但还有一个痛点没解决:扩缩容依然会丢数据

因为一致性哈希机制决定了,节点变动就会导致 Key 映射变化,老数据找不到地方去,照样会丢。

所以,是时候换个更成熟的方案了。

第三代:Tair 分布式架构

这个时候,阿里开源的 Tair 成为了新选择。

它的架构分为三部分:

客户端\] → \[[中心节点](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D260370939%26content_type%3DArticle%26match_order%3D1%26q%3D%25E4%25B8%25AD%25E5%25BF%2583%25E8%258A%2582%25E7%2582%25B9%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=260370939&content_type=Article&match_order=1&q=%E4%B8%AD%E5%BF%83%E8%8A%82%E7%82%B9&zhida_source=entity")\] → \[存储节点

  • 客户端不再自己算路由,而是从中心节点拉取"路由表";
  • 中心节点有两个配置管理节点,负责监控所有存储节点;
  • 当节点宕机或扩容时,它能自动重建拓扑,并触发数据迁移
  • 客户端根据新的路由表访问对应的存储节点。

这样一来,扩缩容不再丢数据 ,Tair 通过数据迁移机制保证了数据完整性

看起来很完美?

但又遇到了新的问题


⚠️ Tair 的局限性:脑裂、迁移影响业务、数据结构不丰富

虽然 Tair 解决了很多问题,但在使用过程中发现:

  • 中心节点虽然是主备架构,但没有分布式仲裁机制
  • ,在网络分区情况下容易出现"脑裂";
  • 数据迁移期间性能波动大
  • ,影响线上业务;
  • 相比 Redis,Tair 不支持丰富的数据结构
  • ,很多 Redis 用户用起来不习惯;
  • 开源版本四五年未更新,迭代完全靠自己维护。

于是美团决定:在已有开源系统的基础上,开启自研之路


第四代:自研双引擎架构Squirrel & Cellar

美团基于 Redis Cluster 和 Tair 分别开发了两个不同的 KV 存储系统:

Squirrel:全内存、低延迟、高吞吐的缓存引擎

  • 基于 Redis Cluster 架构优化;
  • 支持 Redis 全部数据结构;
  • 适用于对延迟敏感、数据量小的场景;
  • 自研功能尽量兼容官方架构,方便未来升级;
  • 目前已支撑每秒亿级请求。

️ Cellar:持久化、大容量、高可靠的数据存储引擎

  • 基于 Tair 改造,加入大量自研特性;
  • 支持数据落盘、冷热分离
  • 适用于数据量大、对延迟容忍度高的场景;
  • 因为 Tair 社区停滞,Cellar 完全由美团团队自主迭代;
  • 同样支撑每秒亿级请求。

这两个系统相辅相成,构成了美团内部的"KV 双子星"。


关注【Linux教程】,获取编程学习路线、项目教程、简历模板、大厂面试题pdf文档、大厂面经、编程交流圈子等等。

二、 内存KV存储 Squirrel 架构揭秘

前面讲了美团整个 KV 存储系统的演化史,从 Memcached 到 Redis,再到 Tair,最终形成了美团现在的两大主力系统:Squirrel(全内存)Cellar(持久化)

接下来就重点来看看 Squirrel 是怎么设计出来的?它又是如何支撑起万亿级请求的?

2.1、数据分布机制:Key 是怎么找到"家"的?

先说个关键问题:Key 是怎么分布到各个节点上的?

这个问题在分布式系统里叫"数据分片",而在 Squirrel 和 Cellar 中,美团采用的是 Redis Cluster 的经典方案:

vbnet 复制代码
Key → 哈希计算 → Slot ID → 路由表映射 → 找到目标节点

具体来说:

  1. 预分片机制
  2. :美团预先划分了 16384 个 Slot(跟 Redis Cluster 一致);
  3. 哈希算法固定
  4. :每个 Key 经过 CRC32 哈希后取模,得到一个 Slot ID;
  5. 路由表控制分配
  6. :Slot 到节点的映射通过路由表维护;
  7. 客户端直连
  8. :客户端根据最新的路由表直接访问对应节点,不经过代理层;

这种方式的好处是:

  • 分布均匀;
  • 易于扩缩容;
  • 客户端负担可控;
  • 与 Redis 社区生态兼容性强。

你可以把它想象成"快递分拣系统":

快递员拿到包裹(Key),扫描一下编号(CRC32),查一下分拣柜(Slot ID),然后按照最新的派送地图(路由表)送到对应的站点(Redis 实例)。

2.2、高可用设计:宏观容灾 & 微观稳定性都要抓!

说到高可用,很多人第一反应是"别挂",但其实它包含两个层面的理解:

✅ 宏观高可用:能扛住大风大浪

  • 单点故障(宕机) → 自动 Failover;
  • 多节点宕机 → 主动迁移副本;
  • 机房级故障 → 支持跨机房部署和切换;
  • 区域级故障 → 异地多活备份;

这就像你在家里准备了一个备用电源,小区停电也不怕。

✅ 微观高可用:让每一次请求都稳稳当当

  • 在线扩容时不影响业务;
  • 数据迁移过程中不丢包;
  • 版本升级灰度发布
  • 网络抖动自动重试;
  • 热点 Key 自动拆分;

这就像你开车的时候遇到小坑小路,车自己帮你缓冲过去了,你根本没感觉。

美团在 Squirrel 的设计中,从这两个维度都做了大量工作,确保系统既"扛得住大事",也"经得起小事"。

2.3、Squirrel 架构解析:Redis Cluster 的增强版

来看一下 Squirrel 的整体架构图

各组件说明:

组件 作用
客户端 SDK 拉取路由表、执行请求、自动重试、失败转移
ZooKeeper 存储集群元数据,如 Slot 分配、主从拓扑等
集群调度平台 负责扩缩容、故障转移、负载均衡等自动化运维
Redis 实例 主从结构,负责实际的数据读写
Gossip 协议 实例之间互相通信,同步状态信息

Squirrel 本质上是在 Redis Cluster 的基础上,加上美团自研的调度平台和客户端 SDK,打造出了一个全内存、低延迟、高吞吐、高可用分布式缓存系统。它不仅继承了 Redis 的丰富生态,还在易用性、稳定性、扩展性方面做了大量增强。

2.4、Squirrel 节点容灾

我们再来回顾一下 Squirrel 是如何实现节点容灾的。对于 Redis 集群来说,官方已经提供了一套较为完备的节点宕机处理机制。按照标准流程,任何一个节点从发生宕机到被标记为 FAIL 并最终摘除,通常需要约 30 秒时间。

对于主库的摘除操作,需要格外谨慎,因为它可能影响数据的一致性。但如果是从库呢?美团认为这个等待过程是不必要的。此外,也注意到,内存型 KV 存储的数据量一般较小,但在业务规模较大的公司中,往往会存在大量的集群。一旦发生交换机故障,可能会同时影响多个集群,宕机后补副本的操作就会变得非常繁琐。

为了解决上述两个问题,美团设计并实现了 HA(High Availability)高可用服务

它的架构如下图所示,能够实时监控集群中的所有节点。无论是网络抖动还是节点宕机(例如 Redis 2),HA 都能迅速感知,并实时更新 ZooKeeper,通知其摘除 Redis 2。客户端接收到变更通知后,会将读流量自动路由到 Redis 3 上。

如果 Redis 2 只是几十秒的短暂网络抖动,在 HA 检测到它恢复之后,会将其重新加回集群。

如果过了一段时间,HA 判断该节点属于永久性宕机,则会直接向 Kubernetes 集群申请一个新的 Redis 容器实例(如 Redis 4),并将其加入集群。此时,集群拓扑结构恢复为一主两从的标准结构。HA 更新完集群拓扑信息后,会写入 ZooKeeper,通知客户端更新路由表,使其能够将读请求转发到新的从节点 Redis 4 上。

通过这套机制,美团将从库的摘除时间由原来的 30 秒缩短至 5 秒以内。同时,借助 HA 自动申请容器实例的能力,美团实现了分钟级的宕机补副本操作,整个过程无需任何人工介入。

2.5、Squirrel 跨地域容灾

解决了单节点宕机的问题之后,美团再来看跨地域部署场景下的挑战。跨地域容灾与同地域部署相比,存在两个显著差异:

第一,相对于同地域机房间的网络环境,跨地域专线的稳定性较差;

第二,跨地域专线带宽有限且成本高昂。

而原生 Redis 集群内的复制机制并未考虑极端网络状况的影响。比如,如果美团把主库部署在北京,两个从库部署在上海,同一份数据需要通过北上专线传输两次,这将造成巨大的带宽浪费。

此外,随着业务的发展演进,美团也在推进单元化部署和异地多活架构。显然,使用 Redis 原生的主从同步机制已无法满足美团的需求。因此,进一步开发了集群间复制方案

如上图所示,美团以北京的主集群和上海的从集群为例进行说明。美团要实现的是:通过集群同步服务,将北京主集群的数据同步到上海从集群。

具体流程如下:

首先,向同步调度模块下发"建立两个集群间同步链路"的任务。调度模块根据主从集群的拓扑结构,将同步任务下发至同步集群。同步集群接收到任务后,会模拟一个 Redis 的 Slave 节点,通过 Redis 的复制协议,从主集群的从库拉取数据,包括初始的 RDB 快照以及后续的增量变更。同步机获取到这些数据后,会将其转换为客户端的写命令,并写入到上海从集群的主节点中。

通过这样的方式,美团成功地将北京主集群的数据同步到了上海从集群。若要实现异地多活,只需添加一条反向的同步链路即可,从而实现集群间的双向数据同步。

接下来,继续讨论微观层面的高可用保障,即如何维持端到端的高成功率。在 Squirrel 中,主要有以下三类问题会影响成功率:

① 数据迁移造成的超时抖动;

② 持久化操作引起的超时抖动;

③ 热点 Key 请求导致单个节点负载过高。

2.6、Squirrel 智能迁移

在数据迁移方面,美团主要面临以下三个挑战:

① 虽然 Redis Cluster 提供了 Slot 迁移能力,但它并不负责决定迁哪些 Slot,也不指定 Slot 从哪个节点迁移到哪个节点;

② 在实际迁移过程中,大家都希望迁移越快越好,但迁移速度过快又可能对正常业务请求产生干扰;

③ Redis 的 MIGRATE 命令会阻塞工作线程,尤其在迁移大 Value 时,主线程会被长时间阻塞,严重影响性能。

为了解决这些问题,构建了一整套全新的智能迁移服务。

该服务具备以下几个关键特性:

  • 支持自动化决策 Slot 的迁移源与目标;
  • 动态控制迁移速率,避免影响线上业务;
  • 引入异步非阻塞迁移机制,解决大 Value 阻塞主线程问题;
  • 支持并发迁移多个 Slot,提升整体效率;

通过这套智能迁移服务,在保证系统稳定性的前提下,大幅提升了数据迁移的速度与灵活性。

下面按照工作流来介绍迁移服务是如何运行的。

首先,生成迁移任务。这一步的核心原则是"就近优先"。例如,在同机房内的两个节点之间进行迁移,相比跨机房迁移效率更高、延迟更低。因此,在生成任务时会优先选择网络距离更近的节点作为源和目标。

迁移任务生成之后,会下发到一组专门用于执行迁移操作的迁移机上。迁移过程中,迁移机具备以下几个关键特性:

  1. 集群内并发迁移
  2. :迁移机会在多个迁出节点之间并发执行迁移命令。例如,可以同时向 Redis 1 和 Redis 3 下发迁移指令,提高整体迁移效率;
  3. 批量 Key 迁移
  4. :每次执行 MIGRATE 命令时,不是只迁移一个 Key,而是迁移一批 Key,从而减少网络往返次数,提升吞吐量
  5. 动态速率控制
  6. :美团会通过监控服务实时采集客户端的成功率、响应耗时,以及服务端的负载、QPS 等指标,并将这些状态反馈给迁移机。整个迁移过程类似于 TCP慢启动机制:迁移速度会逐步提升,一旦检测到请求成功率下降或延迟上升,迁移速度就会自动降低,最终达到一种动态平衡------在尽可能快完成迁移的同时,最小化对正常业务请求的影响。

接下来,来看一下大 Value 的迁移问题

Redis 原生的 MIGRATE 命令在迁移大 Value 时会阻塞主线程,严重影响服务的响应性能。为此,美团实现了一个异步 MIGRATE 命令

该命令在执行过程中,Redis 的主线程不会被阻塞,仍然可以继续处理其他正常的请求。如果在此期间有针对正在迁移 Key 的写请求到达,Redis 会返回错误信息,以避免数据不一致的问题。

通过这一改造,美团最大限度地保障了业务请求的稳定性,同时避免了主线程因迁移大 Value 而陷入长时间阻塞的风险。

2.7、Squirrel 持久化重构

在 Redis 的主从同步过程中,会生成 RDB 快照文件。生成 RDB 的过程通常通过调用 fork() 创建一个子进程来将内存数据写入磁盘。虽然操作系统提供了写时复制(Copy-on-Write,COW)机制来优化这一过程,但当内存使用量达到 10GB 或 20GB 以上时,fork() 仍可能导致整个 Redis 进程出现接近秒级的阻塞。

这对在线业务来说几乎是不可接受的。此外,为了满足对数据可靠性要求较高的业务场景,美团也会开启 AOF 持久化功能。然而,在高写入压力下,AOF 刷盘操作可能因 I/O 抖动造成主线程阻塞,从而影响请求的成功率。

为了解决官方持久化机制带来的这两个问题,美团对 Redis 的持久化机制进行了全面重构。

以下是新版持久化机制的核心流程:

写请求\] → \[写入 DB\] → \[记录到内存 [Backlog](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D260370939%26content_type%3DArticle%26match_order%3D1%26q%3DBacklog%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=260370939&content_type=Article&match_order=1&q=Backlog&zhida_source=entity")\] → \[[异步线程](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D260370939%26content_type%3DArticle%26match_order%3D1%26q%3D%25E5%25BC%2582%25E6%25AD%25A5%25E7%25BA%25BF%25E7%25A8%258B%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=260370939&content_type=Article&match_order=1&q=%E5%BC%82%E6%AD%A5%E7%BA%BF%E7%A8%8B&zhida_source=entity")刷盘到硬盘 Backlog

具体改进如下:

  • 写请求首先写入数据库;
  • 同时记录到内存中的 Backlog 中,这部分与官方实现一致;
  • 异步线程负责将变更持续地刷写到硬盘 Backlog 中;
  • 当硬盘 Backlog 积累过多时,会选择在业务低峰期触发一次 RDB 快照,并删除该 RDB 之前的所有硬盘 Backlog 数据,以节省存储空间。

那么,当需要进行主从同步并寻找同步点时,这套机制又是如何工作的呢?

处理流程如下:

  1. 首先查找内存 Backlog
  2. :如果同步点在内存 Backlog 中存在,则直接使用;
  3. 若内存中未找到,则查找硬盘 Backlog
  4. :由于硬盘容量远大于内存,因此硬盘 Backlog 可以保留大量历史数据,大大降低了找不到同步点的概率;
  5. 如果硬盘 Backlog 中也找不到同步点
  6. :则会触发一次类似全量同步的操作。但与官方不同的是,这次全量同步无需重新生成 RDB 文件,而是直接利用已有的硬盘 RDB 文件及其之后的硬盘 Backlog 完成同步。

通过这一设计,美团显著减少了全量同步的次数,提升了主从同步的成功率与效率。


2.8、Squirrel 热点 Key 解决方案

接下来介绍 Squirrel 是如何应对热点 Key 问题的。如下图所示,普通主从节点构成了正常集群的一部分,而"热点主从节点"则是独立于正常集群之外的一组特殊节点。

它们之间是如何协作的呢?来看一下完整流程:

当客户端向普通节点发起读写请求时,Redis 实例会在内部同时对 Key 的访问频率进行统计。一旦某个 Key 达到预设的访问频率或带宽占用阈值,系统就会自动触发流控机制,限制对该热点 Key 的访问,防止节点因突发流量被打满。

与此同时,美团的监控服务会定期扫描所有 Redis 实例,收集统计到的热点 Key 信息。一旦发现热点 Key 存在,监控服务会将对应的 Slot 上报给迁移服务。

迁移服务接收到通知后,会执行以下动作:

  1. 将一组专门用于处理热点流量的"热点主从节点"加入当前集群;
  2. 将包含热点 Key 的 Slot 整体迁移到这组热点主从节点上;

由于这些热点节点仅承载热点 Slot 的请求,其处理能力得到了显著提升。这样一来,就实现了:

  • 实时热点 Key 监控;
  • 自动流控止损;
  • 热点 Slot 的快速隔离与扩容;
  • 高效应对突发访问压力;

通过这一整套机制,美团不仅有效避免了单个节点因热点请求过载而导致的服务异常,还实现了对热点流量的动态响应和弹性扩展。

三、持久化 KV Cellar 架构和实践

接下来介绍持久化 KV 系统 ------ Cellar 的架构设计与工程实践。下图是 Cellar 架构图。

相较于阿里开源的 Tair,美团在架构层面做了两个关键改进:一是引入了 OB(Observer)节点 ,二是引入了 ZooKeeper 来增强集群的元数据管理能力。

OB 的作用类似于 ZooKeeper 的 Observer 角色,它主要负责提供中心节点的元数据查询服务。OB 实时从中心节点的 Master 同步最新的路由表信息,客户端通过 OB 获取路由表,而不是直接访问 Master。

这种设计带来了两个显著优势:

  1. 天然隔离客户端与 Master
  2. ,防止大量客户端请求对 Master 造成压力;
  3. OB 不参与集群管理决策
  4. ,只提供读取服务,因此可以水平扩展,极大提升了路由表的查询能力。

为了进一步提升系统的高可用性与一致性,美团引入了 ZooKeeper 做分布式仲裁,解决在网络分区(脑裂)场景下 Master 与 Slave 之间的冲突问题。同时,美团将集群的核心元数据存储在 ZooKeeper 中,保障了元数据的可靠性与一致性。

3.1、Cellar 节点容灾

了解完整体架构后,来看一下 Cellar 是如何实现节点容灾的。

在实际运行中,节点宕机或网络抖动通常是临时性的故障 。如果每次节点短暂离线都触发副本重建和数据补全操作,会消耗大量资源并影响业务请求。为应对这一挑战,美团设计了 Handoff 机制

如上图所示,当 A 节点宕机后,系统会触发 Handoff 流程。中心节点通知客户端:A 节点不可用,将原本属于 A 的分片 1 请求转发到 B 节点。B 节点在处理正常请求的同时,还会将应写入 A 的数据记录在本地日志中。

若 A 节点在数分钟内恢复(如因网络抖动导致短暂停机),中心节点会指示 B 节点将暂存的日志回传给 A。待 A 完成数据同步后,中心节点再通知客户端恢复正常的请求路径,将分片 1 的流量重新打回 A 节点。

通过这套机制,美团可以做到:

  • 秒级摘除故障节点
  • 快速恢复时仅需同步增量数据
  • 支持主动 Handoff,用于升级等运维操作,实现"静默升级"。

3.2、Cellar 跨地域容灾

接下来介绍 Cellar 如何实现跨地域容灾。其面临的问题与 Squirrel 类似,但美团也采用了类似的解决方案 ------ 集群间复制机制

以一个典型的北京主集群、上海从集群为例说明:

当客户端向北京主集群的 A 节点发起写操作时,A 会像普通集群那样,将数据复制到 B 和 D 节点。同时,A 还会将该写操作发送到上海从集群的 H 节点。H 节点接收后,在本地执行写操作,并将其复制到从集群的 I、K 节点。

通过在主从集群之间建立这样的复制链路,美团实现了跨地域的数据同步,同时最大程度降低了跨地域专线的带宽占用。

此外,只需在主从集群间配置双向复制链路,即可轻松实现异地多活架构

3.3、Cellar 强一致

在完成节点容灾与跨地域容灾之后,美团迎来了更高的业务诉求 ------ 强一致性

美团原有的复制机制是异步的,在发生故障切换时可能会丢失尚未复制的数据。这对金融支付等不允许数据丢失的业务来说是无法接受的。

为此,美团选择了业界主流的 Raft 协议,作为实现强一致性的基础。选择 Raft 主要基于以下几点考虑:

  • 论文描述详尽,工程实现性强;
  • 社区已有多个成熟开源实现可供参考;
  • 可有效缩短研发周期;

下图展示了当前 Cellar 集群在 Raft 模式下的架构。中心节点负责调度 Raft 组,决定每个 Slot 的三个副本部署在哪些节点上。

例如:

  • Slot 1 分布在节点 1、2、4 上;
  • Slot 2 分布在节点 2、3、4 上;

每个 Slot 对应一个独立的 Raft 组,客户端只能在对应的 Raft Leader 上进行读写操作。

由于美团预分配了 16384 个 Slot,在集群规模较小时,单个节点可能承载数百甚至上千个 Slot。若每个 Raft 组单独维护复制线程和日志,会造成严重的性能损耗。

为此,美团实现了 Multi Raft 模式

虽然 Raft 自身具备选主机制,但在某些场景下可能出现负载不均。例如,经过多次宕机恢复后,Leader 可能集中分布在少数节点上,从而影响整体性能。

为此,美团的中心节点还承担了 Raft 组 Leader 调度职责。例如,当节点 1 恢复后,中心节点可命令节点 2 将 Slot 1 的 Leader 归还给节点 1,确保整个集群中各节点的 Leader 数量均衡。

3.4、Cellar 智能迁移

接下来介绍 Cellar 的智能迁移机制。如图所示,美团将桶迁移分为三个状态:

  1. 正常状态,无迁移;
  2. 开始迁移,源节点 A 创建快照并发往目标节点 B;
  3. 迁移完成后,进入代理过渡阶段;

在迁移过程中,A 节点会根据 B 节点反馈的状态(如引擎负载、网卡流量、队列长度等)动态调整迁移速度。迁移过程类似 TCP 慢启动机制,最终达到一种动态平衡 ------ 在最短时间内完成迁移,同时尽可能减少对正常业务的影响。

迁移完成后,客户端可能还未更新路由表。此时若请求到达 A 节点,A 会将请求代理至 B 节点,并返回响应的同时提醒客户端更新路由表。这样既避免了错误响应,也保证了客户端平滑过渡。

3.5、Cellar 快慢队列

下图展示了一个标准的线程队列模型:网络线程池接收请求包,解析后放入工作队列,由工作线程池处理并返回结果。

然而,在分析线上超时案例时发现:一批超时请求中,真正因引擎处理慢而导致超时的仅占约 1/20,其余都是因为排队等待时间过长

为此,美团提出了"拆线程池 + 拆队列"的优化方案:

  • 网络线程收到请求后,根据其类型(读/写)和耗时特征(快/慢)分发到四个不同的队列;
  • 每类请求由独立的工作线程池处理;
  • 请求的分类依据包括 Key 数量、Value 大小、数据结构元素数等;

这种设计实现了不同请求类型的资源隔离。例如,一个慢读请求不会阻塞快写请求的处理。

尽管线程池数量从 1 增加到 4,但美团通过线程池间的互助机制(空闲线程帮助其他队列)控制了总线程数不变,避免了资源浪费。

线上实测表明,该设计可将 TP999 延迟降低 86% ,大幅提升了系统的稳定性和成功率。

3.6、Cellar 热点 Key 解决方案

最后介绍 Cellar 的热点 Key 治理方案。如下图所示,中心节点新增了"热点区域管理"的职责。除了管理正常副本分布外,还需协调热点数据的分布。示例中,节点 C、D 被指定为热点区域。

美团通过一次完整的读写流程来说明其运作方式:

当客户端写请求到达 A 节点时,A 在处理完请求后,会根据实时统计判断该 Key 是否为热点。如果是热点,则在进行集群内复制的同时,还将数据复制到热点区域节点(C、D)。响应客户端时,A 会标记该 Key 为热点,客户端缓存该信息。

后续客户端对该 Key 的读请求将直接转发到热点区域,绕过常规副本节点,从而大幅提升热点 Key 的处理能力。

该方案的优势在于:

  • 按 Key 级别扩容 ,而非整 Slot 迁移;
  • 可动态扩展热点区域节点数量,实现负载均衡;
  • 通过实时复制机制,避免了传统客户端缓存热点带来的数据一致性问题;

✅ 结语

从 Squirrel 到 Cellar,我们围绕"高可用、低延迟、强一致"三大核心目标,构建了一套面向不同业务场景的分布式 KV 存储体系。

Squirrel 以高性能和快速容灾见长,适用于缓存类场景;Cellar 则在持久化、跨地域容灾、强一致性等方面进行了深度优化,满足金融级、支付类等对数据可靠性要求极高的业务需求。

在这两个系统的演进过程中,美团不仅解决了诸如节点宕机、网络分区、热点 Key、慢请求阻塞等常见问题,还通过智能迁移、快慢队列隔离、Raft 多副本复制等机制,实现了系统级别的稳定与高效。

这些能力的背后,是一次次线上问题的复盘、一次次架构的重构、一次次性能调优的积累。

相关推荐
青云计划11 小时前
知光项目知文发布模块
java·后端·spring·mybatis
Victor35612 小时前
MongoDB(9)什么是MongoDB的副本集(Replica Set)?
后端
Victor35612 小时前
MongoDB(8)什么是聚合(Aggregation)?
后端
yeyeye11113 小时前
Spring Cloud Data Flow 简介
后端·spring·spring cloud
Tony Bai14 小时前
告别 Flaky Tests:Go 官方拟引入 testing/nettest,重塑内存网络测试标准
开发语言·网络·后端·golang·php
+VX:Fegn089514 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
程序猿阿伟14 小时前
《GraphQL批处理与全局缓存共享的底层逻辑》
后端·缓存·graphql
小小张说故事14 小时前
SQLAlchemy 技术入门指南
后端·python
识君啊14 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端
想用offer打牌15 小时前
MCP (Model Context Protocol) 技术理解 - 第五篇
人工智能·后端·mcp