心尊门 发表于 2020-2-19 17:04:24

谈谈热点账户(一)

经常做银行系统或者支付结算系统的同学应该对热点账户问题都很熟悉,今天我们就谈谈热点账户。在我关于微信红包的那个回答中,我提出过“对于较大型的支付公司,如果银行结算款实时入账,对于那个银行账户而言会有热点账户风险”。
那么什么是热点账户呢?我尝试简单地把我的理解和大家分享一下,希望对大家有帮助。
我们在银行、支付公司的账户,说到底就是存在数据库中的数据。
他们可能长这样(实际上不是长这样的,只是为了简单说明):


假设说,今天天顺的银行账号向匿名专家汇款0.74元,那么完成这笔转账后,天顺银行账户余额变成了35.24元,这个时候数据库里的数据变成了:


在这个过程中,数据库做了哪些操作呢?
首先,数据库需要对这条数据中的余额字段,做一次更新,减少0.74元。
在更新前,他需要对这条数据进行锁定(lock),锁定完成后,对其余额进行更新,然后释放锁定(unlock)
有同学会问,为啥要搞那么复杂呢?直接更新余额不就好了。
其实这么做是为了防止其他业务对这个余额也同时进行操作,避免不必要的数据错误,保证同一时间只有一个业务主体在对余额进行操作。
那么问题来了,假设我们数据库对数据进行一次更新需要使用10毫秒的时间,业务量小的话还行,对于一分钟要处理几千甚至上万次的话,数据库就会来不及响应,最后崩溃。
对于较大型的支付公司和机构,如果他的银行账户在每次支付成功时都实时更新余额无异于给银行带来了十分大的系统压力和数据库瓶颈,而这个账户也就是我们常说的热点账户。
即便是到IT技术如此发达的今天,热点账户依然是困扰很多银行业务系统的顽疾。
那么,我们是否对于热点账户完全束手无策了呢?
当然不是,聪明的程序员和架构师们基于很多业务场景的特殊性做了很多变通和优化,让业务可以在尽量不受热点账户影响的情况下顺利完成。
第一种方法叫做汇总入账:
银行在T日业务完成日切后,将T日发生的所有成功交易进行统计,计算出一个总账,一笔汇总入账到指定的结算账户。
这也是目前最为广泛采用的一种结算模式,基本上主流的收单系统都是沿用这套方式。
这套方案的优势很明显:数据库压力很小,日间所有交易全部是insert进表(insert的开销很小,能够支持高并发。如果基于分布式部署,insert的并发容量理论上可以无限大),日终跑批只要sum出一个结算总金额,和内部户的会计流水比对无误,就可以明确日间交易产生的债权债务总账,一笔入账结算到指定账户。
这套方案的劣势也很明显:结算账户的资金并未实时结算更新,T日的交易款要到T+1日才能结算到账,但是,既然是收单业务,这点资金时效性相对业务可用性相比还是可以接受的,何况已经成为业内标准了,所以基于收单的业务场景目前仍然沿用此模式较多。
现在很多银行的核心账务处理能力实际上已经能够支持较大并发,但收单结算的模式还是保留了下来。
请大家注意一点:汇总结算模式的存在,热点账户是其中一个原因,但不是全部原因。写这篇文章不是要告诉大家,银行收单业务是T+1结算,完全是因为热点账户造成的。汇总结算只是正好在某些条件下,缓解了热点账户问题而已。
留给大家一个思考:大家不知是否发现,微信发红包,经常是红包已经看到了提示你公司拿了X元红包,请到零钱查看,但跑到零钱后发现居然没有。
过了好大一会,零钱里才增加一条入账流水,显示红包金额,在这个过程可能发生了什么?

不知道这样的专栏文章大家是否会感兴趣呢?
睡觉了,下篇文章更新其他解决方案,由简入难慢慢写。
页: [1]
查看完整版本: 谈谈热点账户(一)