连载中 13/18

热点账户:余额更新的锁冲突突围

2026-06-21 · 5096 阅读 · 0 评论 · 0 赞

一个账户拖垮全链路

大促当天,老王的账户服务告警雪崩。肇事者是一个头部商户:平台代收代付模式下,它每秒几千笔交易,每一笔都要 update 同一行余额。AT 模式下全局锁自旋重试挤成一团,换成普通本地事务也一样——数据库行锁把几千个更新排成一条长队,单行更新就是天然的串行点,这不是分布式事务的问题,是谁来都一样的问题。本篇专治这个病。

解法一:缓冲记账,把减法变插入

核心思路:别让每笔交易都去碰余额那一行。交易发生时只 insert 一条流水明细(插入互不冲突,天然高并发),余额的更新由汇总任务批量合并——比如每秒把一千条明细合并成一次 update,行锁竞争次数从一千降到一:

交易时:insert 流水(账户, +金额, 状态=待入账)     ——无冲突
汇总任务:每秒聚合流水 → update 余额 +1000 一次   ——冲突趋近于零
可用余额 = 落账余额 + 待入账明细合计

代价要想清:余额不再实时,「可用余额」要靠余额加待入账明细现算;防透支逻辑也要挪到明细层(入账前校验累计待扣是否超限)。适合收单类场景(只进不出压力小),出账实时性要求高的场景要谨慎。

解法二:子账户,把一行拆成 N 行

把一个热点账户拆成 N 个子账户(或叫影子账户),交易按某种散列(交易 ID 取模)轮询打到底部 N 行上——一行热点变 N 行温点,吞吐直接乘 N。查询余额时汇总 N 个子账户求和。代价:总余额可能分布不均(某个子账户扣穿了而别的还有富余),要配余额调度(子账户间调剂)或允许局部失败重试路由到别的子账户;对账维度也从一行变 N 行。适合「只增不减好办、加减混合要调剂」的账户。

解法三:TCC 冻结,绕开余额行

第 4 篇的 TCC 在这里焕发第二春:Try 阶段不碰余额行,只 insert 一条冻结明细(冻结单,无锁冲突);Confirm 时按冻结单异步批量划账,Cancel 时作废冻结单。余额行依然存在,但更新被合并成批量,热点被明细表摊平——本质上这是「缓冲记账」与「预留模式」的合体,用 TCC 的框架纪律(幂等、空回滚、防悬挂)保证批量划账的可靠性。资金安全敏感、又要高并发的账户,这是最正统的姿势。

解法四:入口限流,最后的一道闸

如果业务允许,最省事的方案是把对热点账户的更新 QPS 限在行锁能承受的范围,超出的请求排队或失败重试。适合低频大额场景(大额转账本来就不该秒级并发),不适合 C 端海量小额。

四路对比

方案吞吐提升主要代价适用
缓冲记账高(合并更新)余额延迟、防透支挪明细层收单、只进不出
子账户随拆分数线性余额不均要调度、对账翻倍加减混合
TCC 冻结高(批量划账)开发成本 + 三大坑防御资金敏感高并发
入口限流无(控制流入)业务等待或失败低频大额

老王的落地组合

最后老王按账户类型分层:个人账户 QPS 低,普通更新加索引就够;头部商户的代收账户用缓冲记账;代付占比高的用 TCC 冻结 + 批量划账;大额转账入口限流。一个服务多种方案并存,热点治理的本质是识别哪些账户热、热到什么程度,再按热度分配复杂度——给所有账户上缓冲记账,和给所有账户硬扛行锁一样,都是懒政。

小结

热点账户一句话:单行更新是天然串行点,缓冲记账变减法为插入,子账户拆行分压,TCC 冻结合批绕行,限流兜底;按账户热度分配方案复杂度。账户的问题解决了,链路上还有一类问题同样磨人:远程调用的超时到底是成是败、重试会不会把小故障放大成雪崩——下一篇:超时与重试。

503

10 年全栈工程师 · 503咖啡馆主理人

#分布式事务#热点账户#缓冲记账#子账户#TCC

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