详解网商银行“三地五中心”数据部署架构
数据库部署架构是从容量、可用性、性能、成本等多方面权衡的结果,网商银行基础架构从建行之初满足快速业务响应的分布式架构,到单元化架构的落地,再到云原生时代,其中伴随着业务的快速发展,数据库的部署架构也经过多个版本的迭代发展。
容灾方面,从最初的“两地三中心”,具备机房级容灾,不具备全部的城市级容灾,经过扩容建设发展到现在的“三地五中心”。具体部署方式如图 3-1-1 所示,采用 3-2-1 的部署方式,任意一个城市的故障,通过选主(选择主库)实现主库的切换完成容灾。
图 3-1-1 “三地五中心”架构
分布式业务应用为支撑业务容量的快速发展和业务的多样性,持续进行微服务的拆分改造,其中数据库也随着进行扩容、拆分、迁移。数据库之间的隔离性、集群故障的业务影响面愈加重要,如何合理规划业务集群,实现业务的故障影响面可控,是发展过程中一直面临的挑战。
分布式数据库
分布式数据库中的数据在逻辑上是一个整体,但物理上分布在计算机网络的不同节点上。网络中的每个节点都可以提供数据服务,可以通过中间件或者协同服务器实现协调,以代理的形式完成数据库访问的策略控制。图 3-1-2 所示为一种集中代理方式,通过协同服务器实现多应用的数据读写访问,在这种方式中应用不感知分布式的多个节点,通过协同服务器进行读写节点的路由选择、读写分离控制、权限控制等。
图 3-1-2 集中式代理与分布式数据库
分布式数据库增加了系统交互的复杂性,为系统引入了更多潜在的失败环节,但分布式系统带来的好处也非常明显。
(1)持续可用。分布式数据库对同一份数据维护多个副本,当某个副本出现故障时,其他副本还能继续正常提供服务。为避免多个副本同时服务同一份数据带来的数据一致性问题,引入分布式协议 Paxos 或 Raft 实现数据的一致性。以系统包含 3 个副本(1 个主库,2 个备库)为例,每次写事务都需要让主库和其中一个备库同步,在主库出现故障时,至少一个备库有完整的数据,数据不会丢失,可通过分布式协议完成选主,继续提供写服务。在任意一个备库出现故障时,主库仍然可以将数据同步到另一个备库,形成“多数派”,保证数据不会丢失。
(2)可扩展。通过对集群节点的扩容,完成读写容量的线性扩展,支撑大促的突发流量。
(3)低成本。分布式系统通常只需要采用廉价的普通服务器替代高端服务器与高端存储设备,通过自动容错能力实现运维成本的降低。
分布式事务与数据一致性
处理事务是数据库系统的基本能力,通过事务保证数据的准确性与一致性,从而减少了上层应用的复杂度。但数据库系统为实现事务,也进行了一定的性能牺牲。事务必须具有 ACID 属性。
lA,原子性(Atomicity):事务中多个操作要么全部完成,要么全部未完成,不存在中间状态。
lC,一致性(Consistency):事务必须始终保证系统的一致性状态,不管在什么时间,并发事务有多少。
lI,隔离性(Isolation):为了防止事务操作的混淆,必须使请求序列化,使得在同一时间仅有一个请求作用于同一数据。
lD,持久性(Durability):事务完成以后,事务对于数据的变更持久保存,不会进行回滚。
分布式事务通常是在多个节点的机器上运行,运行时有进行 RPC 的过程,相对于单系统数据库,在保证事务的原子性上会遇到更多的异常环节,存在更多的恢复与回滚情形,当前大多通过两阶段提交协议进行解决。分布式事务提交到多台服务器上进行处理时,每台服务器都需要进行日志的记录,当事务出现失败时,对应的服务器都需要进行回滚操作,典型的分布式事务处理过程。
图中左侧是协调者状态机,右侧是参与者状态机。协调者是驱动整个事务提交流程的主体,它可以在任意机器上,当然也可以和其中一个参与者在同一台机器上。参与者是真正的事务操作的执行者。协调者首先通知所有的参与者持久化(图中的 prepare 命令),当参与者使事务的日志处于持久化状态后会回复 prepare OK,当所有参与者都回复 prepare OK 后,意味着整个事务完成了。然后协调者会写下事务 commit 的日志,并且发送 commit 给所有参与者,如果其中任何一个参与者返回失败(即 abort OK),那么协调者就会认为事务是失败的,记下事务回滚的日志,并且发送 abort 给所有参与者。
在这个流程中,分布式事务提交的延迟是两次写日志(参与者写 prepare 日志,协调者写 commit 日志)的延迟和两次通信(协调者通知参与者 prepare,协调者通知参与者 commit)的延迟。
图 3-1-3 分布式事务处理过程
多租户策略
一套分布式数据库集群可以用于支持多个业务,通过分配多个数据库实例进行管理,这就是多租户策略。多租户是分布式数据库实现资源隔离与未来进行云化发展的基础,通过多租户还可以实现安全的隔离、故障的隔离、运维的隔离等。
首先是租户资源的隔离,租户是资源分配的最小单元,每个租户可以进行 CPU、内存、存储、网络带宽、连接数等的资源控制。CPU 等资源可以在租户创建时进行指定,也可以按需进行动态调整。每个租户之间的资源不进行复用,以避免资源的抢占带来的稳定性问题。
其次是安全的隔离,租户有对应的用户权限,每个租户的用户只能访问自己租户内的实例以及相关租户资源。不存在可以进行跨租户访问的超级用户,实现了安全策略的可控,避免了数据安全问题。
再次是故障的隔离,因为硬件资源的隔离,单个租户的“抖动”、资源不足、数据错误等不会影响其他租户,对于分布式数据库的监控最小采集粒度是租户级别,数据库的故障影响分析也从租户维度进行关联分析。
最后是运维的隔离,租户是资源分配的最小单元,在进行资源调度、集群扩容时按照租户进行迁移,集群的备份与恢复也从租户维度进行控制。
“异地多活”之“三地五中心”
《商业银行数据中心监管指引》要求金融机构设立异地模式的灾备中心,其中重要系统的灾难恢复能力要达到《信息安全技术 信息系统灾难恢复规范》中定义的灾难恢复等级第 5 级(含)以上。具体要求是,RPO 为数分钟到两天,RTO 为 0~30 分钟。
传统银行中最常见的是“两地三中心”模式,具备同城的机房级容灾能力,实现了同城一个机房故障下 RPO 为 0,异地数据弱一致。网商银行从“两地三中心”的“异地多活”进一步发展到“三地五中心”,实现 RP0 为 0,RTO 在 1 分钟内的城市级容灾架构,保证了银行系统的高可用和不间断的用户服务能力,实现了金融服务的随时在线。
常见部署模式
传统银行的“两地三中心”(见图 3-1-4)
图 3-1-4 传统银行的“两地三中心”
(1)同城双机房采用主备模式,应用访问主数据库,进行数据写入。
(2)同城双机房间采用存储设备的同步复制,保障同城双机房之间的数据实时一致。
(3)异地机房用异步复制方式进行数据同步,备份节点数据非强一致,对数据实时性要求不高的可以进行读访问。
(4)同城主备库之间进行故障检测,出现异常时进行主备切换。
(5)应用端可以通过使备库只读而降低主库压力。
这种部署模式本质上只能做到机房级容灾,当城市 1 异常时,城市 2 的数据是不完整的,无法实现城市级的容灾。
分布式数据库“两地三中心”(见图 3-1-5)
图 3-1-5 分布式数据库“两地三中心”
(1)“两地三中心”模式有三个副本,采用主备模式,应用访问主数据库,进行数据写入主库。
(2)主库数据实时同步到所有备库,基于一致性协议,在 1/2 的节点完成数据的同步后,即认为数据同步完成。同城机房因耗时更短,两个机房的数据保持实时同步。
(3)异地机房因耗时较长,在数据同步上有延迟,但相对于传统银行的备份节点,该延迟较小,在 1 分钟以内。
(4)两个从节点都可以提供数据的弱一致性只读服务。
三个副本中最多允许有一个故障点,所以这种模式只具备城市 2 的城市级容灾能力,不具备城市 1 的容灾能力。
分布式数据库“三地五中心”(见图 3-1-6)
图 3-1-6 分布式数据库“三地五中心”
“三地五中心”模式有五个副本,最多允许存在两个异常节点,所以采用 2-2-1 的方式进行分布建设。当任意一个城市的机房发生城市级的故障时,数据库都依然能够继续提供服务。
五副本在进行数据写入实时同步时,需要三个节点完成写入,因一个城市最大节点只有两个,所以必然会存在跨城市的实时同步,带来耗时的增加。具体耗时的增加与城市间的距离有关,例如从杭州到上海,需要增加 6~8 毫秒。
城市 3 只有单节点,无法满足城市内的容灾要求,一旦有故障,应用都需要跨城访问数据库,所以在部署时,城市 3 不进行应用的部署。由于不提供数据服务,城市 3 可以进一步降低成本,机房 5 作为日志副本,无全量数据,参与一致性协议投票选举主节点。
从“两地三中心”到“三地五中心”的升级
从“两地三中心”升级到“三地五中心”,是基础设施的重大升级,不只是简单的数据副本的增加。其带来的架构改善有以下几点。
(1)数据库具备了城市级容灾能力。
(2)应用具备了城市级容灾能力,应用的部署可以实现城市 1 与城市 2 双中心的模式,应用的容灾能力增强。
(3)数据库的容量提升,只读副本数量增加,服务能力增强。
这种升级同时也对原数据中心架构引入了新的挑战。
(1)跨城带来的耗时增加,对业务的批处理、链路整体耗时、热点行等产生影响。
(2)数据同步副本数增加,原有机房间的网络需扩容。
(3)数据同步副本数增加,原有租户的硬件资源扩容。
在架构升级的过程中,需始终保持容灾能力不降低:任何单个机房出现故障后,集群依然可用,且除了主库所在城市 1 之外的其他城市机房出现故障,集群依然可用,依然能够提供服务。其过程如下。
(1)初始状态,如图 3-1-7 所示。
图 3-1-7 “两地三中心”
(2)城市 2 新增一个副本,该副本用于数据异步式同步,不参与一致性投票,该副本对原集群结构稳定性无影响。参与投票的依然是机房 1、机房 2、机房 3,容灾策略与“两地三中心”一致,数据同步耗时无增加。“两地四副本”模式如图 3-1-8 所示。
图 3-1-8 “两地四副本”
(3)城市 3 新增一个副本,该副本数据实时同步,参与一致性投票,但需限定在选主时不能作为主库,以避免耗时的增加,因应用部署还在城市 1。在这种模式下,城市 2、城市 3 的单个城市故障不影响集群的稳定性。“三地五中心”模式如前面的图 3-1-1 所示。
(4)城市 2 的不参与投票副本切换为实时同步,并开始参与投票,完成“三地五中心”的部署。在任意一个城市的机房出现故障时,都能够实现容灾切换。
以上过程中,如果机房 5 不选择部署全量副本,只是参与投票的日志副本,那么建设周期会较短,可以直接在城市 2 建设全量副本,完成后立即进行机房 5 的配置。
应用耗时分析与优化
“三地五中心”带来的事务耗时增加了跨城耗时部分,会对业务全链路耗时、热点行、批处理产生影响,需要在架构升级前进行耗时分析,在升级后进行耗时的监控与验证。
基于分布式的 trace 中间件,使用实时计算对链路上的应用日志、数据库日志进行解析,分析出业务链路的不同场景中的库依赖、SQL 模板、SQL 执行顺序与次数。然后按照“三地五中心”建设的库关联、应用部署城市,分析会增加耗时的 SQL,从而计算出整体链路的耗时增加。根据评估结果进行耗时的优化,可考虑的方向有:缓存、应用部署、SQL 的优化,以及异步化改造等。
热点行也会因为单次事务的耗时增加导致锁冲突加剧,热点行问题更加明显。可以在建设完成后进行压测,识别热点行,并有针对性地解决热点问题。
单次耗时的增加,也会导致批处理整体完成的时间延长,需要评估是否会超出业务可接受的完成时间。可考虑的优化方案有调整批处理分组数、调整锁粒度等。
数据访问路由策略
由于单机房的容量限制以及容灾能力不足,多机房的应用与数据库部署一般有两种模式:扩展模式与镜像模式。扩展模式按照业务把应用进行分类,把相互依赖的应用部署在同一个机房中,实现业务之间的隔离。但必然存在一些业务需要多机房同时提供服务,这种模式本质上是把一个机房拆分并部署为多个机房。镜像模式下每个机房都部署相同的应用与数据库,每个机房都具备全量的业务提供能力,按照比例进行流量的调拨。运行时机房只承担一部分业务,但必然存在一些基础应用和数据无法按照流量进行比例划分,需要机房间的数据共享与同步。
网商银行在进行单元化架构改造时,根据业务情况,结合两种模式,把数据划分为三类。
(1)可进行流量调拨的数据,可以按照一定的规则进行等比例划分,实现每个机房只需要一部分数据。对应用进行镜像化部署,应用对于数据的访问在同一个机房内可以完成。应用与数据的访问情况如图 3-1-9 所示,其中每个数据库在其他机房也都有副本,以实现容灾能力。
图 3-1-9 可进行流量调拨数据的访问
(2)不可进行流量调拨的全局数据,数据库的主节点在某个机房,其他机房和城市进行数据访问会出现跨机房与跨城市情况,耗时增加较多。应用与数据的访问情况如图 3-1-10 所示,在流量调拨时,同机房调用优先进行。
(3)全局数据的耗时涉及跨城情况时,存在业务不可接受的情况。可进行流量调拨的数据分布在其他城市时,应用的访问也会出现跨城情况。这部分数据会同步到一个独立库中,该库在每个城市都有部署。全局城市级数据模式下应用与数据的访问如图 3-1-11 所示,在进行流量调拨时同机房调用优先进行。
图 3-1-10 全局数据模式下应用与数据的访问
图 3-1-11 全局城市级数据模式下应用与数据的访问
综合考虑分布式数据库主节点与副本的读写分离、应用与库的部署情况、数据库自身的负载等,应用对于数据的访问优先级如下:同机房正常状态→同城正常状态→同城高负载状态→跨城正常状态→跨城高负载状态。其中三类数据在正常和容灾场景中都按照以上策略,通过该策略可降低数据访问的耗时,实现数据库的负载均衡。
多集群部署
网商银行的数据库集群部署经历了两个阶段,从建行之初的单库、分库少量集群,通过按业务的垂直拆分、分库的水平拆分,发展到现在的用户、产品、业务、账务、交换、公共等多套集群,保障了业务快速增长过程中的高可用。
建行之初,业务分库集群有 5 套,用于支撑业务的分库,分库方式包括 10 分库、20 分库、100 分库,分配到各分集群的策略也有两种:所有分库集中于单个集群或均分到 5 套集群。这种方式可以节约运维成本,但随着业务的快速增长,单集群故障影响全行业务的情况越来越不可接受。
网商银行应用采用微服务架构,L1 层的架构如图 3-1-12 所示。
图 3-1-12 网商银行应用 L1 架构图
业务流量的流向是渠道层→业务产品层→核心层→基础服务层,其中业务产品层各产品之间的业务隔离,数据也隔离,业务产品层和核心层可以按照用户信息进行分库分表,如图 3-1-13 所示。
数据库集群要结合应用架构、相关应用对业务的影响、分库分表的维度进行设计,减轻集群故障的影响。基础服务层中 PaaS、分布式消息等进行独立集群部署;用户、产品进行独立集群部署并进行主备多集群保障;账务、交换等公共服务库独立部署;对存款、信贷、理财、支付结算等业务分别部署 10 套集群,分库均分到集群中,单集群故障影响面降低到 10%。在业务集群分拆过程中,需各业务库统一分库维度,避免因分库维度不同导致的故障影响放大,例如:单集群中两个业务库维度不同,则该集群发生故障时业务的影响由 10%增加到 19%(即 1-0.9×0.9)。
图 3-1-13 网商银行数据库集群划分
容器化部署
为什么要进行容器化部署
架构设计上为避免集群的单点,而将业务分摊到更多集群上。分布式数据库集群是由多台物理机构成的,在高可用方面集群存在多种单点,一方面集群强依赖“心跳”、系统租户等单点,另一方面,具备自动选主能力的分布式集群,遇到 SQL 导致进程中断或崩溃的情况。有限数量的物理机无法创建更多集群,而容器化技术可以在一定数量的物理机中创建出更多的数据库集群,待后面机器数量增加后,这些集群可以迁移到不同的物理硬件上,从而实现集群数量、容灾能力的提升。
如何进行容器化部署
如图 3-1-14 所示,容器化部署在物理机中按一定规格虚拟出容器,在容器中部署分布式数据库以增加集群数量。
从 ECS 部署切换到 ECS+容器化部署可按如下步骤实现灰度化。
(1)在集群中增加容器化节点,并将库的一个备节点切至容器化节点,如图 3-1-15 所示。
图 3-1-14 容器化部署
图 3-1-15 将一个备节点切至容器化节点
(2)依次替换两个容器化节点,并将主节点切至容器节点。设置选主优先级,若 ECS5 崩溃,则数据库将 ECS1 的备节点选为主节点,如图 3-1-16 所示。
图 3-1-16 将备节点选为主节点
(3)此时,若出现单容器故障,仍可回滚到 ECS 上,运行一段时间检查无误后,将 ECS1 节点替换为容器化节点,如图 3-1-17 所示。
图 3-1-17 将 ECS1 节点替换为容器化节点
分区与容器化
分区与容器化既有联系又有区别,它们都为数据库的应用提供了扩展性。业务规模较小时,容器化可以创建多套集群,满足架构设计上对多集群的需求,此时表分区通常用不到。业务规模较大时,分区在集群数量不变的情况下提供容量的扩展性,容器化提供了更细粒度的管理能力。例如,可以将同一个业务链路的上下游的相同用户的分区放到同一台或者同一组物理机上,减小单台物理机上业务链路用户范围。分区是分布式数据库提供的能力,而容器化不属于数据库本身。
《金融级 IT 架构:数字银行的云原生架构解密》
网商银行技术编委会 著
架构书中的“战斗机”!
引领数字化时代金融级别的 IT 架构发展方向
书中阐述的核心技术荣获“银行科技发展奖”
网商银行 IT 技术架构演进实践精华
本书介绍了网商银行成立至今的 IT 技术架构演进路线,涵盖了分布式、单元化、弹性混合云、云原生多个基础架构领域,同时介绍了技术风险、安全可信、业务架构等多方面的技术实践经验,我们希望和读者分享网商银行在金融级 IT 技术上做的独特探索,跟大家探讨数字化时代金融级 IT 架构的发展方向。
评论