热点帐户解决方案

问题描述

在某一瞬间,单个帐户集中的发生资金变更,若不加控制,其帐户余额会因发生脏读、覆盖更新等状况而错误记录。若是简单的以悲观锁、乐观锁的方式限制,虽然不会发生数据错误,但会形成服务不可用(该帐户的更新请求所有失败)。而请求重试、再次网络通讯的开销并不能忽略不计。网络

在帐户系统的实际业务中,发生“热点帐户”状况的通常有两种:并发

局部热点帐户
还款时 一人 -> 多人
放款时 多人 -> 一人
债转时 多人 -> 一人(基于业务系统的特定场景设置,此处认为债权转出人为热点帐户)
局部热点帐户可经过分布式锁的方式处理,本文再也不赘述。框架

全局热点帐户
平台支出帐户、平台收入帐户、过渡帐户。。这些帐户老是在发生资金变更异步

全局热点帐户的解决方案分析

  • 前提

既然是普适的解决方案,那就考虑该帐户会大量并发的发生余额增长、余额减小、余额冻结、余额解冻的操做,其中余额冻结和余额解冻可视同为增、减,简化模型,下面以Hot帐户为例分布式

  • 思路

1.收到请求 -> 2.落库待处理,返回处理中 -> 3.落库数据批量汇总处理,状态控制 -> 4.返回处理结果(取决于第2步)
第2步可根据实际业务,返回成功(例如业务上余额无限大的帐户或者容许为负值的帐户)优化

  • 示意图

图片描述

  • 说明
  1. H帐户初始资金为0,几乎同时收到请求:H帐户放款给A帐户100,放款给B帐户100,C帐户还款给H帐户50,D帐户还款给H帐户250
  2. 数据按顺序落库后,跑批任务汇总处理,假设每次处理3条
  3. 第一个批次通过计算,发现余额不足,因而将(3)余额增长的操做先执行,并更新状态,(1)、(2)不执行也不更新
  4. 第二个批次通过计算,余额充足,执行全部操做并更新状态
  • 冻结/解冻

虽然冻结至关于减,解冻至关于增,可是冻结得优先于解冻执行,因此最终得出了以下执行顺序:
增->冻结->解冻->减spa

Q&A

  • 实时余额如何获得

首先我要问,什么场景下咱们须要获得实时余额?图片

判断钱够不够扣,够不够冻结?
No no no,咱们要求热点帐户的资金处理都必须异步,这意味着请求发过来只会获得处理中,成功与否咱们会通知你。并且就是你查询的时候钱充足,并不意味着发生变更的时候也充足,这类查询是没有意义的。要么像ZF这类钱永远充足的帐户,查询就更没有意义了事务

财务、审计。。whatever须要统计数据?
这个能够有,咱们将帐户余额和缓冲记录表内的数据实时计算告诉你。可是不要说我实时计算的余额不许,由于会有未提交的事务balabala。。那么亲,这和热点帐户不要紧,即便你查询一个很是普通的帐户,碰巧该帐户同时在更新,你也查不许。。实时计算的余额在那一瞬间是准确的,并且我认为这类需求不会很大it

  • 一些特殊帐户有优化吗?
  1. 只增不减、只减不增的帐户,上述的框架是能够包含解决的,也不必特殊优化
  2. 资金永远充足的帐户,在流程的第2步,能够落库后返回成功
  3. 若是H->A的划帐要求两个帐户事务一致性,那么就须要对咱们流程第2步中的表作修改了,将H->A整个落库,后批量处理
相关文章
相关标签/搜索