cover_image

「QQ红包」海量资金交易系统方案实践

moren 腾讯VATeam
2022年06月01日 09:56

引言 QQ红包是QQ平台的基础功能,于2015年上线,至今历时8载。不同时期,面临挑战不同,先后经历抢占支付市场、社交平台活跃和周边产品导流等多个阶段。系统从无到有,容量从千万级到亿级,玩法从普通红包到口令红包再到接龙红包,支付渠道从QQ支付到微信支付,系统架构和产品功能不断迭代和优化。亿级红包系统,如何保障资金安全、并发性能和系统可用?本文将为你介绍QQ红包海量资金交易系统的设计方案,如何为QQ用户提供安全稳定可靠并有趣的社交+支付服务。



01


系统概况


QQ红包具有三大业务特点,首先,QQ用户量庞大,海量交易数据;其次,“秒杀”式抢红包,海量并发请求;再者,资金交易系统,安全级别更严格更高。为方便大家对QQ红包系统有全局认识,先列举红包功能、支付渠道、核心交易指标和技术挑战的一些解决方案及思路。接下来,介绍QQ红包系统设计,重点讲述资金安全、海量数据、高并发和可用性等四方面的处理和实现。


图片




02



系统设计


1 系统模块

QQ红包系统自上往下,分别是QQ客户端、接入层、路由层、逻辑层和存储层等五层;由左向右,支付渠道、红包系统和其他功能模块。


图片


2 业务流程

系统基本功能包含包红包、抢红包和查询。其关键业务流程如下


图片



03



资金安全


资金安全是交易系统的重中之重,必须妥善解决。在支付交易中,资金伴随着信息而流动,两者以订单为驱动为依归,合理严谨的订单模型是红包资金安全的基础保障


1 订单模型

要了解订单模型,先介绍业务的资金流,即资金的转移过程。举个栗子,张三李四王五等1000人组建吃瓜群,群主张三在群发红包,吃瓜群友哄抢,李四王五赵六等3人抢到红包。此时,张三的钱经历了什么?去向何方,如何被化整为零,怎么完整无损转入其他人余额账户?

1.1 资金流

个人红包是典型的支付应用场景,底层资金流是C2B2C。其中,C是个人账户(用户钱包余额账户或银行卡账户),B是红包商户,用于承载红包资金,是包红包交易和拆红包入账两个关键环节的桥梁。


图片

在账户间资金流转,需要有效载体,非红包中转B账户莫属。稳打稳扎步步为营是基本准则,不限于交易系统,不仅要有凭有据,更加需要合理可靠的凭据,否则资金流乱成一团麻,账务明晰和业务可持续性就无从说起。

1.2 订单关联

在交易中,不同维度的订单环环相扣,以一推三,全局唯一,同时,遵循支付系统交易原则,先减后加。

  • 红包交易单与红包总单一一对应,保证一笔支付产生一个红包;

  • 拆红包使用数据库单机事务,保证化整为零过程的正确性;

  • 入账单与红包分单一一对应,保证转账幂等,不重复入账;

  • 红包最多退款一次,退款单与总单及交易单一一对应,保证不重复退款。


图片


图片


1.3 其他保障

处理核心订单模型设计,还有更多事前、事中和事后全流程的业务与资金安全保证措施。

  • 红包鉴权码和关系链校验等防盗拆;

  • 关键数据签名防篡改等;

  • 联合安全和风控打击外挂、黑产行为和洗钱赌博等违规行为;

  • 交易监控、对账和审计等异常发现机制。



04



海量数据


一口吃不下大西瓜,得切开;海量红包订单和高并发请求,单台服务器扛不住,得分而治之。三个臭皮匠胜于诸葛亮,况且诸葛亮不常有而臭皮匠遍地,拆分后使用有限数量臭皮匠能完成诸葛亮的事情,可见有分而治之性价比超乎想象。

订单按负载均分SET、按日期分冷热存储和按用户异构订单构造用户列表,多重拆分保证系统容量可扩展、系统解耦合和整体性能稳定

1  订单SET化,系统可扩展

SET化是把业务系统分成多个逻辑分区,任意分区可单独提供完整服务,水平可扩展从而解决系统容量问题。介绍SET架构在红包的实践

红包系统是交易系统中的订单模块,从流量均匀可控性和数据持续性上,以红包订单作为拆分对象是最合理的。注:按用户拆分,无法控制每个用户的发红包量,容易出现流量倾斜

首先包红包流程,请求随机分配任一可用红包SET,生成带SET标志的红包订单号。接下来这个红包的所有抢红包、拆红包和查询详情等操作,以红包单号为路由,定向到对应红包SET进行处理,高度内聚。
各个SET之间相互独立,提供完整包抢拆查等能力,互不影响,从而完成对红包海量请求分治。


图片


2 时间分库表,冷热分离

