探索AIGC电商新纪元,火山引擎《云上新视界》公开课等你来报名! 了解详情
写点什么

支付系统如何进行分布式改造

  • 2019-09-06
  • 本文字数:5104 字

    阅读完需:约 17 分钟

支付系统如何进行分布式改造

《企业级 Agents 开发实战营》重磅上线,10 周带你进行工具、对话及多模态等不同类型 Agents 工程化开发实战!

传统支付系统面临的挑战

随着近年来移动支付的兴起 ,如条码支付、声波支付、NFC 近场支付等,随之还产生了聚合支付把多种支付方式聚合在一起,方便人们的使用,移动支付已经渗透到我们生活的每一个角落,不带钱包出门已经没有任何阻碍。


这就给传统的支付系统提出了新的挑战,用户量激增,系统容量和性能跟不上了。传统的架构往往以 IOE 技术为主,采用 scale up 方式以更强的硬件提升系统性能和容量,扩容成本将是巨大的。


支付机构是持牌机构,都有受到监管,对系统稳定性有强要求,传统架构下往往都会用冷备的方式来进行容灾,意味着又要投入一倍的成本。由于数据库主备复制的延时,必须等到数据同步完成才可以切换,容灾切换时间长,进行分布式改造已经刻不容缓。


分布式架构有着海量、成本、稳定、速度的优势,其核心思想是“解决一切单点”,单点容易出故障、性能有瓶颈,那么就拆分成多个点。垂直拆分能更清晰化模块划分,区分治理,水平切分能解决大数据量性能瓶颈问题,分布式改造主要是将这两者结合起来对传统架构进行改造。

分布式改造之垂直拆分

垂直拆分就是将原来一个整体的系统按业务模块拆分成多个系统。系统内部数据是自包含的,不会与别的系统共用数据库,系统与系统之间的交互通过暴露和调用服务来实现。那么如何按照业务来拆分呢?


为了方便理解,首先我们来看一下一笔支付过程是如何进行的:



图:简化的支付路径图(注:该图来自蚂蚁金服内部)


  • 商户发起收单请求,经过 API 网关,调到产品层的“在线收单”产品

  • 调用收银台选择支付方式,也可能直接进入支付环节,创建交易流水

  • 进行支付处理,通过金融交换从银行扣客户帐,记录帐务流水,入商户帐,记录账务流水

  • 对交易按照费率进行收费,记录收费的帐务流水。此时会异步触发营销和风控策略

  • 日终会异步进行会计记帐(也有同步记会计帐的)、业会核对、清结算和对帐处理


那么从这个过程我们就可以大概推演出支付系统的一般应用架构:



图:支付系统的应用架构


那么如何进行垂直拆分呢?刚刚我们推演的应用架构派上用场了。


什么是应用架构:应用架构定义一个大型软件系统由哪些应用子系统构成,以及应用之间如何分工和合作。好的应用架构抽象合理、协作有序、易于扩展、能够复用。有了这个应用架构,我们可以非常清晰的根据应用架构划分的子系统来拆分。


从架构上来说,分为四层:



图:支付系统的分层


渠道层:商户和客户的交易请求的入口。一般会划分以下系统:商户网站、用户网站、无线接入、API 网关。


产品层:通过基础服务层提供的服务组装成具体业务场景功能,对客户、商户运营等人员提供服务。一般会把服务商户的功能划分为商户域,服务 C 端用户的划分为用户域。可以按照这两个域拆分成两个子系统,也可以更进一步根据不同产品特性再拆分,比如商户域中的收单产品、虚拟产品、垂直行业产品。


公共服务层:将各个产品都需要使用的些服务抽像成公共服务。一般会划分:收银台、交易支付、计费等系统。比如说产品层可以通过组装各种交易类型和收费规则形成不同的产品。


基础业务层:支付系统的核心,资金和客户信息的处理都在这里。一般会划分三大子系统:帐务核心、会计核心、会员核心。


其它支撑系统:


网关:负责与银行、银联等金融机构进行资金交换,与外部合作伙伴接入,如渠道拓展商、行业客户等。一般划分:银行接入网关和合作伙伴接入网关。


运营支撑:贯穿于四个层的是运营支撑域:一般会划分运营支撑、安全、风控、营销子系统。


垂直拆分本质上是服务化改造,除了上面的讲的按业务拆分,还需要一套分布式服务框架的支撑。

分布式改造之水平拆分

前面讲的垂直拆分只是把系统按业务模块划分到不同的子系统,数据库也分到了不同系统,但没有解决单表大数据量的问题,而水平切分就是要把一个表按照某种规则把数据划分到不同表或数据库里。简单的说就是做分库分表。


