2318 字
约 7 分钟
9
S25-J12 · 分布式与微服务题库:高可用、锁、事务与隔离

适用读者:冲架构师岗、要回答"你怎么保证高可用/一致性"的人。
前置:S17(分布式与中间件)、S25-J11(MQ)、J09/J10。
覆盖旧文:3465(分布式面试题,7 域)、3481(分布式锁高可用)、3482(分布式事务)、3485(高可用)、3486(服务隔离)、3471(熔断策略)→ 6 篇 / 约 8 万字符。
扩展点:E-S25-037(高可用的度量与四层手段)、E-S25-038(分布式锁的五个坑与工业级方案)、E-S25-039(分布式事务五方案对比与选型)、E-S25-040(隔离与熔断的边界)。
上一篇:S25-J11 · 消息队列与 Kafka 题库:不丢、不重、不乱序
下一篇:题库层第 7 篇 · 高并发系统设计题(待写)。


1. 一句话结论

高可用不是"多加机器",是"把故障域切小 + 让失败可降级 + 让恢复可验证"。 面试的三段式回答:量化目标(几个 9、MTTR 多长)→ 故障域与手段 → 验证与演练。

出处:A-3465、A-3485(高可用)、A-3481(分布式锁)、A-3482(分布式事务)、A-3486(隔离)、A-3471(熔断)。


2. 高可用的度量与四层手段(E-S25-037)

可用性 年停机 常见手段
99% 87.6 h 单机 + 备份
99.9% 8.76 h 主从 + 自动切换
99.99% 52.6 min 多可用区 + 熔断降级
99.999% 5.26 min 多地域 + 单元化 + 演练

四层手段(从便宜到贵):

层 手段 边界
冗余 多实例、多副本、多 AZ 只防"单点",不防"共因故障"(同机架/同版本 bug)
隔离 线程池/信号量/集群/机房隔离 隔离粒度越细,资源利用率越低
降级 关非核心、返回兜底数据、静态化 需预先设计"降级开关"与业务确认
可观测与演练 指标 + 告警 + 混沌演练 没演练过的切换 = 没做

判据(必答):MTTR 比 MTBF 更重要——真实系统一定会故障,能不能 5 分钟内恢复决定可用性等级。

共因故障清单:同一物理机、同一机架、同一网络出口、同一配置中心推送、同一次全量发版、同一份缓存 key 热点。


3. 分布式锁:五个坑(E-S25-038)

① SETNX lock any_value        → 释放时可能删掉别人的锁
② SET lock val NX EX 30       → 原子加锁 + 过期,正确起点
③ value 用唯一标识(UUID)    → 释放前比对,Lua 保证原子
④ 业务超时 → 锁过期 → 别人拿到了  → 需 watchdog 续期
⑤ 主从异步复制 → 主挂后从无此锁  → 可能双持锁
坑 后果 解法
非原子加锁(SETNX + EXPIRE 分两步) 中间宕机 → 永不过期死锁 用 SET ... NX EX 单命令
无唯一 value 误删他人锁 value=UUID,Lua 比对后删
无续期 长任务锁提前释放 watchdog(Redisson 默认 30 s/10 s 续期)
等待策略粗暴 空轮询打爆 Redis 指数退避 + 最大等待≈锁平均持有时间
主从切换 双客户端同时持锁 Redlock(有争议)或 ZK/etcd(CP)

选型判据:

场景 选择
高吞吐、可容忍极小概率双持 Redis(AP)
绝对不能双持(金钱/库存扣减) etcd/ZK(CP)+ fencing token
单机多线程 本地锁(ReentrantLock)

"fencing token"是加分项:锁服务返回单调递增序号,下游资源校验序号——即使双持锁,旧锁的写也会被拒绝。


4. 分布式事务五方案(E-S25-039)

先分清两类上下文(高频追问):

类型 场景 方案来源
数据库实例间 分库分表跨库更新 ShardingSphere 等中间件(XA/柔性)
跨服务业务层 下单→扣库存→支付 Seata 等协调器
方案 机制 一致性 性能 适用
2PC/XA 协调者 prepare/commit 强一致 差(锁资源久、协调者单点) 短事务、低并发
3PC 加 canCommit 阶段 减少阻塞 更差 教学为主
TCC Try 预留 / Confirm / Cancel 最终一致(业务侵入大) 好 资金、库存
Saga 长事务拆本地事务 + 补偿 最终一致 好 长流程、跨多服务
本地消息表 / 事务消息 本地事务 + 消息投递 最终一致 好 异步解耦型业务

