传统支付系统面临的挑战
随着近年来移动支付的兴起 ,如条码支付、声波支付、NFC 近场支付等,随之还产生了聚合支付把多种支付方式聚合在一起,方便人们的使用,移动支付已经渗透到我们生活的每一个角落,不带钱包出门已经没有任何阻碍。这就给传统的支付系统提出了新的挑战,用户量激增,系统容量和性能跟不上了,传统的架构往往以 IOE 技术为主,采用 scale up 方式以更强的硬件提升系统性能和容量,扩容成本将是巨大的。支付机构是持牌机构都是受监管的系统资源不够无法完成api,对系统稳定性有强要求,传统架构下往往都会用冷备的方式来进行容灾,意味着又要投入一倍的成本,由于数据库主备复制的延时,必须等到数据同步完成才可以切换,容灾切换时间长。进行分布式改造已经刻不容缓。
更多关于传统架构与分布式架构对比请参考《》
分布式架构在容量、性能、稳定性、成本方面都具有巨大的优势。在高可用方面,核心思想之一是“解决一切单点”,单点容易出现故障,性能方面也可能成为瓶颈,因此需要将单点改造拆分成多个点。垂直拆分能更清晰化模块划分,区分治理,水平切分能解决大数据量性能瓶颈问题,分布式改造主要是将这两者结合起来,对传统架构进行全面的改造。
分布式改造之垂直拆分
垂直拆分就是将原来一个整体的系统按业务模块拆分成多个系统,系统内部数据是自包含的,不会与别的系统共用数据库,系统与系统之间的交互通过暴露和调用服务来实现。那么如何按照业务来拆分呢?
为了方便理解,首先我们来看一下一笔支付过程是如何进行的:
从这个过程可以大概推演出支付系统的一般应用架构:
图:支付系统的应用架构
应用架构定义一个大型软件系统由哪些应用子系统构成,以及应用之间是如何分工和协作的。好的应用架构抽象合理、协作有序、易于扩展、能够复用。有了这个应用架构,我们就可以非常清晰的根据应用架构划分的子系统来进行垂直拆分。
从架构上来说,分为四层:
图:支付系统的分层
渠道层:商户和客户的交易请求的入口。一般会划分以下系统:商户网站、用户网站、无线接入、API 网关。
产品层:通过基础服务层提供的服务组装成具体业务场景功能,对客户、商户运营等人员提供服务。一般会把服务商户的功能划分为商户域,服务 C 端用户的划分为用户域。可以按照这两个域拆分成两个子系统,也可以更进一步根据不同产品特性再拆分,比如商户域中的收单产品、虚拟产品、垂直行业产品。
公共服务层:将各个产品都需要使用的些服务抽像成公共服务。一般会划分:收银台、交易支付、计费等系统。比如说产品层可以通过组装各种交易类型和收费规则形成不同的产品。
基础业务层:支付系统的核心,资金和客户信息的处理都在这里。一般会划分三大子系统:帐务核心、会计核心、会员核心。
其它支撑系统:
网关:负责与银行、银联等金融机构进行资金交换,与外部合作伙伴接入,如渠道拓展商、行业客户等。一般划分:银行接入网关和合作伙伴接入网关。
运营支撑:贯穿于四个层的是运营支撑域:一般会划分运营支撑、安全、风控、营销子系统。
垂直拆分本质上是服务化改造,除了上面讲的按业务拆分,还需要一套分布式服务框架的支撑。
分布式改造之水平拆分
前面讲的垂直拆分只是把系统按业务模块划分到不同的子系统,数据库也分到了不同系统,但没有解决单表大数据量的问题,而水平切分就是要把一个表按照某种规则把数据划分到不同表或数据库里。简单的说就是做分库分表。
在做分库分表之前我们需对数据模型进行分类,分为“流水型数据”、“状态型数据”和“配置型数据”。
为什么有会员信息还有客户信息?会员往往是注册在支付平台的用户,一个人可以注册多个会员,但是一个自然人只可能有一个客户信息,一个会员通过实名认证后就关联上了客户信息。无论一个客户注册多少个会员,实名认证后都只有一个客户信息。
流水型数据会不断产生,且各条数据间是独立的,天然适合进行分库分表。
状态型数据读写比相当,每一次写操作必须基于前一个正确的状态,可以评估一下数据量的大小,数据量如果大或者要实现单元化架构,也需要进行分库分表,提高并发处理能力,同时方便隔离故障影响。
配置型数据,读多写少,强依赖读,弱依赖写,不要求严格的读一致性,且配置型数据一般数据量不会很大,不需要进行分库分表设计。但是业务处理中往往又需要用到,传统架构的老系统可能使用了一些关联表操作,关联到了配置数据,分库后其它数据与配置不在一个库,不能进行关联表操作,由于配置型数据不要求严格的读一致性的特点,可以将配置型数据加载到分布式缓存里,由业务代码来做“join”。
那么分库分表按照什么规则来拆分呢?通常不会按实体 id 进行 hash 取模的方式来拆分。因为希望同一个用户的数据能够在同一个数据库中,尽量避免产生分布式事务。业界普遍的做法是通过用户维度来进行拆分。由于不同实体 id 的值不同,且不能保证每个实体和请求中都包含用户 id,所以简单的用实体 id 或用户 id 进行 hash 取模将不能保证同一个用户的数据都落在同一个分片。
一种推荐做法是,在用户创建的时候给该用户随机或一定规则(如地区)生成一个两位的分片号 00~99(两位意味着可以分成百库百表,通常够用了),那么在生成与该用户相关的所有实体的 id 的时候,都约定把这个分片号拼接到这个 id 中。在分布式数据访问框架中进行路由选择时,就可以取 id 中的分片号进行路由,而不依赖于用户 id。且在排查问题的时候也非常方便定位数据的存储位置。
下面是一个参考的 id 生成规则示例:
所以数据水平拆分除了需要一个强大的分库分表数据访问中间件,还需要一个分布式序列生成器。当然这个生成器也可以是集成在分库分表数据访问中间件中的一个功能。
那么如果一笔交易涉及多个用户按谁的 id 来拆分呢?比如一笔转账或支付,涉及转出方/转入方或支付方/收款商户。这种情况一般可以按资金转出方来拆分。
分布式改造后带来的问题如何应对
分布式事务产生
由于按用户维度进行了分库分表,可能存在跨数据库的事务,比如说,转账交易中转出方和转入方的账户不在同一个数据库中,这就产生了分布式事务。通常不会用 XA 协议来解决,因为 XA 协议锁资源性能太差,通常是通过 TCC 柔性事务来解决。具体可以参见进阶阅读《》。
跨表查询如何解决
由于分库分表后,不能进行跨库的连表查询,原来的一些很常见的查询操作变得很麻烦。对于不是以用户为维度的汇总查询也非常麻烦。比如说支付交易流水是按发起方用户(支付方)进行拆分的,用户需要查询自己的账单很容易。但是商户要查询账单就比较麻烦了,要去所有的库里遍历、汇总、分页。也非常耗系统资源。所以一般会做一些数据冗余,例如专门实现一个账单系统,通过消息队列异步将用户的交易流水同步过来,T+1 跑批再按商户维度进行拆分,并生成商户账单。查询帐单都从帐单系统中查询。
还可以通过异构索引来查询和做 OLAP 分析,异构索引就是将数据同步到 ,利用 ES 的强大索引能力来做查询和分析,为了使业务更容易使用,可以利用数据访问代理层来屏蔽底层是路由到数据库还是路由到 ES。
如何进行数据同步
企业都有做大数据分析的需求,需要将数据同步大数据平台,如 。分库分表之后,数据同步会比较复杂,毕竟之前是单表同步到 比较简单,但是 100 张表同步到 里会复杂一些。这时就需要设计一套专门的数据模型管理平台,数据模型、分库分表规则等由这个平台来管理,当需要使用数据的时候通过(应用/逻辑表)维度订阅数据即可,不用单独订阅物理表。不仅是数据同步,凡是有业务需要用到各种数据,都可以通过这个平台来订阅,帮助企业数据业务快速发展。
分库分表后批处理任务怎么处理
批处理任务,比如有日终对账、清算、生成账单等,原来在一个数据库中的时候,由一个应用 去数据库中捞取流水就可以了。但是分库分表后流水都落在很多库里,一个 去每个库里遍历显然不是一个很好的办法,且不能充分利用机器资源,提高批处理效率,甚至由于处理的数据量太大在日终低峰期内根本无法完成任务。
前面提到各条流水数据之间没有关联的,完全可以并发的进行处理,每个 捞取一个分片的数据进行处理。那么就需要有一个很好的调度系统来协调,可以采用三层调度的方式。
图:三层调度示意图
三层架构并不是说一定都需要三层,可以根据业务逻辑来定制只有两层也可以。
如何进行数据扩容
通常可以采用“预分配”的方式来做,即一开始就按一个比较长期的容量来规划分片数,比如百库百表。但实际上一开始并没有这么大的量,所以实际只有两个数据库 ,在这两个 上分别建 50 个 ,逻辑上仍然是 100 个分库,物理上只有 2 个数据库 。当容量不够的时候,为了保证数据的均衡,通常会采用成倍扩容的方式,再加两台数据库 ,然后分别迁移 25 个 到这两个数据库 上,数据也搬过来。由于数据同步有延时,全量数据同步完成后,两边的 都禁写,待增量数据同步完成后打开新的 写,会产生短暂的部分用户交易失败,重试一下即可,在低峰期做迁移,产生小范围失败一般是可以接受的。由于逻辑分片数没有变化,扩容成本比较低。通常不会用改变分片规则的方式来扩容,因为改变分片规则需要进行数据重新分布,成本和风险巨大。
如何进行容灾如何更好的排查和分析问题
分布式改造后整个系统架构已经是服务化了,原来通常可以通过查本地日志来定位问题。但现在一个交易由若干个系统协同完成系统资源不够无法完成api,我们需要一套分布式链路跟踪系统或 APM(应用性能管理)系统来协助我们看清整个系统的全貌,分析排查问题。那么如何进行分布式链路跟踪呢?可以通过 标准对整个分布式架构中的中间件和应用进行埋点或自动植入探针实现。
总 结
分布式架构有着海量、成本、稳定、速度的优势,但它也不是银弹,分布式改造是一个较为复杂的工程,既需要熟悉业务,能够设计出整个系统的业务架构,按照业务架构来进行垂直拆分,又需要熟悉数据模型,区分“流水型”、“状态型”、“配置型”数据,根据不同类型数据的特点将它他按用户维度进行拆分,还需要熟悉分布式中间件的运用。分布式中间件在整个分布式架构中起着至关重要的作用,将技术构架与业务结合起来。蚂蚁金服通过多年金融级架构的演进,经过多年双十一大促的验证,已经形成了一套业界领先的金融级分布式架构,请参考《》。
相关热文