关键字:生命周期自动管理 | 低成本 | 超大容量
通过 OceanBase 智能化的历史库迁移平台,帮助用户快速、安全的完成冷数据归档,一次配置即可实现自动化的周期管控。OceanBase 高压缩比的分布式存储引擎, 摒弃了传统数据库的定长数据块存储,采用基于 LSM-Tree 的存储架构和自适应压缩技术,创造性地解决了传统数据库无法平衡“性能”和“压缩比”的难题,
历史数据归档场景
在订单、交易、日志等业务场景中,数据总量会不断增加。而对于这些数据的访问往往和时间有很强的相关性,通常与当前时间越接近的数据越“热”,也就是说,这些数据可能会被频繁地修改与点查。热数据的访问更多是事务型负载和实时分析负载,其数据量在整个系统中的占比相对较低。而在系统中已经存在了一段时间的数据,被称为冷数据,这些数据的被查询次数相对没有那么频繁,也很少被修改。冷数据的访问通常是少量的事务型负载和一些 ad-hoc 或报表统计等分析型负载,而且冷数据通常是稳定运行的 IT 系统中数据量的主要部分。
由于冷热数据有着明显的区别,将它们放在一套相同规格的环境中同等处理显然会浪费系统的资源,单个数据库的容量上限还可能会限制数据的存储。但是,将冷数据定期归档到更经济的存储介质中,访问数据时采用从归档数据中还原的方法,又会对历史数据的查询性能和系统的复杂度带来负面影响。因此,将数据分为线上库和历史库,将在线数据定期同步到历史库中的做法成为了越来越多系统的解决方案,通过在存储和计算成本更低的环境上部署历史库来降低成本和满足业务需求。
解决方案
行业现状与挑战
- 数据增长加速:面对快速增长的在线数据,尤其例如新零售、支付等订单和交易场景,数据往往多呈现为流水型特征,即写入一段时间后不会再次访问或更新。
- 成本高效率低:低频或零访问数据占用在线业务库的固态存储空间,造成大量硬件资源浪费,堆高企业 IT 成本,导致在线数据库体积臃肿、查询效率降低,给后续数据变更、扩展造成阻碍。
- 传统方案风险高:传统数据归档方案往往是业务研发或 DBA 采用脚本或简单的同步工具进行,难以在并发和效率上有效控制,很容易对在线数据库产生影响,严重的甚至导致生产数据误删事故。
- 运维管理复杂:多个业务对应的不同数据库、甚至不同表都可能有各异的归档周期和限定条件,会导致大量定时任务的逻辑维护复杂,耗时耗力。
方案描述
- 基于 OceanBase 对低端硬件的友好兼容, OceanBase 历史库平台实现了归档任务配置图形化,周期管控自动化,数据迁移 + 校验 + 删除一键自动灰度执行等能力。稳定性方面提供了防导爆、智能限速、多粒度流控等机制,真正实现了数据归档的智能化运维。
- 此方案历经蚂蚁集团核心业务场景验证,交易支付历史库单实例数据超过 6PB,采用上百台大容量机械盘的低成本硬件支撑,磁盘水位自动均衡,平稳运行多年,节省了大量机器资源。

方案优势
- 可视化管理:任务创建与运行、进度大盘、一键暂停/恢复等基础操作图形化。
- 智能化运维:令牌桶算法限速控制、断点续传、任务调度自动化管控等机制,以及宕机自动替换、自动扩缩容、防导爆等自愈手段,实现运维零干预。
- 低成本:大容量 SATA 盘机型友好,结合 OceanBase 高压缩存储能力,单节点最大即可存储相当于传统数据库 400TB 数据。
- 海量存储:适用在线业务瘦身,真正做到为数据归档减负。历史库集群可作为大容量关系型数据库使用,能稳定支撑写入量巨大但低频访问的业务查询需求,如监控、日志、审计核对等场景。
OceanBase 存储引擎和数据压缩技术介绍
作为一款 HTAP 数据库产品, OceanBase 使用基于 LSM-Tree 架构的存储引擎,同时支持 OLTP 与 OLAP 负载,这种存储架构提供了优秀的数据压缩能力。在 OceanBase 中,增量数据会写入 clog 和 memtable 中, OceanBase 的 memtable 是内存中的 B+ 树索引,提供高效的事务处理能力。
memtable 会定期通过 compaction 生成硬盘持久化数据 sstable ,多层 sstable 会采用 leveled compaction 策略进行增量数据重整。sstable 中数据块的存储分为两层,其中 2M 定长的数据块(宏块)作为 sstable 写入 I / O 的最小单元,存储在宏块中的变长数据块(微块)作为数据块压缩和读 I / O 的最小单元。