TCC 的三个坑(必答):

① 空回滚:Try 未执行,Cancel 先到 → 需"防悬挂"(记录 Try 标记)
② 幂等:Confirm/Cancel 可能重复 → 唯一键/状态机
③ 悬挂:Cancel 先执行,Try 后到 → 需按事务 ID 拒绝迟到的 Try

判据:强一致要付性能代价,最终一致要付"补偿逻辑 + 幂等 + 对账"的复杂度。选型先问"业务能否容忍中间态"。


5. 隔离与熔断的边界(E-S25-040)

隔离的六种形态:

形态 手段 代价
机房/地域隔离 核心业务独立机房 成本最高
集群隔离 VIP 与普通用户分集群 利用率下降
服务隔离 独立部署 + 独立数据库 运维复杂
线程池隔离 每依赖一个线程池 线程数膨胀
信号量隔离 计数限并发 不支持超时(同步阻塞)
数据隔离 分库分表/独立 schema 跨库查询难

一个常见误区(原文强调):核心与核心之间也要隔离——都部署在一台机器上,宕机就一起挂。

熔断的三态与阈值:

CLOSED →(错误率 > 50% 且样本 ≥ 20)→ OPEN →(等待 30 s)→ HALF_OPEN
HALF_OPEN → 试探成功 → CLOSED;失败 → OPEN

阈值设计要点:按错误率 + 最小样本量双条件(防少量请求误熔断);OPEN 期间快速失败 + 走降级;不要对强依赖下游熔断后静默返回空——要有业务兜底(缓存/默认值/人工)。


6. 场景题:一句话答法

问题 答法
你的系统怎么保证高可用 目标 SLA → 故障域 → 冗余/隔离/降级/演练 → MTTR 指标
分布式锁怎么保证高性能 锁粒度小(分段锁)、等待用退避、锁内不放大事务
跨服务一致性怎么保证 优先本地消息表;资金类 TCC;长流程 Saga + 对账
熔断会不会误伤 双条件阈值 + HALF_OPEN 试探 + 按接口分级

7. 反例:五种"听起来高级"的错答

说法 问题
"用 Redis 分布式锁就万无一失" 主从切换会双持锁;必须配 fencing/CP 存储
"2PC 是最可靠的,所以我们用它" 性能与协调者单点问题;高并发不适用
"加了副本就高可用" 共因故障(同机架/同版本 bug)照样全挂
"熔断就是返回默认值" 静默兜底会掩盖故障,需告警 + 业务确认
"TCC 就是两阶段提交" TCC 是业务层预留/确认/取消,与 XA 的资源锁不同

8. 自测

  1. 四个 9 与五个 9 的年停机时间?为什么 MTTR 比 MTBF 重要?
  2. 分布式锁的五个坑?什么是 fencing token?
  3. 2PC / TCC / Saga / 本地消息表 的一致性与性能如何取舍?
  4. TCC 的空回滚、悬挂、幂等分别怎么解?
  5. 熔断的阈值为什么要"错误率 + 最小样本量"双条件?
答案
  1. 52.6 min / 5.26 min;系统必然故障,恢复速度决定可用性等级。
  2. 非原子加锁、无唯一 value、无续期、粗暴等待、主从切换;fencing = 单调序号,下游校验拒绝旧锁写入。
  3. 2PC 强一致低性能;TCC 最终一致高性能高侵入;Saga 适合长流程;本地消息表适合异步。
  4. 防悬挂(记录 Try)、唯一键/状态机幂等、按事务 ID 拒绝迟到 Try。
  5. 防少量请求(如 2 个失败)造成误熔断。

9. 下一篇

题库层第 7 篇 · 高并发系统设计题(约 60 篇旧文)—— 限流器与阈值设定、短链、直播评论、秒杀库存、IM 推送的标准答法与容量估算。


本篇属于系列《S25 · 求职与面试》。旧文来源:A-3465/3471/3481/3482/3485/3486;扩展点 E-S25-037/038/039/040。技术细节以 duplicate_ref 指回 S17 主讲系列。

S25-J12 · 分布式与微服务题库:高可用、锁、事务与隔离
https://www.clxhxhhr.top/posts/5593/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。