返回 登录
0

京东金融分布式数据中间件CDS

作者:王义林,任职于京东金融,负责数据库中间件研发工作。在职期间带领CDS研发团队推出了多项数据库相关的产品,包括CDS分库分表中间件、作业平台、离线数据中心等产品。
本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅2017年《程序员》

传统关系数据库(RDBMS)强调数据一致性甚于性能,是目前所有公司核心业务的首选。但是,随着业务数据量飞速增长,单机数据库存在明显的性能和容量瓶颈,无法满足高并发和高性能的访问需求,因此如何规避传统单机数据库的缺点是目前人们重点关注的问题。分库分表产品在这种背景下应运而生,根据实现方式主要分为:ORM框架层分库分表(MyBatis、Hibernate)、基于Spring AOP方式分库分表、基于JDBC API层的分库分表和基于应用与数据库间代理层的分库分表。京东金融中间件团队在分析了这些实现方式利弊后,根据自身业务特点实现了基于客户端的分库分表中间件CDS,即Completed Database Sharding。

CDS系统框架

CDS是一个基于客户端开发的分库分表中间件产品,实现了JDBC标准API,支持分库分表、读写分离和数据运维等诸多功能,提供高性能、高并发和高可靠的海量数据路由存取服务,业务系统可近乎零成本进行接入,目前支持MySQL、Oracle和SQL Server三种数据库集群。

CDS系统主要分为几个模块,如图1所示:

图1  CDS系统架构图

  1. CDS Driver:实现JDBC标准API,轻量级分库分表中间件,以Jar包方式集成到应用程序中。
  2. CDS Server:高可用服务集群,分库分表集群配置服务中心,对外提供一致性服务。CDS Driver通过RESTful服务从CDS Server端获取规则,CDS Console产生的应用事件也通过CDS Server推送到应用端。
  3. CDS Console:CDS集群控制台,主要包括集群配置管理、在线应用性能监控以及应用配置在线变更推送等功能。
  4. CDS运维工具:集群数据查询及数据变更工具MyDB、集群环境检查工具、全量数据迁移平台和增量数据同步作业等。
  5. CDS数据中心:使用ElasticSearch+HBase框架,提供离线数据多维度查询、数据统计等功能。

CDS功能特性

CDS系统以客户端分库分表中间件CDS Driver为基础,结合配置服务中心CDS Server、运维控制台CDS Console以及丰富的数据运维工具集,提供了非常强大的分库分表基础数据服务。

图2  CDS系统功能特性

分库分表

为了满足京东金融多业务线需求,CDS提供多种分库分表方案,主要包括以下特性:

  1. 切分键:支持单列切分键、复合切分键(多列组合)、级联切分键(多级路由规则)和查询切分键(多维度查询)。
  2. 路由策略:支持对数字、日期和字符串等类型数据的哈希、取模以及范围的路由策略。同时,如果用户需要对切分键列有特殊路由计算处理,可以实现用户自定义路由算法(Groovy方式)。

图3描述级联切分键的一种实现方案,将业务数据根据时间范围进行第一次水平拆分;当某个时间范围内业务数据过大,可以将这部分数据根据任意拆分规则进行二次均匀拆分。多级路由结合自定义路由算法的实现方式,给业务接入提供了无限可能,用户可根据自身业务需求,选择最合适的数据拆分方案。

图3  CDS水平拆分

读写分离

读写分离对于数据访问量很高的互联网业务而言十分重要。对于大多数业务来说,数据库的访问瓶颈主要在于数据查询,通过配置一主多从的方式,使用只读库分担数据库的查询压力,能够很好地缓解业务系统的性能压力。

CDS将一主多从的数据库框架抽象成一个高可用的数据库群组,对外提供透明化的数据访问服务。业务访问数据库群组时,更新操作直接访问写库;查询操作会根据集群配置的数据库读权重,访问对应的读库。

如果某个读库发生宕机异常而无法提供服务,CDS Driver自动选择其他读库进行访问,同时从读库列表中暂时剔除该读库;当该库恢复服务时,CDS Driver会将其重新加入中可用读库列表。