在这样的存储架构下, OceanBase 的数据压缩集中发生在 compaction 过程中 sstable 的写入时,数据的在线更新与压缩得到了解耦。批量落盘的特性使其采用更激进的压缩策略。OceanBase 从 2.0 版本开始引入了行列混存的微块存储格式( PAX ),充分利用了同一列数据的局部性和类型特征,在微块内部对一组行以列存的方式存储,并针对数据特征按列进行编码。变长的数据块和连续批量压缩的数据也可以让 OceanBase 通过同一个 sstable 中已经完成压缩的数据块的先验知识,对下一个数据块的压缩进行指导,在数据块中压缩尽量多的数据行,并选择更优的编码算法。
与部分在 schema 上指定数据编码的数据库实现不同, OceanBase 选择了用户不感知的数据自适应编码,在给用户带来更小负担的同时降低了存储成本,从历史库角度而言,用户也不需要针对历史库数据做出过多压缩与编码相关的配置调整。 OceanBase 之所以能够在事务性能和压缩率之间取得更好的平衡,都得益于 LSM-Tree 的存储架构。
当然, LSM-Tree 架构不是解 决数据库压缩所有问题的万金油,如何通过数据压缩降低成本、提升性能是业界一直在讨论的话题。对 B+ 树类的存储引擎进行更高效的压缩也有很多探索,比如基于可计算存储硬件的工作,利用存储硬件内部的透明压缩能力对 B+ 树类存储引擎的数据压缩进行优化,使其写放大达到了接近 LSM-Tree 架构存储引擎的效果。但 LSM-tree 中内存数据页更新与数据块落盘解耦,和 sstable 数据紧凑排布的特点,使得 LSM-tree 相对 B+ 树类存储引擎,仍然更适合在对查询/更新带来更少负面影响的前提下实现更高效的数据压缩。
OceanBase 的数据库压缩技术
OceanBase 支持不感知数据特征的通用压缩 ( compression ) 和感知数据特征并按列进行压缩的数据编码 ( encoding )。这两种压缩方式是正交的,也就是说,可以对一个数据块先进行编码,然后再进行通用压缩,来实现更高的压缩率。
OceanBase 中的通用压缩是在不感知微块内部数据格式的前提下,将整个微块通过通用压缩算法进行压缩,依赖通用压缩算法来检测并消除微块中的数据冗余。目前 OceanBase 支持用户选择 zlib 、 snappy 、 zstd 、 lz4 算法进行通用压缩。用户可以根据表的应用场景,通过 DDL 对指定表的通用压缩算法进行配置和变更。
由于通用压缩后的数据块在读取进行扫描前需要对整个微块进行解压,会消耗一定 CPU 并带来 overhead。为了降低解压数据块对于查询性能的影响, OceanBase 将解压数据的动作交给异步 I / O 线程来进行,并按需将解压后的数据块放在 block cache 中。这样结合查询时对预读 ( prefetching ) 技术的应用,可以为查询处理线程提供数据块的流水线,消除解压带来的额外开销。
通用压缩的优点是对被压缩的数据没有任何假设,任何数据都可能找到模式并压缩,但往往出于平衡压缩性能和压缩率的考虑,通用压缩算法会放弃对一些复杂数据冗余模式的探测和压缩。对于关系型数据库来说,系统对数据库内存储的结构化数据有着更多的先验知识,利用这些先验知识可以对数据进行更高效的压缩。
OceanBase 的数据编码算法
- 当通过一列数据存储城市、性别、产品分类等具有类型属性的值时,这些列数据块内部数据的基数( cardinality )也会比较小,这时数据库可以直接在用户数据字段上建立字典,来实现更高的压缩率;
- 当数据按时序插入数据库,这些插入的数据行中的时间相关字段、自增序列等数据的值域会相对较小,也会有单调递增等特性,利用这些特性,数据库可以更方便地为这些数据做 bit-packing 、差值等编码。
为了实现更高的压缩比,帮助用户大幅降低存储成本, OceanBase 设计了多种编码算法,最终在 OceanBase 的负载上实现了很好的压缩效果。 OceanBase 根据实际业务场景需求实现了单列数据的 bit-packing 编码、字符串 HEX 编码、字典编码、 RLE 编码、常量编码、数值差值编码、定长字符串差值编码,同时,创新地引入了列间等值编码和列间子串编码,能够分别对数据库中一列数据或几列数据间可能产生的不同类型数据冗余进行压缩。
降低存储的位宽:Bit-packing 和 HEX 编码
Bit-packing 和 HEX 编码类似,都是在压缩数据的基数较小时,通过更小位宽的编码来表示原数据。而且这两种编码可以与其他编码叠加,对于其他编码产生的数值或字符串数据,都可以再通过 bit-packing 或 HEX 编码进一步去除冗余。