在做分库分表之前我们需对数据模型进行分类,分为“流水型数据”、“状态型数据”和“配置型数据”。


  • 流水型数据:像流水一样不断增长的数据,各条数据间是独立的。如支付订单、交易流水、帐务流水(入帐/出帐)、会计流水等。

  • 状态型数据:代表一个对象当前的状态的数据。如会员信息、客户信息、帐户信息、会计帐。


为什么有会员信息还有客户信息?会员往往是注册在支付平台的用户,一个人可以注册多个会员,但是一个自然人只可能有一个客户信息,一个会员通过实名认证后就关联上了客户信息。无论一个客户注册多少个会员,实名认证后都只有一个客户信息。


  • 配置型数据:系统中用作为配置的数据。如产品、手续费率、分支机构信息、支付路由规则、会计科目等。


流水型数据会不断产生,且各条数据间是独立的,天然适合进行分库分表。


状态型数据读写比相当,每一次写操作必须基于前一个正确的状态,可以评估一下数据量的大小,数据量如果大或者要实现单元化架构,也需要进行分库分表,提高并发处理能力,同时方便隔离故障影响。如果使用 mysql 数据库,单表最好不要超过五百万条记录。


配置型数据,读多写少,强依赖读,弱依赖写,不要求严格的读一致性,且配置型数据一般数据量不会很大,不需要进行分库分表设计。但是业务处理中往往又需要用到,传统架构的老系统可能使用了一些关联表操作,关联到了配置数据,分库后其它数据与配置不在一个库,不能进行关联表操作,由于配置型数据不要求严格的读一致性的特点,可以将配置型数据加载到分布式缓存里,如 redis、memcached,由业务代码来做“join”。


那么分库分表按照什么规则来拆分呢?通常我们不会按实体 id 进行 hash 取模的方式来拆分。因为我们希望同一个用户的数据能够在同一个数据库中,尽量避免产生分布式事务。那么业界普遍的做法是通过用户维度来进行拆分。由于不同的实体 id 的值不同,且不能保证每个实体和请求中都包含用户 id,所以简单的用实体 id 或用户 id 进行 hash 取模将不能保证同一个用户的数据都落在同一个分片。


我们的做法是在用户创建的时候给该用户随机或一定规则(如地区)生成一个两位的分片号 00~99(两位意味着可以分成百库百表,通常够用了),那么在生成与该用户相关的所有实体的 id 的时候都约定把这个分片号拼接到这个 id 中。那么在分布式数据访问框架中进行路由选择时就可以取 id 中的分片号进行路由,而不依赖于用户 id。且在排查问题的时候也非常方便定位数据的存储位置。


下面是一个参考的 id 生成规则示例:



所以数据水平拆分除了需要一个强大的分库分表数据访问中间件,还需要一个分布式序列生成器。当然这个生成器也可以是集成在分库分表数据访问中间件中的一个功能。


那么如果一笔交易涉及多个用户按谁的 id 来拆分呢?比如一笔转账或支付,涉及转出方/转入方或支付方/收款商户。这种情况我们一般按资金转出方来拆分。

分布式改造后带来了哪些问题,如何应对

1. 分布式事务产生

由于按用户维度进行了分库分表,可能存在跨数据库的事务,比如说转账交易中转出方和转入方的账户不在同一个数据库中,这就产生了分布式事务。通常我们不会用 XA 协议来解决,因为 XA 协议锁资源性能太差,通常是通过 TCC 柔性事务来解决。

2. 跨表查询如何解决?

由于分库分表后,不能进行跨库的连表查询,原来的一些很常见的查询操作变得很麻烦。对于不是以用户为维度的汇总查询也非常麻烦。比如说支付交易流水是按发起方用户(支付方)进行拆分的,用户需要查询自己的账单很容易。但是商户要查询账单就比较麻烦了,要去所有的库里遍历、汇总、分页。也非常耗系统资源。所以一般会做一些数据冗余,比如说蚂蚁内部是专门做了一个账单系统,通过消息队列异步将用户的交易流水同步过来,T+1 跑批再按商户维度进行拆分,并生成商户账单。查询帐单都从帐单系统中查询。


还可以通过异构索引来查询和做 OLAP 分析,异构索引就是将数据同步到 ElasticSearch,利用 ES 的强大索引能力来做查询和分析,为了使业务更容易使用,可以利用数据访问代理层来屏蔽底层是路由到数据库还是路由到 ES。

