谈谈账户系统的系统性能设计
数据库优化
对于这个部分相信每个公司都有自己的数据库规范,一般来说根据自己公司的规范做好应该不会有太大问题。这里应该包括有命名的规范、索引的设计、sql的开发设计、sql的优化、数据库的切分等。
这里先说几个点,后续这里另外写独立的文章。
我们在开发的过程中应该尽量避免下面几点:
- 超过255字节字段
- 内置函数:数据库的资源是十分宝贵的,比如一些date之类的函数,能尽量在业务层处理完就在- - 业务层处理。不用放到数据层处理
- 存储过程:存储过程有很多好处,预编译提高了相应的效率。但是不利于移植。这一点见仁见智。
- 触发器:在实际的工作经历中,触发器的效率是比较低下的,避免使用。
- 长事务:避免占用资源
- 多表联合查询:尽量业务层处理
- 批量查询:批量处理属于慢服务,不应该和快服务混合在一起。有条件的话建议批量查询有独立的数据库进行支撑。
读写分离&&快慢分离
在金融系统中是可以将一些服务切分为快服务和慢服务的。例如:
- 快服务:实时支付、转账、提现等等操作
- 慢服务:账单查询、对账、protal上的一些统计查询(当日交易、当月交易等)
对于上述的情况,一般来说,我们可以进行主备机方案、将实时系统的数据同步到慢服务的库中,慢服务的独立出来,这样不会占用实时服务的资源。
并发处理&&并行处理
缓存处理&&预先处理
缓存是每个系统中基本都会用到的东西,架构设计中没有什么是加多一层不能解决的问题。
对于一些热点的数据都必须做缓存处理。
红包问题
红包问题的难点主要有两个,一个是抢 的动作,一个是账户的出账,即热点账户的问题。
因为并没有真实得做过红包,但是听过腾讯的一些方案,这里给出一种方案,大家一起探讨一下。
我们这里给发红包用户开的户有余额户、待结算户(商户可选)、以及红包账户。给到用户开的户是余额户。
我们注意到这里还有一个问题,就是抢红包的时候还是对红包账户会有一定的压力,这里可以对红包账户进行物理的切分,即给到A多个红包账户,之后对红包的抢操作进行相应的路由。这些就是比较灵活的做法。
旁路降级
服务的降级熔断对流量大的服务是非常必要的。
- 旁路:在紧急的情况下对业务进行抽查性的检查,例如风控类,限额类的检查等。或者只对金额高的进行检查等等策略。
- 降级:紧急情况下牺牲非关键特性、降低高可用需求,例如高峰期只记录错误的日志、使用内存日志。相关的报文从记录DB改为记录本地文件。
异步处理
异步处理在大流量场景非常有用。
例如一个支付的流程可能包括:记录订单、账户操作、记录风控、通知商户
可选的做法可以是
- TCC(记录订单、账户操作)、(异步)记录风控、(异步)通知商户
- (事务)记录订单、(异步)账户操作、(异步)记录风控、(异步)通知商户
当然,要保证异步信息的发送成功才能算一个流程的成功,并返回。
第二种做法可能会有账户操作不成功的情况。所以第二种的适用场景可以选择如下:
- 如果是入账的情况,可以选择第二种,实时扣款、异步入账。这样如果有不成功的情况,公司不会承担风险。
- 快捷支付,因为快捷支付一般都是小额支付,并且有相应的较小限额处理,这样也能降低风险成本。
异步处理同适用于退款,先受理,后通知结果。
水平扩展
我们常常讲网站架构的五个点:高可用、可扩展、可伸缩、安全、性能。
- 这里的水平扩展其实指的是可伸缩这个特性,要保证增加的机器数量和性能是线性的关系。
其实我们经常提起微服务,就是希望将服务拆分得足够细,并且解耦。但是因为拆分了服务,有可能会出现的情况就是,由于网络波动的影响,有时候发现某台机器占用很高,后面排查又没有任何问题。我们是不是可以考虑将所有的业务放在一台机器上,水平扩展的时候将所有的服务都再部署一份。当然这个没有具体的答案,但是据说腾讯账户确实是如此做的。并且叫OMP(业务服务集群)。