支付宝使用OceanBase的历史库实践分享
为解决因业务增长引发的数据库存储空间问题,支付宝基于 OceanBase 数据库启动了历史库项目,通过历史数据归档、过期数据清理、异常数据回滚,实现了总成本降低 80%。
历史数据归档:将在线库(SSD 磁盘)数据归档到廉价存储的历史库(SATA 盘),节省约三分之二存储成本,提高在线库性能和运维效率;
过期数据清理:直接原地清理过期数据,100% 节省存储成本;
异常数据回滚:数据归档后,发现异常后可以从历史库进行数据恢复,将数据回滚到在线库。
流水型业务的数据量通常会跟随时间不断增加,当增加到一定数量,便会影响数据库的性能,甚至引发数据系统的容量瓶颈。为了解决这个问题,常见做法是将一部分冷的、不经常访问的数据存放到历史库中。
所谓历史库,主要是指把线上数据库超过一定时间的数据迁移到另外一个数据库中,确保线上库的数据量可控,以及保持业务的可持续发展,而历史的数据如果需要也可以在历史库中进行查询。
众所周知,支付宝曾经历替换数据库的阶段,为了保证金融业务的数据一致性与系统高可用、高扩容能力,选择将全部业务陆续迁移到原生分布式数据库 OcenaBase 。在将数据迁移到历史库后,单位空间磁盘成本降低到线上机器的 30% ,总体成本下降 80% 左右,甚至有些业务的存储成本降低到了原来的 1/10。
那么,支付宝启动历史库的背景是什么?期间经历了怎样的改造和演进,以及为什么 OcenaBase 能拥有如此高的数据压缩能力?本文通过支付宝历史库实践及业务改造技术方案为大家讲述。
时光倒回十年前,天猫“双 11”自 2009 年举办开始,每年成交额呈指数级增长,与此同时,支撑用户抢购的交易系统面临的压力也逐年递增。为了保障“双 11”期间系统的平稳运行及用户的良好体验,支付宝必须面对新的挑战。
从 2013 年开始,支付宝交易核心已经面临架构上的水平拆分上限了,如果保持当前架构下仅针对业务进行水平拆分扩容,需要购买更多的 Oracle 数据库,这将带来数据库成本近乎直线的攀升。该如何平衡成本和稳定性?这个问题是彼时支付宝工程师面对的难题。
要么购买更多的机器并投入更大的精力进行业务拆分,能够保证短期内的数据库性能与稳定性,要么重新选择一款不丢数据且稳定性高的数据库,而这次选择也将决定支付宝未来的成本投入和技术走向。正在众人焦头烂额之时,已经在淘宝收藏夹、SQL 引擎等业务线默默耕耘三年的 OceanBase 尝试抓住这次发展机会。
OceanBase 是完全自研的原生分布式数据库,天然具备高性能、高稳定、数据强一致等特点。在 2014 年“双 11”交易系统测试期间,系统已经扩容到最大集群量仍然无法抵御预测的流量洪峰,作为备选的 OceanBase 经受住了流量试验,支撑住了系统的稳定性。此举不仅使交易系统数据库切换为 OceanBase,还迎来了 2015 年“双 11”支付系统 51% 的流量考验,OceanBase 再次扛起流量洪峰,保障了系统的稳定性与高性能。
2016 年,OceanBase 实现了支付宝全业务覆盖,其弹性伸缩的架构,使得 OceanBase 集群可以通过增加机器扩容存储容量。但在 2017 年新的问题又摆在支付宝 DBA 面前:在不采购新机器的前提下,如何基于现有机器支持支付宝业务的快速发展?
彼时在线库集群积压了近两年的历史数据,占用了大量机器资源,新的数据还在爆发式增长,存储空间的压力与日俱增。在此背景下,支付宝 DBA 不得不将在线库的历史数据剥离,释放在线库存储空间,提高资源利用率,历史库迁移提上日程。
历史数据从在线库迁移到历史库,需要保证数据在迁移过程中的安全可靠,以及速度可控,不影响线上业务或历史库性能,还需要保证迁移后的数据完整性和操作历史可查询,如任务日志等,方便审计排查问题。
整个迁移过程分为如下三个步骤:
第一,在线库历史数据迁移到历史库
按照迁移规则,迁移指定时间范围的历史数据到历史库。比如某时间节点之前的数据全部迁移到历史库,此时应用仍访问在线库。
迁移是通过查询条件获取主键,按主键顺序批量扫描数据,每次扫描 n 条( batchsize 可配置),批量插入历史库,同时记录每批迁移记录的主键、时间、源库、目标库等信息,保留在 metadb 中,可查询历史操作轨迹,以防止异常情况下重新开始。迁移程序需要关注历史库内存消耗情况,具备防导爆功能。
第二,应用修改历史数据切流时间配置,访问历史库
当所有表时间节点之前的历史数据全部迁移到 OceanBase 历史库后,应用调整历史库切流时间配置,将时间节点之前数据查询流量切到历史库,验证正确性。
此时在线库和历史库均包含时间节点之前的数据,如果发现异常时,应用可回滚。
第三,在线库删除历史数据,回收空间
第二步切流验证无误后,按同样的规则,根据中间库中的记录,批量查询历史库对应的记录全信息,主键匹配删除在线库记录,此时在线库删除的记录,肯定在历史库存有一份,不会丢失任何数据。
与正向迁移一样,反向删除在线库数据,需要记录位点,防止异常情况从头开始。同时关注在线库内存消耗,防止内存写爆。
一、历史库平台演进
历史库目的是为了解决因为业务增长引发的数据库存储空间问题。通过性能换成本的方式,将过去不再使用的业务数据或查询很少的数据,搬迁到性能低但存储量大的机型构成的集群中,降低线上数据库存储带来的开销。针对历史库的需求,需要一个迁移程序将冷数据从在线库迁移至历史库,并且保证在线库和历史库都持续可用,不需要停机切流。因此,有几点特殊的需求:
考虑数据量比较大,需要支持断点续传。
由于交易历史库有一些表之间有关联,需要具备主子表维度迁移的功能。
需要具备删除已经迁移的数据的功能。
由于当时常用的数据迁移工具 DataX 和 DTS 都不支持主子表维度迁移,也不具备删除已迁移数据的能力,因此,支付宝及 OceanBase 的研发人员决定自研一套迁移工具供历史库迁移使用。自研的迁移工具包括迁移、校验、删除三种任务模式。通过多线程启动对应的任务,并将相关迁移任务、进度和结果写入 metadb ,以便监控任务进度和支持断点续传。
任务模式
a. 迁移
通过生产者—消费者模型实现的 Writer 和 Reader 进程,实现表记录的迁移。当前支持读取源数据库和目标数据库的配置信息、迁移表以及流控、日志打印等参数配置,具备一定的通用性。
b. 校验
迁移完成后,从目标数据库读取主表和(所有)子表的记录,并与源数据库逐行逐字段做字符串匹配,效验数据一致性。当有不一致的数据,会将主键写入 metadb。
c. 删除
当前支持指定校验完成后是否从源数据库删除记录。通过主键匹配的方式。校验前对相关表记录加锁,校验完成后执行删除语句,提交事务。
逻辑说明
工具中具体的迁移、校验、删除逻辑通过启动对应的线程实现。在工具启动时,根据配置文件初始化任务(job)和子任务(task),并写入 metadb 的 jobs 和 tasks 表,便于断点续传和进度统计。
工具使用多线程模型将一个迁移、效验任务(job)分割成若干个 task 并行执行,可以提高处理速度。线程的数目可配。
迁移逻辑使用多个 reader 同时从数据源读取数据,写入 buffer 。同时 writer 从 buffer 里获取数据,写入目标数据源。DataReader 从数据源读取主表的信息(如果有关联子表,则一起读取),返回一个 TransRecords 对象:
DataWriter 线程则从 buffer 获取到数据后,写入目标数据源。
数据源封装
工具使用 oceanbase-connector-java 获取 OceanBase 连接,通过一个工厂类 DataSourceFactory 获取指定类型的数据源连接。用这种方式可以屏蔽数据源差异,做到不同源数据库之间的迁移和校验。当时已经支持 OceanBaseMySQL 数据源。
限速及防导爆
为防止因数据查询或者清理过快导致线上产生抖动,或相应数据库下流订阅同步产生数据积压等问题,工具支持 OceanBase 的限速及防导爆功能。目前限速分为单表处理的行数、租户运行最大处理的并发数、租户最大网络读写流量、集群运行最大处理的并发数、集群最大网络读写流量这 5 个方面进行的限速。历史库平台在运行期间写入时还会对写入操作的租户 CPU 、内存使用情况进行检测,满足安全的区间内才会进行操作。
断点续传
工具正常启动一个新任务,完成子任务切分后,会将任务信息写入 jobs 表,将子任务信息写入 tasks 表。如果工具异常退出,可以自动断点续传,不需要重新开始执行。
二、历史库平台架构
历史库平台为数据提供了更长生命周期管理能力。历史库平台通常由在线数据库、历史库客户端、历史库管控平台、历史数据库集群组成,为用户提供一站式的数据存储、归档解决方案。
通过历史库管控平台,用户可以方便地配置迁移任务,指定规则将符合条件的非活跃数据从在线数据库迁移到成本更低的历史 OceanBase 数据库集群中。同时,历史库平台提供多维度的限速能力,以及多项目间优先级调度功能。用户通过配置限速减少迁移时对业务的影响,通过配置优先级可管理多套集群,满足多项目同时运行。待数据迁移完成后,提供数据校验、校验成功后删除在线数据配套功能,方便实用。
经过支付宝业务的打磨,历史库平台(见下图)已经支撑支付宝内部交易、支付、账务等多个重要系统,节省了支付宝内部数据存储成本。同时,在网商银行也有广泛的使用场景。
从图中可见,历史库平台包含三大板块:在线数据库、历史数据库集群、历史库管控平台。
在线数据库,用于存放应用常常需要访问的数据。通常会采用更高规格配置的服务器,提供高性能的处理能力。目前已支持 OceanBase,MySQL,Oracle 作为数据源。
历史数据库集群用于存放应用产生的终态数据,根据应用需求不同,即可以作为数据归档存储的集群不对应用提供访问,也可以满足应用的访问需求。采用成本更低的 SATA 盘来搭建 OceanBase 数据库集群。其中的历史库客户端用于处理用户发起的迁移、校验、删除任务。支付宝内部实现了多维度的限速,根据需求不同可以灵活地提供集群限速和表限速功能,最大程度的避免了任务对在线库应用流量的影响。
历史库管控平台是用户对历史库进行各项操作的运维管理平台,提供权限管理、任务配置、任务监控等功能。
当前已建设 20 多个历史库集群,在支付宝内部已覆盖交易、支付、充值、会员、账务等几乎所有核心业务,总数据量 95 PB,每月增量 3 PB。其中,最大的交易支付集群组,数据量 15 PB,每日数据增量可达到 50 TB。支付宝历史库的实践,带来的收益显著,主要包括以下三点:
第一,成本下降 80% 左右。
由于历史库采用成本更低的 SATA 盘来搭建 OceanBase 数据库集群,单位空间磁盘成本降低到线上机器的 30%。同时使用更高压缩比的 zstd 压缩算法,使得总体成本下降 80% 左右。
如果线上是 MySQL、Oracle 等传统数据库,那么成本会降低更多。因为 OceanBase 本身的数据编码、压缩以及 LSM-Tree 的存储架构等,使得存储成本只有传统数据库的 1/3。
第二,弹性伸缩能力降低运维成本。
历史库使用 OceanBase 三副本架构,每个 zone 中有多个 OBServer ,通过分区将数据分散到多个 unit 中。OceanBase 具备业务无感知的弹性伸缩能力,并且可以通过扩容节点增加容量、提升性能。这意味着历史库可以不再受限于磁盘大小,通过少数集群就可以涵盖所有业务的历史库,降低运维成本。
目前历史数据是永久保存的,随着时间的推移,历史库的容量占用也会越来越高。依赖 OceanBase 本身的高扩展性,通过横向扩展 OBServer ,增加 unit_number 即可实现容量的扩容。
第三,数据强一致,故障快速修复。
数据迁移相当于一份数据归档及逻辑备份,如果这些数据发生了丢失,那么后续需要做审计、历史数据查询的时候,数据就对不上了。这对于很多业务尤其是金融业务而言是无法忍受的。
OceanBase 底层使用 Paxos 一致性算法,当单台 OBServer 宕机时,可以在 30s 内快速恢复,并保证数据的强一致,降低对线上查询及归档任务的影响。
随着支付宝的交易、支付、账务、充值、会员等几乎所有核心业务都搭载了 OceanBase 作为历史库,历史数据的存储不再受限于磁盘大小,业务的发展也不再受限于数据库系统的容量。支付宝携手 OceanBase,实现历史库的总体成本下降 80% 左右,存储成本只有传统数据库的 1/3 ,降本增效成果显著,助力支付宝从容应对业务持续增长。
支付宝基于 OceanBase 数据库启动历史库项目实现降本增效,不仅是支付宝内部业务发展和数据库运维的关键诉求,对于整个金融行业的历史数据存储也意义重大,为后续重要业务的历史库迁移改造提供了可靠的成功案例,为 OceanBase 数据库走向政企、泛互等其他重要领域树立了典型示范。
往期推荐
▼ 点击下方「阅读原文」,进一步了解历史库!