暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

高性能体验提升之路,一文读懂阿里云AnalyticDB云原生存储引擎

327

一、背景

云原生数据仓库AnalyticDB MySQL版(下文简称为 ADB MySQL)是阿里巴巴自主研发、经过超大规模以及核心业务验证的PB级实时数据仓库,本文将讲解其自研存储引擎的实现及优化。

ADB MySQL的存储引擎数据模型如下:

表数据首先基于分布键order_id进行分片,将整张表数据打散成N份。分片内部基于分区键time按天进行分区,首先写入到实时数据中对用户查询可见,后台Compaction时与历史分区进行合并,构建索引并以分区为粒度做冷热归档。模型示意如下:

这个典型的分片+分区两层数据组织的方式,在合理使用时,能在数据规模维度上线性拓展,不过存在以下典型问题
  1. 实时数据堆积。分片内实时数据在合并到分区前没有索引,而合并由于数据组织的原因只能串行。当写入速度大于后台合并速度时实时数据会积压,会导致典型查询慢问题。
  2. 分区粒度不可控。分片内的每次合并,都要将实时中涉及到的历史分区全量合并,产成新的分区数据。在分区由用户定义的前提下,定义分区很小时,会导致大量小文件,而定义分区很大时,合并开销又大大增加,进一步导致实时数据堆积问题。这些都只能事后运维干预,开销极大。

  3. 横向拓展不轻量。扩缩容等操作时需要搬迁本地热分区数据,扩缩容速度受限于本地热数据大小。典型云上用户大多数据都是需要分析的热数据,无法体会到快速扩缩容的云原生使用体感。

为了能更好的解决这类问题,满足线上各类用户的使用场景,我们设计开发了新的单机引擎XuanWuV2,数据全OnDFS,更精细的数据组织、更稳定高效的IO和更轻量的横向拓展性。

二、XuanWuV2引擎

1. 数据模型

针对在XuanWu中碰到的问题,我们参考业界经典LSM结构,并结合自身数据分布特点,设计了新的数据组织模型。分片内示意如下:

相对于原来单分区单物理文件组织、每次将实时与分区全量合并的方式,新的数据模型主要有以下特点:
1. 分层。分层可以做更精细的控制,解耦用户行为对后台的影响,让用户更关注业务实现,具体表现上:
  1. L0。来自实时数据的Flush产生物理文件,物理文件内按用户定义逻辑分区有序组织。因此L0的每一个物理文件都是按分区顺序的SortRun;
  2. L1及以下层。来自上层的局部合并,整层是一个逻辑SortRun,按分区有序。SortRun按固定行切割为物理文件进行组织,层级间大小相差一个系数。
2. 局部合并。在分层基础上,合并细分不同的场景并区分优先级,将有限资源让渡给更高优的合并动作,最大化资源利用效率并降低对用户业务影响,具体表现上:
  1. L0 Flush。实时数据最高优Flush到L0,转换为读友好数据提供查询,不参与历史分区的合并。解决实时数据堆积问题;

  2. L1局部合并。L0中数据在分区维度上选择L1中有分区重叠的物理文件,局部合并到L1中,从算法角度最大化降低实时写入的合并放大;

  3. 大分区合并。上一层的大分区跨多个物理文件时会有额外的读放大,以更低优的策略合并到下一层优化为大的物理文件。

3. 自适应物理分区。在分层基础和合并的过程中,以最佳实践的分区大小进行物理文件的组织,将最佳实践自包含于存储内部。自动将小分区合并到一个物理文件,而将大分区拆分为多个物理文件。降低用户来回修改分区的运维负担,尤其对不同年月数据量不一情况更为有效。
在设计细节的基础上,我们再对两套模型进行区分对比:

因此,XuanWuV2的数据模型通过更精细化的软件设计和实现,解耦掉用户行为对内核的影响,为用户提供最大程度的易用、稳定、高性能体验,让不同场景的用户都能专注于自己的业务实现。

2. 数据、元数据与索引

