热点账户处理
互联网交易中,当某一商家交易量大的时候,商家对应的账户更新的比较频繁,该商家对应的账户记录会变成热点行,该商家的账户就是热点账户。通常热点账户会导致各种系统问题,对数据库也会造成很大压力。
热点账户分类
根据资金流动的方向可以把热点账户分为「加频账户」、「减频账户」和「双频账户」。 其中「加频账户」是指资金流入比较频繁的账户,比如商家的收款账户;「减频账户」是指资金流出比较频繁的账户,比如商家的退款账户;「双频账户」指流入和流出都比较频繁的账户,比如商家在电商平台开设的内部户。
热点账户识别
在交易系统中可以通过提前配置、 实时统计和同步的方式来识别热点账户。历史的热点账户可以提前配置到系统中,在交易过程中可以利用流式计算的思路实时统计账户请求量,当请求量达到阈值将账户信息同步到系统的热点账户名单中。系统整体架构如图 1 所示。
图 1
热点账户问题解决方案
1. 限流
热点账户问题的根源是大量请求并发竞争账户的操作权,账户的操作权是稀缺资源,所以我们可以减少单位时间内对账户的操作次数,所以「限流」通常是最直接有效的解决方式。限流简单来说就是超出我能力范围的不处理。如图 2 所示。
图 2
虽然限流能明显减少对账户的操作,但限流是通过拒绝交易来达到目的,通常会影响客户体验,这种方式通常作为系统保障的兜底措施。
2. 缓冲
缓冲的方式就是同步转异步来处理交易请求。互联网交易热点通常具有瞬时性,可以先把请求接下来,比如缓冲到消息队列中,并将结果返回给调用方。然后在从消息队列中取出交易数据进行处理,借助消息队列的「削峰填谷」的特性来消除瞬时的热点。如图 3 所示。
图 3
但缓冲的方式可能会导致请求大量积压,如果积压的量超过日处理能力的上限,可能会导致循环积压的问题。由于缓冲队列消费不及时可能会导致账户金额更新不及时,这种情况下可以采用全局缓存来缓存账户信息,将数据放到缓冲队列前,先更新缓存中账户数据。这种方式比较适合处理瞬时的热点数据。
3. 合并请求数据
我们还可以合并用户的请求的方式来削减单位时间内对账户的操作次数。先将明细数据保存下来,然后使用单独的 worker 来汇总明细数据,并更新账户数据。如图 4 所示。
图 4
这种方式也会造成账户数据更新上的延迟,同样可以采用全局缓存的方式来缓存账户信息,保存明细数据的同时更新缓存中的账户信息。
4. 分治
账户的操作权是稀缺资源,除了减少账户操作次数这一思路之外,我们还可以利用分治的思想,给主账户创建多个影子账户,将主账户的资金分散到影子账户中,通过一定的路由规则,将交易请求发送到不同的影子账户上。如图 5 所示。
图 5
这种方式带来的问题是,如何来平衡影子账户的资金和如果账户资金不足要扣减多个账户的时候怎么处理。
缓存
缓存是高并发系统的又一大利器,在以上方案中也有缓存的应用,总体思路是将账户数据同步到缓存中,缓存数据异步刷新到数据库中。这种方式需要考虑缓存和数据库数据一致性的问题,如果发生数据不一致的情况,可能需要根据明细数据进行对账操作。
总结
处理热点账户的问题需要根据具体业务和应用场景来具体处理,选择合适的解决方案,最重要的是需要保证账户数据的一致性。