(bit-packing)

( HEX 编码)
单列数据去重:字典编码和 RLE 编码等
字典编码则可以通过在数据块内建立字典,来对低基数的数据进行压缩。当低基数的数据在微块内的分布符合对应的特征时,也可以使用游程编码/常量编码等方法进行进一步的压缩。

(字典编码/RLE 编码)
利用数据的值域压缩:差值编码等
差值编码也是常用的编码方法, OceanBase 中的差值编码分为数值差值编码和定长字符串差值编码。数值差值编码主要用来对值域较小的数值类数据类型进行压缩。对于日期、时间戳等数据,或其他临近数据差值较小的数值类数据,可以只存储最小值,每行存储原数据与最小值的差值。定长字符串编码则可以比较好地对人工生成的 ID,如订单号/身份证号、url 等有一定模式的字符串进行压缩,对一个微块的数据存储一个模式串,每行额外存储与模式串不同的子串差值,来达到更好的压缩效果。

(整形差值)

(字符串差值)
减小多列数据冗余:列间编码
为了利用不同列间数据的相似性增强压缩效果,OceanBase 引入了列间编码。通常情况下,列存数据库只会对数据在列内部进行编码,但在实际应用中有很多表除了同一列数据之间存在相似性,不同列的数据之间也可能有一定的关系,利用这种关系可以通过一列数据表示另外一列数据的部分信息。
列间编码可以对复合列、系统生成的数据做出更好的压缩,也能够降低在数据表设计范式上的问题导致的数据冗余。
自适应压缩技术:让数据库选择编码算法
数据编码的压缩效果不仅与表的 schema 相关,同时还与数据的分布,微块内数据值域等数据本身的特征相关,这也就意味着比较难以在用户设计表数据模型时指定列编码来实现最好的压缩效果。为了减轻用户的使用负担,也为了实现更好的压缩效果,OceanBase 支持在合并过程中分析数据类型、值域、NDV 等特征,结合 compaction 任务中上一个微块对应列选择的编码算法和压缩率自适应地探测合适的编码,对同一列在不同数据块中支持使用不同的算法来进行编码,也保证了选择编码算法的开销在可接受的区间内。
降低数据编码对查询性能影响的能力
为了能够更好地平衡压缩效果和查询的性能,我们在设计数据编码格式时也考虑到了对查询性能带来的影响。
行级粒度数据随机访问
通用压缩中如果要访问一个压缩块中的一部分数据通常需要将整个数据块解压后访问,某些分析型系统的数据编码大多面向扫描的场景,点查的场景比较少,因此采用了在访问某一行数据时需要对相邻数据行或数据块内读取行之前所有行进行解码计算的数据编码的格式(如 PFor 等差值编码)。
OceanBase 需要更好地支持事务型负载,就意味着要支持相对更高效的点查,因此 OceanBase 在设计数据编码格式时保证了编码后的数据是可以以行为粒度随机访问的。也就是在对某一行进行点查时只需要对这一行相关的元数据进行访问并解码,减小了随机点查时的计算放大。同时对于编码格式的微块,解码数据所需要的所有元数据都存储在微块内,让数据微块有自解释的能力,也在解码时提供了更好的内存局部性。
缓存解码器
在 OceanBase 目前的数据解码实现中,每一列数据都需要初始化一个解码器对象来解析数据,构造解码器时会需要进行一些计算和内存分配,为了进一步减小访问编码数据时的 RT ,OceanBase 会将数据的解码器和数据块一起缓存在 block cache 中,访问 cache 中数据块时可以直接通过缓存的解码器解析数据。当不能命中 block cache 中缓存的解码器时,OceanBase 还会为解码 器用到的元数据内存和对象构建缓存池,在不同查询间复用这些内存和对象。
通过上述细节上的优化,行列混存格式的 sstable 编码数据也可以很好地支持事务型负载。而且由于编码数据行列混存的格式,使得在分析型查询的处理上,编码数据有着和列存数据相似的特性,数据分布更紧凑,对 CPU cache 更加友好。这些特性使列存常用的优化手段也能应用于分析型查询优化中,充分利用 SIMD 等方法来提供更高效的分析型负载处理。
计算下推
由于编码数据中会存储有序字典、 null bitmap 、常量等可以描述数据分布的元数据,在扫描数据时可以利用这些数据对于部分过滤,聚合算子的执行过程进行优化,实现在未解码的数据上直接进行计算。 OceanBase 对分析处理能力进行了大幅的优化,其中包括聚合与过滤计算下推到存储层执行,和在向量化引擎中利用编码数据的列存特征进行向量化的批量解码等特性。在查询时充分利用了编码元数据和编码数据列存储的局部性,在编码数据上直接进行计算,大幅提高了下推算子的执行效率和向量化引擎中的数据解码效率。基于数据编码的计算下推和向量化解码也成为了支持 OceanBase 高效处理分析型负载,在 TPC-H benchmark 中达到优秀性能指标的重要功能。