除了数据模型和合并的变化外,我们还在原来按固定行组织列级IO块的基础上,增加了按固定大小的IO块组织。相应的也增加了IO寻址用的OrdinalIndex,并对这类元数据进行分层管理,以解决大数据规模下的元数据内存占用问题。

a. 行对齐
如上为典型固定行(RowGroup)方式的IO组织,文件IO组织部分的箭头为文件数据存储顺序。每个列按固定K行组成IO块并进行压缩,文件中按列顺序依次存储同RowGroup中的IO块.
其优点在于实现简单且基于行号随机IO寻址高效,缺点在于不同列IO和内存都对不齐,单记录比较大的字段IO低效且内存占用大,内存复用效率低, 扫描时容易出现典型的大字段OOM问题。为此,我们在XuanWuV2中进一步引入了按大小对齐的IO组织。

b. 大小对齐

XuanWuV2的固定大小IO组织如下:

对比XuanWu的按行IO组织:

  1. 不同列IO块大小(压缩前)是固定的。对比固定行IO组织下,description列由于单条记录过大,单IO块比其他列大的多。
  2. 多了额外的辅助结构OrdinalIndex。同样IO大小下,不同列能容纳的行数是不一样的,基于行号去随机寻址IO块需要辅助结构,记录每个IO块的开始rowId和IO块信息,如上Description列的OrdinalIndex每条记录对应每个Block的信息。
OrdinalIndex等元数据不常驻内存,与RocksDB的Partitioned Index类似,使用两层结构进行管理,IO块级换入换出,即使在超大规模数据集下也没有内存瓶颈。
除了数据和元数据外,我们还升级优化了索引的编码,索引的压缩率有不错的提升。

从不同维度对比下:

3. 云原生

在内核之上,我们基于XuanWuV2的多版本管理做了更彻底的存算分离,分区数据全OnDFS,热分区Pin到本地缓存中加速查询。通过计算资源组的不同访问模式来满足在离线查询的不同需求,典型的:

  1. 在线(交互式)查询,访问本地Pin的热分区数据,满足较为敏感的延迟需求;

  2. 离线(吞吐型)查询,直接访问DFS,能做到更好的并发控制和计算资源的横向拓展。

离线查询仅涉及计算资源的横向拓展较为快速,而在线查询关联的存储资源带状态,涉及更为复杂的恢复动作。数据OnDFS后,除了成本更低外,在线的存储资源备份/恢复/扩缩容等产品化能力也更轻量,让用户有更好的云原生使用体感。

如上,源实例日常活动:
  1. 产生的分区数据上传到DFS中,同时将用户定义热数据Pin到本地缓存提供查询;

  2. 查询透过表引擎访问,本地缓存中记录数据访问热力图。

扩缩容活动:

  1. 源节点Export出去表在DFS上快照版本信息,作为恢复元数据。同时Export源节点访问热力图;
  2. 目标节点Import快照版本信息,恢复表引擎状态。同时Import热力图启动高频访问数据的异步加载;
  3. 源节点从快照位点开始增量同步到目标节点,追齐后切换提供查询。
数据基于DFS共享,整个过程不涉及数据的搬迁,比之前更为轻量,有更好的拓展性。

对于源节点访问的本地热数据,目标节点在热力图异步预取成功前会直接访问DFS,针对此类场景我们基于每个查询的具体结果集,以Batch的方式提前并发异步预读访问的数据,加速冷数据的访问。

三、总结

本文介绍了云原生数据仓库AnalyticDB MySQL版XuanWuV2的数据模型、数据和元数据等部分内容,除此之外,XuanWuV2还在多版本管理、轻量级Checkpoint、快速重启恢复、查询改写和优化等方面做了大量的改进工作,都是基于我们碰到的实际问题,期望能在当前XuanWu引擎的基础上做进一步的改良,充分继承其已有优势的同时,弥补它设计和实现上的不足,为线上的稳定性、性能、易用性和云原生拓展性打好基础,为客户创造更大的价值。

👇点击文末「阅读原文」查看XuanWuV2官方文档,即可了解更多内容。

点击查看 XuanWuV2引擎介绍

喜欢就请 点赞/分享/推荐 哦

文章转载自阿里云瑶池数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论