图4  CDS读写分离

全局唯一序列

在分库分表场景下,原生的数据库无法实现全局唯一序列生成。CDS实现全局唯一的序列管理,且可通过CDS Console查询和管理应用序列值,通过事件推送实时变更业务序列值。

CDS全局序列主要用于保证全局唯一性,每个应用服务器的CDS Driver会缓存一段序列值,减少并发访问全局序列的压力;同时能够保证同一台应用服务器的序列值有序,不保证全局序列值有序。

同时CDS也支持分表序列,与分库分表一一对应,能够避免全局序列管理的单点问题,全局唯一性由应用保证。

应用事件推送

通过CDS Console可以实时监控应用进程的连接池、慢语句、驱动配置和JVM等信息;同时CDS Driver会实时统计应用进程信息,并接收CDS Console推送的增量规则变更、sequence更新以及配置信息变更等事件,无需重启应用便可实时完成事件处理。

图5  应用事件推送

其他特性

  1. 作业平台:CDS作业平台是参照Storm自主开发的一个分布式作业处理框架,提供了海量数据的分片并行迁移、流式数据同步等功能。通过CDS作业平台,可以高效完成单库到分库分表、分库分表到单库、分库分表到分库分表、分库分表到HBase等多种数据迁移需求。

  2. 分布式事务服务:业务进行水平拆分后,分布式数据库的强一致性很难保证,目前业界也没有很好的解决方案。CDS基于BASE模型,通过解析MySQL的binlog来实现事务反向补偿,对用户完全透明,不一致时间窗口控制在秒级,业务最终状态为事务失败状态,业务服务能感知事务失败异常。

  3. 数据中心:分库分表可以大大提升业务系统的高并发访问性能,但会带来一些访问限制,如多维度查询、联合查询、复杂SQL查询等。后台运营系统需要对业务数据库进行数据统计,往往会存在多维度查询、联合查询等需求。CDS数据中心使用ElasticSearch+HBase框架,能够提供运营数据多维度查询和数据统计等功能。

CDS原理概述

CDS Driver是CDS中间件的核心模块,实现JDBC标准API,以Jar包形式部署在应用端,完成数据路由、连接池管理、读写分离和异常告警等功能。

如图6所示,CDS Driver提供的功能主要包括几大模块:

图6  CDS驱动架构图

  1. SQL解析:CDS采用开源SQL解析器JSqlParser,并在其基础上进行了优化及功能扩充,包括支持自定义的宏、提供指定执行群组、限制结果集大小以及指定切分键定位等功能。同时CDS Driver通过SQL解析对象缓存机制,大大降低SQL解析带来的性能损耗。

  2. 连接池管理:CDS内置使用京东金融自主开发的WangyinCP连接池,同时也全面支持目前业界常用的连接池,如:BoneCp、C3p0、DHCP等。

  3. 慢语句统计:CDS Driver会实时统计业务查询时间超过指定阈值的SQL语句,便于业务根据慢语句进行业务优化和性能调优。

  4. 读写分离:CDS Driver根据集群配置的读写分离规则,完成应用访问的读写分离。

  5. 弱XA事务:CDS驱动本身只实现了弱XA支持,即执行阶段分库执行失败后,对事务中已完成执行的其他分库操作进行回滚;而在提交阶段,如果发生分库提交失败,则无法对之前已提交的分库进行回滚;可以通过CDS的分布式事务补偿服务进行基于BASE的最终失败的分布式事务补偿。

  6. 自定义路由算法:当CDS的几种默认路由策略无法满足业务特殊需求时,可根据业务自身需求,使用Groovy语法实现自定义路由规则。

CDS最佳实践:交易系统平滑扩容

2015年,京东金融交易系统的交易订单量达到数据库访问及存储瓶颈,DBA评估单库容量最多能够支撑几个月的增长,因此需要进行水平拆分。