3. 如何进行数据同步?

企业都有做大数据分析的需求,需要将数据同步大数据平台,如 hadoop,分库分表之后,数据同步会比较复杂,毕竟之前是单表同步到 hadoop 比较简单,但是 100 张表同步到 hadoop 里会复杂一些。


我们需要有一套数据模型管理平台,数据模型、分库分表规则等由这个平台来管理,当需要使用数据的时候通过(应用/逻辑表)维度订阅数据即可,不用单独订阅物理表。不仅是数据同步,凡是有业务需要用到各种数据,都可以通过这个平台来订阅,帮助企业数据业务快速发展。

4.分库分表后批处理任务怎么处理?

批处理任务,比如有日终对账、清算、生成账单等,原来在一个数据库中的时候,由一个应用 Server 去数据库中捞取流水就可以了。但是分库分表后流水都落在很多库里,一个 Server 去每个库里遍历显然不是一个很好的办法,且不能充分利用机器资源,提高批处理效率,甚至由于处理的数据量太大在日终低峰期内根本无法完成任务。


前面提到各条流水数据之间没有关联的,完全可以并发的进行处理,每个 Server 捞取一个分片的数据进行处理。那么就需要有一个很好的调度系统来协调,可以采用三层调度的方式。



图:三层调度示意图


  • 第一层 split:把任务按照分片规则拆分成多个 Load 任务,并发送到集群中的 Server 去执行。

  • 第二层 load:每个 load 任务捞取一个分片的数据,逐条创建 execute 任务,并发送到集群中的 Server 去执行。注意:捞取数据要进行流量控制以免数据量太大把集群打满。

  • 第三层 execute:执行具体的一条数据的逻辑。


三层架构并不是说一定都需要三层,可以根据业务逻辑来定制只有两层也可以。

5. 如何进行数据扩容?

通常我们会采用“预分配”的方式来做,即一开始我们就按一个比较长期的容量来规划分片数,比如百库百表,但实际上一开始并没有这么大的量,所以实际只有两个数据库 Server,在这两个 Server 上分别建 50 个 schema,逻辑上扔然是 100 个分库,物理上只有 2 个数据库 Server,当容量不够的时候,为了保证数据的均衡,我们通常会采用成倍扩容的方式,再加两台数据库 Server,然后分别迁移 25 个 schema 到这两个数据库 Server 上,数据也搬过来,由于数据同步有延时,全量数据同步完成后,两边的 schema 都禁写,待增量数据同步完成后打开新的 schema 写,会产生短暂的部分用户交易失败,重试一下即可,在低峰期做迁移,产生小范围失败一般是可以接受的。由于逻辑分片数没有变化,扩容成本比较低。我们通常不会用改变分片规则的方式来扩容,因为改变分片规则需要进行数据重新分布,成本和风险巨大。

6. 如何进行容灾?

  • 同城容灾:通常可以同城多机房部署应用,数据库只有一个机房处于 Active 状态,所有机房的应用都连这个机房的数据库,另一个机房的数据库为备库,进行主备复制,当备机房发生灾难时业务不会中断,但业务会跌一半,当主机房发生灾难时,数据库切换备库,会有短暂的业务中断。

  • 异地冷备:应用也是异地多机房部署,由于异地网络延时不可忽略,异地备机房是处于 standby 状态,正常是没有流量的,冷备机房采用数据库主备同步的方式同步数据,这种方式灾备切换时间长,成本投入高。

  • 异地多活:应用采用异地多机房单元化部署架构,每个机房的应用都是可以提供服务的,单元内是自包含部署全量应用,每个单元服务多个分片的用户,单元化架构可以参考《素描单元化》。由于异地网络延时是不可忽略的,数据层的容灾方案也是分“流水型”、“状态型”、“配置型”数据采用不同的容灾策略。具体可参考《分布式系统数据层设计模式》。

7. 如何更好的排查和分析问题?

分布式改造后整个系统架构已经是服务化了,原来通常可以通过查本地日志来定位问题。但现在一个交易由若干个系统协同完成,我们需要一套分布式链路跟踪系统或 APM(应用性能管理)系统来协助我们看清整个系统的全貌,分析排查问题。那么如何进行分布式链路跟踪呢?可以通过 opentracing 标准对整个分布式架构中的中间件和应用进行埋点或自动植入探针实现。

总结

