交易系统平台工程师面试宝典 - 第4节

第4章 技术基础:数据库与缓存:索引优化、事务隔离级别、Redis高可用与缓存策略

本章核心能力画像:掌握索引设计原则、事务隔离机制(MVCC)、Redis高可用架构与缓存一致性策略。目标:在高压交易场景下,既能保证数据正确性,又能支撑毫秒级响应。
数据库与缓存核心考点 索引优化 事务隔离与MVCC 缓存策略与高可用 最左前缀 & 覆盖索引 索引下推与回表优化 RR vs RC 选型 MVCC + Next-Key Lock 缓存穿透/击穿/雪崩 主从 + 哨兵 / 集群
面试加分点:主动关联业务场景(如秒杀库存扣减)来展示隔离级别选择;提及“先更新DB再删缓存 + 延迟双删”的一致性方案;强调Redis哨兵与集群的故障转移机制。
---

面试问题1

问题:MySQL索引有很多种,你在交易订单场景中如何设计索引?请结合联合索引的最左前缀原则说明优化思路。

考察点:是否理解B+树索引结构;能否根据业务查询模式设计联合索引;是否清楚索引下推、覆盖索引等优化。

回答框架:
1. 确认核心查询 WHERE 字段(如 userId + status + createTime)。
2. 按最左前缀原则建立联合索引 (userId, status, createTime),字段区分度由高到低。
3. 利用覆盖索引避免回表,例如索引包含 orderAmount 即可免除回表。

示例回答:
“订单详情页最常见查询是userId+status+createTime排序。我建立联合索引(userId, status, createTime),遵循最左前缀,userId区分度最高放最左。同时把orderAmount作为覆盖索引列,EXPLAIN显示Using index,避免回表。分库分表后还设计了全局主键索引。”

可能追问:索引下推是如何减少回表次数的?联合索引字段顺序调换后性能会如何?

避坑提醒:不要回答“每个字段建单独索引”,MySQL通常一条SQL只能用一个索引;不要忽视 order by 排序也可能用到索引。

面试问题2

问题:MySQL的RR(可重复读)和RC(读已提交)隔离级别在交易系统中如何选择?MVCC如何解决幻读?

考察点:是否理解隔离级别差异;MVCC实现机制;能否根据业务冲突场景权衡。

回答框架:
1. 区分RR与RC:RR可重复读,RC读已提交。
2. MVCC通过ReadView + undo log实现非锁定读;RR的ReadView在事务第一个快照读时生成,RC每次生成新ReadView。
3. RR利用Next-Key Lock防止幻读,RC只加Record Lock。

示例回答:
“交易中库存扣减等写密集场景,我选择RC避免间隙锁导致死锁,配合乐观锁或行锁保证并发。查询报表用RR保证重复读一致性。MVCC在RC下每次快照读都生成新ReadView,能看到已提交更新;RR则在事务开始就固定ReadView,再配合Next-Key Lock防止幻读。”

可能追问:什么情况下RR也会出现幻读?间隙锁对性能有什么影响?

避坑提醒:不要认为RR完全避免幻读(快照读不会幻读,但当前读可能幻读);不要忘记解释Next-Key Lock是记录锁+间隙锁的组合。

面试问题3

问题:项目中使用Redis作为缓存层,如何保证高可用?遇到缓存穿透/击穿/雪崩时如何解决?

考察点:Redis高可用方案(主从、哨兵、集群)的选型;缓存失效场景的防护策略。

回答框架:
1. 高可用:常用主从 + Sentinel(自动故障转移)或Redis Cluster(分布式、自带高可用)。
2. 缓存穿透:布隆过滤器判断key是否存在 + 缓存空值(短过期)。
3. 缓存击穿:热点key永不过期 + 互斥锁(SETNX)。
4. 缓存雪崩:过期时间加随机值 + 本地缓存兜底 + 限流降级。

示例回答:
“订单量高场景使用Redis Cluster 6分片3副本,自动故障转移。穿透:布隆过滤器拦截非法key,同时缓存空值5秒。击穿:热点商品key不设过期时间,后台异步更新,配合互斥锁防止并发重建。雪崩:基础key过期时间加3~5分钟随机偏移,读不到时加载本地缓存并异步刷新Redis。”

可能追问:布隆过滤器如何移除元素?如何解决缓存与数据库一致性问题?

避坑提醒:不要只说“加锁”而不说明锁粒度;缓存空值需注意空值过多导致内存浪费;一致性方案优先讲“先更新DB再删缓存”+延迟双删。

项目案例:订单中心缓存与索引优化实战

STAR 表达图 —— 订单中心缓存与索引优化 S 背景 日均千万订单 T 任务 查询性能提升10倍 A 行动 索引+缓存+架构优化 R 结果 TP99 20ms 联合索引 + 覆盖索引 Redis缓存 + 布隆过滤器 RC隔离 + 乐观锁 查询耗时从200ms降到30ms 缓存命中率 98.5% 死锁率降低 90% 系统稳定支撑千万级订单
项目名称 交易订单系统缓存与索引改造
业务背景 订单中心日均千万笔订单,查询维表(订单列表、详情页)QPS高峰5万+,数据库成为瓶颈。
规模指标 日订单量 1200万+,峰值 QPS 8万,DB 慢查询占20%,TP99 200ms。
技术栈 MySQL 8.0 + Redis Cluster 6.0 + Sentinel + MyBatis + ShardingSphere
核心难点 1. 联合索引字段顺序难以覆盖所有查询条件;2. 热点商品缓存击穿导致DB雪崩;3. 高并发下死锁频发(RR级别间隙锁)。
面试高频追问 · 为什么选择RC隔离级别?死锁如何排查?(用 SHOW ENGINE INNODB STATUS 分析)
· 布隆过滤器误判率如何控制?(设置合适的bit大小和hash函数)
· Redis主从同步延迟导致缓存不一致怎么办?(读取从库前判断主从延迟,延迟大于阈值走DB)
可迁移话术 “面对高并发查询,我首先分析业务查询模式,建立联合索引并用覆盖索引减少回表。对于热点数据,采用‘缓存+布隆过滤器+本地缓存’多层防护,将缓存击穿影响降到最低。同时,将DB隔离级别改为RC并结合乐观锁,死锁率降低90%。这套思路在后续的促销活动订单查询中也成功复用。”
面试金句:将项目难点量化为具体指标(TP99 200ms→20ms),并主动引出技术选型权衡(RR vs RC、主从延迟容忍度),让面试官感受到你的系统设计闭环能力。