据编码压缩的基础测试
不同的压缩方式如何影响 OceanBase 的压缩效果,以下通过一个简单的测试进行观察。使用 OceanBase 4.0 版本分别在交易场景的 TPC-H 10g 的数据模型和用户行为日志场景的 IJCAI-16 Brick-and-Mortar Store Recommendation Dataset 数据集上对 OceanBase 的压缩率进行测试。
- TPC-H 是对订单,交易场景的建模,对 TPC-H 模型中数据量比较大的两张表,即存储订单的 ORDERS 表和存储商品信息的 LINEITEM 表的压缩率进行统计。在 OceanBase 默认配置( zstd + encoding )下,这两张表的压缩率可以达到 4.6 左右,相较只开启 encoding 或 zstd 压缩时提升明显。
- IJCAI-16 taobao user log 则是淘宝脱敏后的真实业务数据,存储了用户浏览商品时的行为日志。在 OceanBase 默认配置( zstd + encoding )下压缩率可以达到 9.9 ,只开启 encoding 压缩率可以达到 8.3 ,只开启 zstd 压缩率为 6.0 。

OceanBase 存储引擎技术为何能更好地支持历史库场景?
OceanBase 存储引擎的数据库压缩功能在设计上希望能够在用户少感知、不感知存储格式的前提下,在不降低事务型负载性能的同时降低存储空间和 存储成本,同时提升分析型负载的性能。这样的设计与历史库的设计不谋而合。高度压缩的数据既能够帮助历史库数据降低至少 50% 的存储成本,高效的写入查询和统一的配置接口又能够帮助业务增效。
对于历史库数据同步的需求, OceanBase 的 LSM-Tree 存储引擎天生具有高效的写入性能,既能够通过旁路导入高效处理定期的批量数据同步,又能够承载一些实时数据同步和历史库数据修改的场景。
对于历史库数据的定期跑批报表,和一些 ad-hoc 的分析型查询带来的大量数据扫描的需求,因为历史库中增量数据较少,所以绝大多数数据都存储在基线的 SSTable 中,这时计算下推可以只扫描基线数据,绕过了 LSM-Tree 架构常见的读放大问题。而且支持在压缩数据上执行下推算子和向量化解码的压缩格式可以轻松地处理大量数据查询和计算。
对于大量历史数据存储的需求, OceanBase 的 SSTable 存储格式和数据编码压缩功能可以使 OceanBase 更轻松地支持超大容量的数据存储。而且高度压缩的数据和在同等硬件下更高效的查询性能也能够大幅度降低存储和计算的成本。
此外,企业可以选择将历史库所在的集群部署在更经济的硬件上,但是对数据库进行运维基本不需要感知数据编码与压缩的相关配置,应用开发也可以做到在线库和历史库使用完全相同的访问接口,简化应用代码和架构。
这些特点让越来越多的企业开始在历史库场景使用 OceanBase 进行降本增效的实践。OceanBase 也不断在存储架构,降本增效方面做出更多的探索。
用户案例
支付宝
业务挑战
- 从 2013 年开始,支付宝交易核心已经面临架构上的水平拆分上限了,如果保持当前架构下仅针对业务进行水平拆分扩容,需要购买更多的 Oracle 数据库,这将带来数据库成本近乎直线的攀升。该如何平衡成本和稳定性?这个问题是彼时支付宝工程师面对的难题。要么购买更多的机器并投入更大的精力进行业务拆分,能够保证短期内的数据库性能与稳定性,要么重新选择一款不丢数据且稳定性高的数据库。
- 在 2014 年,支付宝原有的数据库系统已经扩容到最大集群量,但仍然无法满足历史库的需求。当时作为备选的蚂蚁集团完全自研的原生分布式数据库 OceanBase 经受住了试验,支撑住了系统的稳定性。此举使支付宝的交易系统数据库切换为 OceanBase,保障了历史库系统的稳定性与高性能。
解决方案
历史库目的是为了解决因为业务增长引发的数据库存储空间问题。通过性能换成本的方式,将过去不再使用的业务数据或查询很少的数据,搬迁到性能低但存储量大的机型构成的集群中,降低线上数据库存储带来的开销。针对历史库的需求,需要一个迁移程序将冷数据从在线库迁移至历史库,并且保证在线库和历史库都持续可用,不需要停机切流。因此,有几点特殊的需求:
- 考虑数据量比较大,需要支持断点续传。
- 由于交易历史库有一些表 之间有关联,需要具备主子表维度迁移的功能。
- 需要具备删除已经迁移的数据的功能。
迁移工具 OMS 包括迁移、校验、删除三种任务模式。通过多线程启动对应的任务,并将相关迁移任务、进度和结果写入 metadb ,以便监控任务进度和支持断点续传。
历史库平台架构
历史库平台为数据提供了更长生命周期管理能力。历史库平台通常由在线数据库、历史库客户端、历史库管控平台、历史数据库集群组成,为用户提供一站式的数据存储、归档解决方案。通过历史库管控平台,用户可以方便地配置迁移任务,指定规则将符合条件的非活跃数据从在线数据库迁移到成本更低的历史 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 内快速恢复,并保证数据的强一致,降低对线上查询及归档任务的影响。
携程
业务挑战
解决方案
- 相比传统的集中式数据库 MySQL,OceanBase 在存储层面极致的压缩能力,有效降低企业使用数据库的硬件成本。
- OceanBase 具备灵活的资源扩展能力,根据业务实际发展情况可以动态的进行计算和存储能力的线性扩展,支撑海量数据的存储和计算,同时很好地应对未来的业务增长要求。
- 在数据迁移方面,因 OceanBase 兼容 MySQL 协议与语法,因此 OMS 可以做到平滑迁移,可大幅降低业务迁移和改造成本。OMS 通过全量迁移、增量迁移、反向迁移,保障数据迁过程中的强一致,并提供数据同步到 kafka 等消息队列中的能力。

用户收益
- 运维更加高效与便捷:单集群替换数十套 MySQL 环境,运维管理成本大大降低,同时管理更加方便。使用普通的 PC 服务器即可构建超高吞吐的 OceanBase 集群,无需分库分表,快速按需扩展,为携程历史库在水平扩展过程中提供了平滑的成本增长曲线。
- 低成本:支撑上百 TB 数据存储场景且性能和稳定性有保证,同时相比较之前的方案,OceanBase 方案的存储成本降低 85%,降本效果明显。
- 数据同步性能提升:数据迁移对业务透明,OMS 支持全量数据迁移、增量数据同步,支持主流数据库的一站式数据迁移。数据从上游写入到下游 OceanBase 响应延迟更小,数据同步速度更快,同步延迟时间减少 3/4。
- 数据写入性能优秀:OceanBase 的无共享架构、分区级主副本打散,以及并行执行框架提供的 ParallelDML 能力,真正实现了高效的多节点写入。利用该特性,数据写入性能提升数倍,能够从容应对携程历史库的超高并发数据写入需求。