QQ红包作为平台基础产品功能,持续时间很长,日积月累,数据量越来越庞大。在订单SET化基础上,需要更小粒度数据存储能力,即分库分表。

如何拆分库表?按订单hash,按用户,按时间?时间粒度多大?结合QQ红包订单量级和活跃规律,QQ红包采用年库日表,既可避免单表数量过大导致数据库性能大幅下降,同时做到数据冷热分离,对数据管理有极大帮助。整表搬迁,不变更热表,让数据迁移变得更加简单可控。


图片

3 数据异构,系统耦合

订单SET化&分库分表存储,用户维度的数据如何聚合查询?如何最低成本满足用户查看本人收发记录、收发红包个数和金额的基本需求?

通过异构构建用户维度的红包列表,订单与用户数据隔离。


图片


实时流程,收发红包流水,异步拆分订单数据到消息队列,并按用户维度写入红包订单关键信息(如订单号、金额和时间等);通过滚动对账保证订单和用户列表数据的一致性;

用户先从列表服务获取红包列表,再使用红包订单号到红包SET或历史订单库查询红包详情;

用户维度数据,只存列表首页可见的信息,红包详情只有明确需要才到订单系统查询,避免过多非关键数据的冗余存储和传输,可有效节约资源。

总的来说,从水平和垂直两个方向进行拆分,抓住关键点,明确目标和边界,大系统小做,洪水也可以成为恬静溪流。



05



高并发

订单SET化,解决整体海量数据问题,转移单体的性能瓶颈压力。

然而,人人都有精益求精的追求,业务目标不变甚至提高的情况下,能否使用更少SET来满足需求?简而言之,单SET性能能否提升,做到极致

然而,实实在在的困难摆在面前,红包是资金相关的交易系统,对数据一致性和持久化有很强需求,资金安全首位,拆红包是数据库事务操作(先锁红包总单,检查红包状态和并扣减金额和数量,通过后再写红包分单),数据库容易成为系统性能瓶颈。在群组和频道场景,每个红包都相当一次商品“秒杀”活动,相对普通商品,红包秒杀的不是卖出获利的货物,而是现金,这就面临“既要安全又要快还要...”的世纪难题。

1 单机路由,本地缓存

非关键操作不读写数据库,逻辑层需要做合理有效的本地缓存,所谓“好钢用在刀刃上”。围绕两个问题,缓存什么?如何提高缓存命中率

  • 缓存内容:红包总单状态、剩余金额和数量、抢红包请求数,挡住可预见的无效抢请求落到数据库;

  • 单机路由:相同红包路由到同一服务器,提高缓存命中率,实现拆红包请求行队列化,避免在数据库层发生资源竞争;

图片

2 其他策略

使用本地缓存进行拦截,流量呈漏洞状,有效提高底层资源使用的有效性。此外,还有其他策略,提供单机吞吐量。

  • 入账异步化拆红包和入账分离,拆红包精简事务,快速响应,降低数据库SQL并发数,同时达到削峰填谷,保护下游入服务

  • 业务单元逻辑和物理上高内聚,逻辑服务和数据库就近部署,避免跨网调用和流量穿越



06



可用性


在系统设计和需求迭代中,拒绝大而全,依赖最小化,架构越简单系统越稳定,故障率越低,可用性就高。运行环境是不稳定的,通过3方面提高系统可用性。

  • 接入层、Relay路由层和SET逻辑服务部分等无状态模块,集群分布冗余部署,负载均衡,降低故障出现概率

  • 依赖模块分级,对可降级影响低的模块做柔性降级策略降低故障影响范围

  • 红包SET,服务接口联动,异常上报和统计,快速屏蔽故障点,出现故障快速恢复


这里重点讲述红包系统的故障发现和切换

1 故障发现,自动切换

故障切换过程:当红包订单DB出现故障,包红包落地上报失败,下单检测成功率下降,拒绝下单,抛特定错误,Relay路由捕捉错误上报到L5,L5调整ALLSET_L5中故障机器IP权重,流量减少,如持续不可用,机器IP将被剔除,故障Set自动下线,流量切到其他正常Set,从而实现故障发现并自动切换。反之,SET故障解除后,按规则逐步恢复流量。


图片




07



总结


以上从资金安全、海量数据、高并发和可用性等方面介绍了QQ红包系统。主要采用了SET化、多维度分库表、本地缓存、单机路由、请求排队串行化和故障发现及自动切换等设计,是典型而独特的资金交易系统解决方案,在节假日和春节实践中充分证明了可行性和可用性。合抱之木始于毫末,万丈高楼起于垒土,QQ钱包研发团队在不断迭代和优化QQ红包系统,致力为QQ钱包用户提供安全可靠的资金交易服务。


继续滑动看下一个
腾讯VATeam
向上滑动看下一个