水平拆分需求评估

  1. 业务数据量已快要达到数据库存储容量瓶颈;
  2. 水平拆分不迁移原始业务流水数据,将原数据库作为历史库,提供查询功能;
  3. 订单映射表全量迁移至分库分表集群,进行水平拆分;
  4. 由于交易系统十分重要,必须保证水平拆分过程中业务持续可用,因此需要实现不停机平滑上线。

CDS平滑扩容方案

业务表拆分策略

交易业务核心为流水数据,同时存在一些配置数据,两者之间没有关联查询,跨库事务可由业务层避免。配置表数据量不是非常大,无需水平拆分,可将此类数据放到某个工作组,对应用透明;业务流水数据量非常大,需根据订单号进行水平拆分。

图7  业务表分表策略

考虑到业务历史数据统计的需求,水平拆分方案考虑1+10模式:保留原始的历史库流水数据,新流水数据均匀分布到新增的10个分表中。

图8  1+10分库策略

分库分表路由策略

交易系统业务查询条件均包含订单号,因此使用业务查询订单号作为切分键进行分库分表。业务订单号字段内容为[YYYYMMDD+版本位+分库分表位+序列号],其中:版本号作为一级路由,分别路由到历史库和新增库;分库分表位作为二级路由,根据分库分表位定位分库分表。

图9  分表路由规则

水平拆分后,业务需要保证交易订单号全局唯一,CDS提供了两种序列生成方式:全局唯一序列和分表唯一序列。交易系统根据业务特点,通过订单号中的分库分表位结合分表序列号保证全局唯一,同时避免全局唯一序号的单点问题。

应用接入CDS

  1. 根据业务水平拆分方案,在CDS Console创建分库分表集群规则,集群配置成功后,通过CDS Console可以得到集群URL。
  2. 应用接入CDS驱动Jar包依赖,将原生的JDBC数据源配置替换成CDS数据源配置,使用CDS提供的连接URL。可以通过连接属性配置对应CDS功能,包括全表扫描、连接池配置等功能配置。

代码1

应用平滑上线

不停机方案的关键问题在于解决当应用升级过程新老版本应用并存时,如何保证数据的一致性。

  1. 升级前通过CDS作业平台对存量数据迁移到CDS集群中,全部应用升级后,将旧应用生成的增量数据再次迁移到CDS集群中。但是,在应用升级过程中需要解决两个难题:

1-1. 老应用只能读写历史库,如何访问新应用写入CDS集群中的数据?
1-2. 新应用如何访问老应用写入历史库的数据?

图10  应用升级时的订单数据访问

  1. CDS提供的数据重读、双写的解决方案能够很好地解决这个问题:

图11  CDS双写

2-1. 通过CDS集群配置,将历史库作为分库分表集群的重读库,在新应用没有读到旧应用写入历史库的数据时,会根据重读规则到历史库进行二次查询;

图12  CDS重读

2-2. 将历史库配置成双写群组,新应用产生的订单数据,会同时插入历史库和CDS集群,保证老应用访问到新应用产生的订单数据。

流水表数据保留历史库,新应用产生的流水数据落到新增分库分表集群中,在应用升级过程中会存在一种问题:新老应用并存时,如何保证这段时间内数据全部落到相同的数据库中?

图13  升级过程中,新老应用读写历史库

CDS提供一种延时切换的方案:设置一个默认时间阈值,阈值之前的流水数据均落到历史库上,如图13所示;当所有应用全部升级成功后,通过CDS Console推送时间阈值变更事件,当前时间到达该阈值后,所有应用的数据全部路由到新分库分表集群,如图14所示。

图14  推送切换事件,应用切换访问数据库


订阅2016年程序员(含iOS、Android及印刷版)请访问 http://dingyue.programmer.com.cn
图片描述

订阅咨询:

• 在线咨询(QQ):2251809102
• 电话咨询:010-64351436
• 更多消息,欢迎关注“程序员编辑部

130+位讲师,16大分论坛,中国科学院院士陈润生、滴滴出行高级副总裁章文嵩、联想集团高级副总裁兼CTO芮勇、上交所前总工程师白硕等专家将亲临2016中国大数据技术大会,票价折扣即将结束,预购从速

评论