听说你觉得旁路缓存很Low?蚂蚁金服一面:高并发下的 Redis 顶级连环炮,你能扛到第几问?
公众号名称:Fox爱分享
作者名称:Fox爱分享
发布时间:2026-06-01 07:00
去大厂面试过的人都知道,缓存可不是简单的 Get/Set。面试官最喜欢的套路,就是先从一个你自以为完美的方案切入,然后通过层层递进的极端场景死里整你,直到把系统逼到崩溃边缘,看你到底能不能扛住。
今天直接还原一场真实的蚂蚁一面现场。这 6 个直击灵魂的 Redis 高并发连环炮,看看顶级的后端架构师是怎么“降维打击”的。
一. 多级缓存怎么做的,考虑了哪些缓存一致性问题,多个服务器本地缓存、Redis缓存、DB之间数据一致性怎么解决?
单把压力丢给 Redis,在高并发(比如十万级 QPS)的极限压榨下,网络 I/O 和单点热点一样会成为瓶颈。所以,真正的核心系统都是玩多级缓存架构的:
-
一级缓存(本地内存):直接用 Caffeine 部署在 App 节点内存里,速度是纳秒级的,完全没有网络开销。
-
二级缓存(分布式缓存):Redis 集群,负责承载海量共享数据。
-
三级存储(持久化层):MySQL / TiDB 兜底落盘。
怎么防脏数据?“Canal + MQ 异步双删 + 本地自过期”

多个服务器的本地缓存、分布式 Redis、底层 DB,三者要做到最终一致,最稳妥的打法是靠数据变更流水线:
-
DB 与 Redis 的一致性:写完 DB 后,直接删 Redis(是删除,别去更新)。为了防止并发读写时旧数据回写,用 Canal 监听 MySQL Binlog,一旦 DB 变了,Canal 异步抓取并投递到 MQ,由消费者去执行 Redis 的二次删除(带失败重试),确保 Redis 干净。
-
多个服务器本地缓存的一致性:某个节点改了数据,通过 MQ 的广播模式(Broadcast) 发通知。所有 App 节点收到消息后,同时把自己的 Caffeine 本地缓存失效掉。
-
绝对兜底:本地缓存必须设一个极短的过期时间(比如 5~10 秒)。哪怕 MQ 偶发性延迟,本地缓存也会快速自动过期,重新去 Redis 抓取,完成弱一致性兜底。
二. 旁路缓存太low了,而且你是高并发,并不能很好的解决这个问题,面试官举例了很多数据一致性实现方案
面试官潜台词:别总拿着 Cache-Aside(旁路缓存)当银弹。先改 DB 再删缓存,在高并发读写交织的极限拉扯下,100% 会漏出脏数据。在我们这种体量下,哪怕万分之一的概率也是灾难。你还知道哪些更硬核的一致性方案?
嫌旁路缓存 Low,那就必须甩出下面这三个在不同高并发场景下的演进方案:

方案一:Read/Write Through(读写穿透)
把基础存储设施封装成一个统一的 Cache Provider。业务代码根本不碰 DB,只跟缓存抽象层打交道。
-
Read Through:缓存有就返回;没有,由缓存组件自己去刷 DB 并回填,再给业务。
-
Write Through:写请求来时,缓存组件同步负责将数据更新到缓存和 DB,两边都成功了才返回。这种方式代码解耦极好,但对中间件的封装要求高(Redis 官方不直接提供,得自己硬编码封装)。
方案二:Write Behind Caching(异步回写)
这是标准的操作系统 PageCache 刷盘思想。高并发写过来,只改缓存,立马返回成功。缓存层后面挂着异步线程池或者定时任务,批量、合并地把数据异步刷进 DB。
-
恐怖的吞吐量:比如一秒内某个热点商品库存被扣了 100 次,合并成一条 扔给 MySQL。DB 压力直接降到冰点。
update count = count - 100 -
致命软肋:有强一致性时间窗口。如果数据还没刷进 DB,缓存服务器拔电源了,数据直接蒸发。只适合点赞、游戏扣血等高频但“少金”的场景。
方案三:分布式锁强一致方案
如果业务容不得半点脏数据(比如金融资产交易),别想了,老老实实上 Redisson 读写锁(RReadWriteLock)。写请求加排他锁,读请求加共享锁。用细粒度的锁把并发读写强行串行化。虽然吞吐量有损耗,但能斩断所有产生并发脏数据的根源。
三. 秒杀问题,redis做预扣减,问题在哪里?
用 Redis 的单线程特性,拿 Lua 脚本或者 DECRBY 做库存预扣减,确实是扛流量的标准姿势。但要是在生产环境,这个方案有三个巨大的坑:

-
“少买”与“超卖”的拉扯风险: Redis 预扣减成功了,但后续用户取消订单、或者支付超时,这时候必须回滚 Redis 库存(加回来)。如果回滚的时候服务正好重启、网络丢包,这部分库存就卡死在里面了,导致商品没卖完、后面的人又买不到(少买)。反之,如果运维看数据不对人工去刷,又极容易引发超卖。
-
热点 Key 直接把单台 Redis 顶死: 预扣减意味着所有人都在争抢同一个商品的 Key。哪怕你 Redis 分片集群再大,这个 Key 也只能落在其中一台机器上。几十万 QPS 轰过来,那台机器的 CPU 瞬间就会被 Lua 脚本或者 命令打满,网卡直接爆掉,整个集群跟着一起卡死。
DECR -
链路异步化产生的“体验断层”: Redis 扣减成功后,是靠 MQ 异步去创建订单和扣减 DB 的。如果下游 MQ 堆积了,用户在前端看着“抢购成功”,结果等了半天进不去支付页面;或者后面 DB 真正扣减时发现用户触发了风控导致订单失败,这种“先给希望再绝望”的体验在金融级场景里是很危险的。
四. 宕机了你怎么解决,容灾处理之后,还是有一部分数据丢失了你该怎么办?
容灾第一步:多机房高可用架构
应对 Redis 宕机,标准回答必须是跨机房双活 + Cluster 自动选主。Master 暴毙,Sentinel 或 Cluster 秒级内把 Slave 顶上去。前端 App 配合 Redisson 驱动,动态感知拓扑变更,自动切换连接。
极端情况:容灾切过去了,但还是丢了一部分数据怎么办?
因为 Redis 的主从复制是异步的(或者 AOF 刷盘是 everysec 每秒刷盘),Master 挂掉的那一瞬间,还没来得及同步给 Slave 的那部分数据,就是彻底丢了。这时候绝对不能慌,两步走:

-
立刻熔断,保护下游:降级限流,把前端疯狂重试的流量挡住,绝对不能让流量穿透到 MySQL。
-
“唯一流水号 + 状态机”异步对账修复: 所有进 Redis 的核心请求,在网关层必须生成全局唯一的 Business_Snowflake_ID(业务流水号)。这时候立刻拉起异步数据对账重放任务:去扫上游落盘的原始日志(比如 Nginx 精确日志、网关持久化日志或者 MQ 里的历史消息),用流水号去跟现在的 DB/Redis 里的状态做比对,查漏补缺,把缺失的请求“重放”补回来。
五. 对账补偿之后还是有一部请求的数据丢失了,这时候怎么办?

面试官开始极限施压:日志也丢了,或者对账系统发现数据对不上、压根找不到这条记录了,这时候数据彻底蒸发了。作为金融级高并发架构师,你怎么收场?
技术手段已经玩到头了,这个时候必须把技术的高可用,转为业务层面的柔性容错:
-
业务状态机强行重置(全量倒推): 数据对不上了,直接启动全量 DB 倒推覆盖。以持久化 DB 里的强一致性数据为准,重新构建 Redis 里的全量数据。宁可让业务稍微延迟展示,也绝对不能让脏数据继续蔓延。
-
金融级业务的“冲正”与“挂账”: 在蚂蚁这种场景下,如果涉及到资金流水凭空消失,系统必须支持反向冲正交易。设立专门的差错挂账账户,通过离线平台的清算总账对账,一旦发现资金对不上,直接挂单,由风控和财务介入进行人工或自动化补账。
-
用户侧体验补偿(拿钱解决): 如果是营销、秒杀类请求数据丢了,导致用户扣了钱却没收到货。前端引导展示:“系统正在紧急处理中…”,安抚情绪。后端直接触发自动化补偿:给受损用户发一张无门槛大额代金券、加倍积分、或者全额退款并致歉。架构师必须明白一点:技术解决不了的极端漏洞,要靠业务规则和钱来兜底。
六. redis一直宕机起不来,甚至你的容灾策略都出问题了,你该怎么办?
终极绝杀:集群全盘崩溃,主从全死,备用机房也起不来。这时候,怎么保证整个核心系统不整体瘫痪?
这是真正的灾难演练。回答的精髓只有八个字:断臂求生,极限降级。

-
第一步:切断依赖,绕过 Redis(Bypass) 配置中心(如 Nacos / Apollo)立刻下发最高级别的强控降级指令。所有业务系统的代码逻辑瞬间切换:所有原本需要经过 Redis 的读写逻辑,全部绕开!
-
第二步:核心读请求——拿静态数据挡枪 对于商品详情、首页推荐等读请求,App 直接返回本地内存(Caffeine)里的缓存,或者直接返回写死在网关层、CDN 层的 静态 JSON 兜底数据(比如“系统繁忙,请稍后再试”)。绝对、绝对不准让这十万级的 QPS 穿透到 MySQL,否则底层数据库一秒就会被卡死,全站彻底瘫痪。
-
第三步:核心写请求——流量漏斗 + MQ 盲写 如果是下单、支付等必须处理的写请求:
-
在网关层用漏斗算法强行限流 99% 的流量,只放 1% 的边缘流量进来。
-
进来的写请求,不经过任何 Redis 校验,直接“盲写”投递到 RocketMQ / Kafka 中。利用 MQ 极高的写吞吐和磁盘持久化能力,把请求先死死堆积住。
-
后端消费服务开启极低速的单线程,根据下游 MySQL 的实时承受能力,慢条斯理地消化 MQ 里的消息,完成最终落盘。
- 第四步:绿色隔离区重建 Redis 在运维开辟的干净隔离环境中,重新搭建一套崭新的 Redis 集群。通过最新的 DB 快照或离线数据进行热点数据预热。确认新集群稳定后,通过配置中心灰度放开流量(1%、5%、20%…100%),逐步把系统恢复到正常状态。
💡 总结
蚂蚁一面的这几道题,核心不是考你 Redis 的命令怎么写,而是考你在极端恶劣、甚至系统彻底瘫痪的环境下,如何通过架构设计保护住最核心的资产(底层数据和数据库)。优秀的架构师,不仅要会搭高大上的多级缓存,更要会写各种“擦屁股”的降级兜底方案。
🔥 欢迎关注公众号「Fox爱分享」
专属于后端开发者的硬核技术充电站。在这里,没有毫无营养的搬运,只有深入底层的源码剖析、高并发生产环境的踩坑实录、以及直击大厂一线的面试通关秘籍。


原创 Fox爱分享 Fox爱分享
内容效果不满意?点此反馈