分布式架构有着海量、成本、稳定、速度的优势,但它也不是银弹,分布式改造是一个非常复杂的工程,需要熟悉业务,设计出整个系统的业务架构,按照业务架构来进行垂直拆分。需要熟悉数据模型,区分“流水型”、“状态型”、“配置型”数据,根据不同类型数据的特点将它他按用户维度进行拆分。


熟悉分布式中间件的运用,分布式中间件在整个分布式架构中起着至关重要的作用,将技术构架与业务结合起来。整个改造需要公司内部下定决心,All in 的方式进行。蚂蚁金服通过十五年五代金融级架构的演进,多年双 11 的考验,形成了一套业界领先的金融级分布式架构。


本文转载自公众号蚂蚁金服科技(ID:Ant-Techfin)。


原文链接:


https://mp.weixin.qq.com/s/G232Ro3OhaPfrfgQAhPhNA


2019-09-06 10:393551
用户头像

发布了 150 篇内容, 共 32.3 次阅读, 收获喜欢 38 次。

关注

评论

发布
暂无评论
发现更多内容

英特尔深耕元宇宙算力技术,剑指开“元”盛世

科技新消息

最好用的七大顶级 API 接口测试工具

蒋川

API 测试工具

潮玩盲盒一番赏盲盒星球app专业源码搭建

风行无疆

优秀的代码的分层结构

xcbeyond

架构 28天写作 12月日更

记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑

Jerry Wang

JavaScript ajax 跨域 28天写作 12月日更

一周信创舆情观察(12.6~12.12)

统小信uos

Apache Log4j 2 安全漏洞扫描及启示录

极狐GitLab

gitlab 安全 供应链 漏洞扫描 Apache Log4j 2

分布式架构与性能优化

高性能架构探索

分布式 微服务 性能优化 内容合集 签约计划第二季

ClickHouse在工业互联网场景的OLAP平台建设实践

京东科技开发者

【Spring Boot 快速入门】一、周末建立了Spring Boot专栏,欢迎学习交流

小阿杰

SpringBoot 2 spring Boot Starter 内容合集 签约计划第二季

开发者故事|朝九晚六大小周,我就是快乐的技术人

尔达Erda

程序员 云原生 经验分享 成长笔记 思考路径

自身的强大,无惧任何威胁!

Tiger

28天写作

【实战】网络安全学习:内网渗透实例

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 内网渗透

百度王海峰:深耕自然语言处理近30年,推进AI融合创新

百度开发者中心

自然语言处理

【Spring Boot 快速入门】二、Spring Boot集成MyBatis可以连接数据库啦!

小阿杰

SpringBoot 2 mybatis配置 内容合集 签约计划第二季

基于社交网络的客户智能 ( AI ) 推荐系统研究

索信达控股

推荐系统 推荐算法 个性化推荐

Istio在Rainbond Service Mesh体系下的落地实践

北京好雨科技有限公司

istio PaaS rainbond

行业分析| 泛娱乐应用出海探索

anyRTC开发者

音视频 语音通话 视频直播 视频通话 泛娱乐

探探的IM长连接技术实践:技术选型、架构设计、性能优化

JackJiang

网络编程 websocket 即时通讯 IM

Rainbond 5.5 发布,支持Istio和扩展第三方Service Mesh框架

北京好雨科技有限公司

istio PaaS rainbond

一篇教你代码同步 Github 和 Gitee

冴羽

JavaScript GitHub 自己搭建博客网站 GitHub Pages vuepress

CSS之选择器(七):empty

Augus

CSS 12月日更

多点 DMALL x StarRocks:实现存储引擎的收敛,保障高查询并发及低延迟要求

StarRocks

数据库 数据分析 高并发 StarRocks

京东云PostgreSQL在GIS场景的应用分享

京东科技开发者

SD-WAN、SASE 和多云空间的未来趋势

devpoint

5G SD-WAN sase 12月日更

Go 语言快速入门指南:第一篇 介绍

宇宙之一粟

Go golang 编程入门 签约计划第二季 12月日更

低代码如何让中小型企业蓬勃发展?

低代码小观

低代码 企业管理系统 低代码平台 中小企业

Explore the Sky丨来 TiDB Hackathon 2021 探索无限可能

PingCAP

Go 数据库 hackathon TiDB database

Android C++系列:Linux Socket编程(三)CS模型示例

轻口味

28天写作 12月日更

滨海中小企业协会参加新区工商联(总商会)第四次代表大会

InfoQ 天津

点击下载 | 世界经济论坛全新推出深度AI洞察报告

澳鹏Appen

人工智能 机器学习 深度学习

支付系统如何进行分布式改造_文化 & 方法_Geek_cb7643_InfoQ精选文章