您当前的位置: 首页 >  云原生

凌云时刻

暂无认证

  • 1浏览

    0关注

    1437博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

以“升舱”之名,谈谈云原生数据仓库 AnalyticDB 的核心技术

凌云时刻 发布时间:2022-07-21 17:30:53 ,浏览量:1

企业级云原生数据仓库 AnalyticDB 提出了升舱计划,旨在承担和帮助金融、运营商、政务等行业构建下一代数据管理和分析系统,以应对不断增长的数据规模、业务数字化转型和传统数仓替换升级的需求。7 月 19 日,“千仓万库,轻云直上——阿里云数据库升舱计划实战峰会”召开,点击文末“阅读原文”可观看峰会具体直播内容。

背景

说到升舱,我们首先想到的是飞机经济舱升级到商务舱、头等舱。阿里云企业级云原生数据仓库 AnalyticDB(以下简称 ADB)[1] 在帮助以金融机构为主的行业数字化转型和传统数仓升级项目中,也引用了“升舱(仓)”这个概念。

长期以来,企业级数据仓库构建主要以 Teradata、Oracle、DB2、Vertica、Greenplum 等为主,这些系统一方面功能完备,稳定可靠;另一方面成本高,部分有专用硬件限制,同时需要应对业务几何级数据量规模增长。以 Hadoop 生态为代表的大数据系统主要解决了数据分析的大规模数据量问题,在功能完备性,易用性和维护性上与这些传统数仓相比,还是有差距。所以大部分金融机构都是在保留已有 MPP 数仓核心业务的基础上,尝试部署 Hadoop 系统用于创新业务探索,同时解决数据增长带来的成本问题。

近年来,一方面国外涌现出了以 AWS Redshift , Snowflake , Google BigQuery , Azure Synapse 为代表的云原生数仓(公共云形态),有对传统数仓和 Hadoop 系统线下形态的替代和革命之势。另一方面随着上述传统数仓大厂在国内技术市场投入的减少,叠加政策等因素,同时金融、运营商等行业面临数据规模增长,数字化转型,和传统数仓升级需求,需要选型下一代数据管理和分析系统,另外由于国内外市场和政策的区别,我国金融、运营商、政务等行业的数仓构建,主要以混合云为主。

在此背景下,企业级云原生数据仓库 AnalyticDB 提出了升舱计划,旨在承担和帮助金融、运营商、政务等行业构建下一代数据管理和分析系统,以应对不断增长的数据规模、业务数字化转型和传统数仓替换升级的需求。

产品介绍

整体架构

AnalyticDB PostgreSQL 版(ADB)在开源 Greenplum[2]和 PostgreSQL[3]基础上进行自主研发,语法层面对两者保持兼容,功能层面为开源 Greenplum 超集,同时兼容大部分 Oracle、Teradata 语法与功能,支持业务应用以尽可能少的改造工作量对已有数仓业务进行迁移升级。其整体架构如下图:

在这里插入图片描述

图1 整体架构

构ADB 由协调节点和计算节点两大组件构成:

协调节点负责全局事务管理,全局元数据存储,SQL 解析,重写,优化,执行计划生成与调度。

计算节点主要包含执行引擎和存储引擎,其中执行引擎既支持 Greenplum/PostgreSQL 功能强大的原生引擎,又支持数据分析场景性能优化的自研向量化引擎,多态化存储引擎则支持本地行存堆表、列存压缩表,和外部表,以及基于存储计算分离架构下的云原生表。

协调节点和计算节点通过双副本保障高可用,同时通过水平和垂直扩展提供计算和存储资源的线性扩容。

ADB 与阿里云生态系统高度集成,支持以 OSS 为备份存储介质的分布式一致性备份恢复(包括全量和增量备份),同时支持通过 DBS 备份到 NAS,HDFS 等第三方存储介质。对于存储在 OSS 上的 ORC,Parquet,JSON,CSV 格式用户数据,和 MaxCompute 上的用户表和分区,支持并行高速并行导入加载到本地,或者通过列过滤、谓词下推直接对 OSS 上的数据进行数据湖分析。

在云原生架构形态下,云原生表则在计算节点本地则只有缓存数据(计算节点无状态化),全量数据存储在低成本的 OSS 上。

使用场景与生态集成

上文描述了 ADB 的整体架构和内部组件,传统数仓迁移替换,或者构建下一代数据管理分析系统,除了要具备高可用易扩展的分布式系统架构和功能完备性能出众的内核引擎外,还需要有开放的生态集成和管理工具配套。

下文从数据同步到数据加工再到数据查询分析,端到端描述 ADB 在数据处理各个阶段的生态集成、配套工具和场景支持能力。

在这里插入图片描述

图2 使用场景与生态集成

1、数据同步阶段,数据通过实时写入或批量加载方式入库,形成 ODS(Operational Data Model)层。典型的数据源包括:MySQL/SQL Server/PostgreSQL/Oracle 等 OLTP 业务数据库,业务 App 产生的实时数据,在 OSS/MaxCompute/Hadoop 上的归档或原始数据,以及来自 Kafka/Flink 等的流式数据。

ADB 通过 MVCC,两阶段提交(2PC),和全局事务管理(GTM)机制提供分布式事务能力(默认隔离级别 Read Committed),同时在实时写入场景支持 Upsert 覆盖写(Insert on Conflict,功能等同于 Oracle 的 Merge Into),批量导入场景支持外表,文件,自定义程序输出等多种并行高速加载。

2、数据加工阶段,在库中对 ODS 层数据进行加工,形成 CDM(Common Data Model)和 ADS(Application Data Service)层,典型操作包括 INSERT INTO SELECT, CREATE TABLE AS 等。

3、数据查询分析阶段,按业务需求对库中数据进行查询分析,或供下游系统消费处理,典型的查询分析场景包括交互式分析,BI 报表,数据类业务应用等。ADB 既通过存储引擎索引排序等特性支持高并发低延时的多维度点查范围查场景,也通过向量化执行引擎,CBO 自适应优化器,列式存储支持大数据量多表关联聚合的复杂分析场景。

产品形态与硬件平台

ADB 除了在公共云提供国内和国际站的 SaaS 服务外,也通过阿里云飞天企业版(ApsaraStack)和敏捷版(DBStack)支持混合云输出,满足线下部署需求。与部分传统数仓需要专有硬件平台不同,ADB 本身支持 x86 通用硬件部署,同时也支持 Arm 架构,以及国产化鲲鹏平台、海光处理器、麒麟系统等。通用硬件和国产化平台的支持,也是金融等领域数仓升级的重要参考因素。

核心技术

通过上面概括性的产品介绍,我们对 ADB 的整体架构、使用场景与生态工具、产品形态与硬件平台支持有了基本了解。下面进一步深入到其在“升舱”项目中的部分硬核技术,包括自研向量化执行引擎,多态化存储引擎,基于代价的自适应优化器,租户间不同实例和租户内不同负载的资源隔离,以及存储计算分离形态的云原生架构。

向量化执行引擎

PostgreSQL 在上世纪八十年代诞生时数仓分析 OLAP 场景尚未出现,其主要用于处理 OLTP 场景,执行引擎是 Record-Oriented(Tuple-at-a-time)的火山模型,Greenplum 在 PostgreSQL 基础上构建了 MPP 分布式数据库,在执行引擎层引入了 Motion 节点,使得集群中每个计算节点都能像单机 PostgreSQL 一样运行,共同完成由协调节点下发的 SQL 分布式执行计划,最终通过协调节点汇总返回查询结果,通过分布式并行执行大大提升了单机 PostgreSQL 的性能瓶颈。

但在每个计算节点执行引擎内部,依然是 PostgreSQL 原生的 Record-Oriented 模型(即每个算子每次处理一条记录),该执行模型对与以点查或少数据量处理场景为主的 TP 场景没有问题,但对于以大数据量处理场景为主的 OLAP 场景,单条记录处理的开销较大,综合性能和效率较低。

后期基于 Postgres 构建的数据分析系统,如 Redshift,Vertica,Vectorwise(准确来说是基于 Postgres 的前身 Ingres),都对 PG 原有执行引擎进行了替换改造,Redshift 主要是基于 Code Generation(JIT, Just-in-Time Compilation)和 Vectorized Scan,Vectorwise 则是纯粹的向量化执行。PostgreSQL 11 也支持了表达式的 JIT[4],用以加速 SQL 中的表达式处理。

ADB 在保留原生 Greenplum/PostgreSQL 引擎的同时,自研了 Block-Oriented(Batch-at-a-time)向量化执行引擎,用于处理大数据量的分析场景。下图以两边关联后做聚合的简单 SQL 为例,做了两者对比。

在这里插入图片描述

图3 执行模型:Record-Oriented V.S. Block-Orientend

对比 Record-Oriented 通过 getNext() 接口每次获取和处理一条记录,Block-Orientend 模式通过 getNextBlock() 接口每次获取一批记录,同时每个执行算子综合运用向量化(Vectorization)[5]和即时编译 (JIT)[6]技术,对这一批记录执行相同处理逻辑,从以下收益出发,获得更高效的资源使用,更快的执行性能:

每次读取和使用相同逻辑处理一批记录数据,能获得更高的 CPU 指令和数据缓存命中率 [7]。

从一次函数调用处理一条记录,到一次函数调用处理一批数据,同时 JIT 则直接避免了函数调用,总体函数调用次数和开销 [8] 减少。

内存的分配回收,也从每条记录的分配回收,到每批记录的分配和回收,整体减少内存分配回收次数和碎片管理开销 [9]。

在按批处理模型下,代码实现能更好地以向量化方式实现,一方面有利于 CPU 进行数据预取,另一方面尽可能减少程序的条件跳转(来自 if…else…,switch 等分支判断)和无条件跳转(来自函数调用),让 CPU 获得更好的指令流水线执行 [10],减少分支预测 [11] 失败,同时也有利于编译器生成 SIMD [12] 指令,提高执行效率。

下图分别展示了 ADB Vectorization 在分组聚合 SQL 场景进行算 Hash,桶寻址,求 Sum 步骤的列式向量化执行示例,和 JIT 在扫描过滤 SQL 场景进行表达式计算的示例。

在这里插入图片描述

图4 Vectorization 与 JIT 实现示例

向量化按批读取和处理的行为,在本批次中让需要处理的数据和处理指令都驻留在 CPU L1/L2 Cache 中,在缓存命中情况下性能为从内存读取的 10~30 倍[13],同时对该批次数据进行相同指令的处理,也能让 CPU 更好的流水线执行,减少 CPU Hazards[14]。JIT 代码生成针对表达式处理场景,则直接避免了解释执行模式下的函数高频函数调用(Function Calls)。

多态化存储引擎

PostgreSQL 原生存储引擎为堆表(Heap Table)[15],主要为 OLTP 场景,核心组件包含默认 8KB 为单位行级 MVCC 的数据页 Page,缓存管理器 Buffer Manager,和预写日志 WAL,以及以 Btree 为主的索引。Greenplum 基于 PostgreSQL 构建了分布式数据库,主要为 OLAP 场景,在存储层主要做了如下技术改造:

1、协调节点新增全局元数据和全局事务状态管理,以支持分布式架构下在协调节点的事务管理,SQL 解析和执行计划生成等需要读取元数据系统表的操作。

2、新增分布式架构下表的水平分布机制(支持哈希,随机和复制分布策略,对业务层透明),以及节点内部垂直分区机制(支持范围和列表分区,后续高版本 PostgreSQL 自身也增加了分区机制)。两者结合支持更大的数据规模和查询过滤效率。

3、对行存堆表由默认页大小由 8KB 设置为 32KB,以获得数据分析场景更好的扫描效率。

4、新增列存压缩表,相比 PostgreSQL 原生的行存堆表,通过列裁剪和压缩,进一步提升分析场景的扫描效率。列存表的元组(Tuple) ID 保持与堆表一致为 48 位,可以直接适配 PostgreSQL 现有索引机制(包括 Btree,Brin,GIN,GiST 等)进行指定列值的索引扫描,加速点查场景。利用支持 MVCC 事务隔离机制的行存堆表作为列存的元数据辅助表,一来用于列存数据的寻址,二来引入 Delete Bitmap 通过标记删除的方式让列存在追加写的基础上支持了更新和删除,同时列存数据也间接有了 MVCC 和事务隔离能力。

5、引入了 PXF 外表,用于访问 HDFS,Hive,MySQL,PostgreSQL 等外部系统。ADB 在 Greenplum 基础上,对本地列存压缩表和行存堆表进行了进一步增强(包括列存排序合并,排序加速计算,MIN&MAX 粗糙过滤,实时物化视图,自动 Analyze/Vacuum/Merge,Upsert 等),对外表则新增了对阿里云 OSS 和MaxCompute的并行导入及数据湖分析能力,同时新增了云原生存储计算分离表(云原生架构产品形态下支持),存储按需计费,灵活弹性扩缩,支持数据共享。下图为 ADB 多态化存储引擎概览。

在这里插入图片描述

图5 多态化存储引擎

下面就 ADB 在存储引擎层的部分自研能力做进一步技术探讨。

稀疏索引

Min & Max Skip Index 是 ADB 在 Greenplum 列存上新增的第一个自研特性,类似于 PostgreSQL9.5 开始支持的 BRIN,简单来说为列存表相应列数据的每个存储块(如varblock)记录该存储块中所有数据的最小值(MIN)和最大值(MAX),扫描时将过滤条件与每个存储块的 MIN 和 MAX 比较,过滤掉一定不包含该过滤条件存储块。

对于可能包含该过滤条件的存储块,则进行具体数据读取,解压,扫描,比较,获得具体的匹配记录。目前主流列存均提供该项能力(如 Redshift 的 Zone Maps [16],ClickHouse 的 Skip Indexes [17]),这里不做过多展开。ADB 除了记录了每个存储块的 MIN & MAX,也记录了多个连续存储块总体的 MIN & MAX,起到进一步快速过滤的效果。

排序合并

排序是列存引擎的关键能力,主流列存在建表时都支持定义排序键(如 Redshift 的 Compound Sort Key [18] 和 Interleaved Sort Key [19],Snowflake 的 Clustering Key [20], ClickHouse 的 Order By [21]),支持手工或者后台自动合并排序,以获得高效的扫描过滤。

同时上面讲的 MIN & MAX Skip Index 必须要依靠排序才能真正发挥作用(除非数据在写入时就天然有序),试想数据无序情况下每个存储块的最大值最小值范围可能都包含过滤条件,比较下来能 Skip 掉的数据块很少,也就相当于 MIN & MAX Skip Index 没有作用。

ADB 在列存排序能力上支持组合排序(对应上述 Redshift 的 Compound Sort)和多维排序(对应上述 Redshift 的 Interleaved Sort,目前 Databricks 的 Delta Lake [22] 也有该能力),两者的区别和使用场景可以参考 Redshift 的这篇 Blog[23],这里不做详细展开。通常新写进来的数据为无序状态,ADB 针对组合排序支持后台自动排序合并(多维排序可在 ETL 步骤中执行 multisort

进行排序),一个好的自动合并排序策略需要达到如下四个目标:

让大部分数据处于有序状态(理想状态是所有数据都有序) 减少数据文件数量和无效数据(来自 delete 和 update)在数据文件中的占比(理想状态是一个文件包含了所有有效且有序数据)

让排序合并需要的资源开销(包括 IO,CPU,MEM)最小化 对前端业务负载影响(如锁,资源竞争等)最小化 这块目前业界做的较好且有公开资料有 Snowflake 的 Automatic Clustering[24],和 SingleStore 的 Background Merger[25]。前者引入的 Overlap-Depth 的概念来实现上述目标 #1,#2,#3,后者的 optimistic/pessimistic 策略则兼顾了上述所有目标。

ADB 的具体实现为将列存数据分为 Unsorted Region 和 Sorted Region 两部分,后台自动排序合并 Worker 负责将 Unsorted Region 中的数据排序合并成一个 Sorted Region 的一个文件。在 Sorted Region 内部又分为不同的 Sorted Part,每个 Sorted Part 中的不同有序文件的 MIN 和 MAX 值没有重叠,在扫描时可以把整个 Sorted Part 当成一个有序文件来处理,提高扫描效率。

为了进一步提升 Sorted Region 内数据的扫描过滤效率,Sorted Region 内不同 Sorted Part 中的文件会进行自动合并,以消除不同 Sorted Part 间的 MIN & MAX 重叠,成为一个新的 Sorted Part。

经过早期上线后使用反馈,我们认为 Unsorted Region 到 Sorted Region 的排序合并相比 Sorted Region 内部 Sorted Parts 间的合并优先级更高,所以分别定义了 Fast Worker 和 Common Worker 来区分优先级地处理两种场景。同时整个排序过程不影响业务侧 DML 操作,这样也达成了上述的四个目标。整体排序合并如下图下半部分:

在这里插入图片描述

图6 排序合并 & 查询加速

上图展示的另外一个功能是基于有序数据的查询加速。

数据有序,首先就是提升了 MIN & MAX Skip Index 的有效性,让 Scan 在条件过滤时对文件的 Skip 和 IO 更精准。

另外执行引擎本身就有 Sort 算子,用于辅助实现 SQL 中的 OrderBy,Group Agg,Merge Join,和 Distinct 等算子,如果存储引擎数据本身就有序(或者大部分有序,因为在实时写入场景下 Unsorted Region 是常态化存在的),那么执行引擎在运行上述要求数据有序的算子时就可以利用这一点,减少额外Sort开销,提升整体性能。

所以这里 ADB 的做法是将这些算子需要的 Sort 算子下推到 Scan 中(我们叫做 SortScan),让 Scan 吐给上层算子的数据有序。

对于一张有数据不断实时写入的表,通常每个节点上的数据同时分布于 Sorted Region(大部分)和 Unsorted Region(小部分)中,SortScan 的具体实现如上图,首先对 Unsorted Region 的数据进行快速排序(如果表数据写入更新相对低频,那么这部分工作通常是不需要的),然后和 Sorted Region 的数据一起进行归并排序,让吐出的数据整体有序,从而加速上层依赖排序的算子。

另外,有序数据在执行引擎处理时本身就能带来很好的缓存命中率,从而提升性能,如 Hash 表计算,连续有序数据在基数比较低的情况下有较多重复,在 Hash 桶寻址时在一段连续数据范围内总是相同。

自动排序合并是当列存引擎要同时支持批处理和实时处理的场景时不可或缺的能力,用来让其在读写性能间获得最佳平衡。

实时物化视图

如果说索引用来加速 SQL 数据扫描算子(Scan)的过滤能力(Index Scan),那么物化视图则是用来加速整个查询 SQL。PostgreSQL 10[26]和 Greenplum 6.2[27]开始分别支持了物化视图,但功能和使用场景比较有限,均需要手工全量刷新,并且不支持查询自动改写。

实时物化视图,一般需要具备自动增量刷新,和自动查询改写能力,更高阶的还有后台根据历史 SQL 执行情况,自动创建物化视图。主流数据管理系统如 Oracle[28],Redshift[29],Snowflake[30]在自动增量刷新和查询改写能力上均有相应体现。

ADB 针对本地行存堆表也构建了实时物化视图功能,整体设计实现如下图:

在这里插入图片描述

图7 实时物化视图

工作流程分为如下步骤:

视图创建:首先用户根据业务常用查询 SQL 创建对应的用于加速的实时增量物化视图

视图自动维护刷新:数据写入更新删除操作首先作用到 User Table 本身,同时生成对应的变更日志(包括新增数据和删除数据)同步到 Delta Log,增量合并刷新则读取 Delta Log,结合 MV 的具体定义,对每个支持的算子(包括过滤,投影,关联和聚集)应用增量合并刷新算法,更新物化视图内容。

查询自动改写:当前执行 SELECT 查询 SQL 时,根据 SQL 本身和库中存在的物化视图定义,搜索可用于改写的物化视图,完成改写,加速查询。若没有可用物化视图或者输入 SQL 不支持自动改写,依然查询原表数据。

ADB 当前物化视图的实现为强一致模型,和索引一样,在加速查询性能的同时,会对写入性能有一定影响,类似机制本身是业务在写入查询性能两者间的取舍。如果未来支持最终一致模型,则是在写入性能和查询实时性方面的取舍。

Auto Analyze & Vacuum

PostgreSQL 本身支持 Auto Analyze[31]和 Auto Vacuum[32],前者用于统计信息的自动收集,后者用于表数据被更新删除后的空间自动回收再利用。

Greenplum 在将单机 PostgreSQL 改造成分布式架构的同时,并未对这两项功能进行分布式改造,前者引入了 gp_auto_stats_mode[33]来替代,后者则要求 DBA 定期执行。

gp_auto_stats_mode 的机制是可设置当前表当前没有统计信息时,则在第一次写入数据结束时自动触发Analyze,或者每次写入更新的数据量到达一定数量时自动触发 Analyze。这个机制对应数仓批量导入和数据加工场景可以很好地工作,但是遇到实时写入更新场景则有问题。

早期 ADB 公共云线上在实时流式写入场景经常碰到的问题是表在第一次写入少量数据时执行了 Analyze 后就再也不执行了(on_no_stats 设置),或者因为实时场景每次写入的数据量少,很少达到 on_change 设置下触发 Analyze 的条件(gp_autostats_on_change_threshold)。

这两种情况带来的问题就是统计信息不准,导致执行计划不佳,查询性能低下(如该走 Index Scan 的走了 Seq Scan,该走 Redistribute Motion 走了 Broadcast Motion,该走 Hash Join 走了 Nestloop Join等)。让 DBA 定期做 Vacuum 也不符合云原生数据库的定位。

基于此背景,ADB 在分布式架构下增加了 Auto Analyze 和 Auto Vacuum 功能,能够在每张表的数据量变化到达设定阈值(为累积计算,不像 gp_auto_stats 一样要求在一次变更中达到)时自动触发 Analyze 和 Vacuum。考虑到该功能为通用能力,上线后我们也将其代码贡献给了 Greenplum 开源社区。

OSS外表

阿里云 OSS[34]是海量低成本对象存储,亦是数据管理系统构建数据湖分析的最佳组合。ADB 基于 Postgres FDW[35]框架实现了分布式架构下的 OSS FDW 外表,与阿里云生态高度集成。该能力对应与 Redshift 的 Spectrum[36]和 Snowflake 的External Table[37]。OSS 外表整体场景和架构如下图。

在这里插入图片描述

图8 OSS 外表

ADB 存储引擎在本地行存堆表和本地列存压缩表的基础上新增 OSS 外表,支持 OSS 多种格式(ORC,Parquet,CSV 等)数据并行高速加载到本地,或者不加载直接在线分析,亦或者与本地表关联分析(加载或分析时 OSS 上的文件自动均匀映射到对应计算节点处理),同时支持列存表对冷分区数据自动分层到 OSS。

为了加速在线分析性能,支持外表 Analyze 统计信息收集,分区裁剪,同时对 ORC,Parquet 列式存储数据支持列裁剪和谓词下推。除了 OSS 外表,ADB 也支持阿里云 Max Compute 外表进行数据批量加载。

备份恢复

数据备份恢复是金融等行业对企业级数仓数据能力的普遍要求。

单机 PostgreSQL 可以通过 pg_basebackup + WAL 归档支持 Continuous Archiving and Point-in-Time Recovery (PITR)[38], 或者通过 pg_dump 做表级逻辑备份。

Greenplum 在基于单机 PostgreSQL 做分布式架构改造后,并未提供对应集群级物理备份和 PITR 能力,集群级逻辑备份则通过 gpbackup and gprestore[39]提供集群/表级的并行逻辑备份和恢复。gpbackup 运行期间系统无法建删表或改表结构,也不能对用户表做 truncate 等操作。

早期 ADB 基于此做定期实例级逻辑备份恢复,公共云业务实例众多,每个客户的维护窗口不同,同时部分业务较难找到维护窗口,同时数据量越大,备份需要的时间也越长。

为此 ADB 对 gpbackup 做的更细粒度的锁优化,让备份期间对业务影响最小(不阻塞 DDL 等操作)。优化本质上是牺牲备份时部分表的一致性(如果遇到业务DDL的情况),但恢复时依然可手工处理,这样取舍的背景是认为恢复是低频操作,但备份是每周甚至一周多次的高频操作。

逻辑备份恢复所能提供的 RPO 是较低的,一般默认一周备份一次(最坏情况下 RPO 也就是一周)。为此 ADB 开发了分布式一致性物理增量备份和PITR恢复,功能上达到单机 PostgreSQL PITR 的能力。整体设计实现如下图:

在这里插入图片描述

图9 物理备份恢复

一句话讲明白就是每个节点(包括协调节点和计算节点)都定期做单机 PostgreSQL 的 pg_basebackup + Continuous Archiving,同时通过周期性的全局恢复点确保恢复时的分布式一致性。

从这个层面讲 PITR 就是从原集群记录的一系列一致性恢复点中选取一个进行恢复,所以理论 RPO 是最后一次一致性恢复点的时间,恢复点打点周期可设为分钟到小时级。为了让备份数据尽量小,ADB 还实现了全量基础备份的差异备份能力,对应表中距离上次未变更的数据部分在本次基础备份中不重复备份。在备份数据存储介质层面,公共云为 OSS,混合云则支持 OSS,或者通过 DBS[40]支持 NAS 和 HDFS。

自适应优化器

PostgreSQL 自带了基于代价估算的 Planner 优化器,其开销低性能好,对于 TP 场景和 AP 简单分析场景非常高效。Greenplum 在将 PostgreSQL 扩展成分布式架构的同时,也对 Planner 进行了相应改造,使其能够生成包含 Motion 节点的分布式执行计划。

同时 Greenplum 又新增了 ORCA 优化器[41],以应对 CTE,多表关联,动态分区裁剪等复杂分析场景,当然一般情况下启动代价会比 Planner 高,同时在部分受限场景具备自动回退到 Planner 的能力。

Planner 和 ORCA 本身各有优势且功能完备,能够覆盖 AP 和 TP 全场景,所以 ADB 并没有像执行和存储引擎那样新增自研优化器,而是在 SQL 解析和重写阶段根据 SQL 本身自动选择最优的优化器来生成执行计划,同时为Planner增加Plan Hint干预能力,可在少数场景人工干预局部调整执行计划。整体逻辑如下图:

在这里插入图片描述

图10 自适应优化器

自适应优化器的行为可简单概括为:AP 复杂查询,启用 ORCA 优化器,在部分复杂分析场景能生成更优的执行计划;TP 实时写入更新删除点查场景,以及 AP 简单查询分析场景,走 PostgreSQL 自带的的经过分布式改造的 Planner 优化器,相比 ORCA 启动时间短,对 SQL 整体 RT 影响小,同时具备 HINT 人工微调功能。

多租户资源隔离

多租户与资源隔离是云原生数仓的必备能力,ADB 既支持租户间不同实例的资源隔离,也支持租户内不同负载的资源隔离。前者(管控能力)在公共云通过 IaaS 层不同 ECS 实现,混合云则通过容器和 Cgroup 机制实现,后者(内核能力)则基于 Greenplum 自带的 ResourceQueue[42],ResourceGroup[43]以及 Diskquota[44]实现。

下图以混合云敏捷版 DBStack 为例,描绘了多租户下多实例的部署形态,以及在实例内部通过 ResourceGroup 对不同业务工作负载的并发,CPU 和内存使用配额示例,以提供不同负载间的资源隔离和共享,同时通过 DiskQuota 可以定义不同用户、不同 Schema 的存储容量使用配额,以更好地规划业务数据存储。

在这里插入图片描述

图11 多租户与资源隔离

离ADB 早期版本主要依靠 ResourceQueue 来控制不容用户的执行队列并发和 CPU 优先级,目前开始逐步过渡到 ResourceGroup,可提供更精细化和更高效的资源粒度控制。

云原生架构升级

Greenplum 本身和 Teradata,Vertica 等传统线下部署的数仓一样,为经典的 Shared-Nothing 架构,最初云数仓 AWS Redshift 也是如此。

这类架构具备高性能,功能完备等优点,同时也支持线性扩容,但由于数据存储在本地,扩容时涉及到大量数据迁移,耗时较长,迁移中的表一般业务侧需要读写等待。另外当不同业务部门部署多个集群实例确保资源隔离时,每个集群就是一个数据孤岛,当业务涉及到相同数据的使用时,需要在跨集群实例间进行同步和冗余。

基于此需求和限制,云原生数仓 Snowflake[45]率先推出了存储计算分离架构,数据和元数据持久化存储由 AWS S3 和自建分布式 KV 系统 FoundationDB 提供,计算资源由独立的 Virtual Datawarehouse 组成,彼此间资源隔离,同时通过共享的元数据和数据存储又快速做到无冗余数据共享,因为本地节点无状态,计算资源本身能做到快速弹性。

随着 Snowflake 存储计算分离架构的演进,Redshift 也由 Shared-Nothing 演进到 RA3 存储计算分离形态,而传统线下数仓 Vertia 也推出了 Eon Mode[46]存储计算分离形态。

基于上述背景,ADB 在公共云目前推出了基于存储计算分离架构的 Serverless 模式[47],整体架构如下图:

在这里插入图片描述

图12 云原生架构升级

基本思路是让计算节点无状态化,元数据逐步抽出存储到按区域部署的高性能分布式易扩展 KV 系统,数据存储到低成本 OSS,通过本地缓存加速持久化在 OSS 上的数据 IO。基于此架构,数据存储按需付费,灵活弹性扩缩容,和数据共享也就走进现实。

升舱流程

除了上面介绍的产品能力和技术外,AnalyticDB 的 Upsert 实时写入覆盖,存储过程,系统监控诊断等能力也是数仓替换升级中非常重要的能力。下面介绍下传统企业数仓到 ADB 的升舱流程,一张图表达如下:

在这里插入图片描述

图13 升舱流程

总体分为四步:

1、对已有系统和业务迁移评估。阿里云提供了 Adam 迁移评估适配工具,支持 Oracle 和 Teradata 到 ADB 的大部分 DDL 和 SQL 自动转换。

2、业务应用按需改造适配,同步进行 DDL 和已有系统数据到 ADB 的迁移。DTS 数据同步传输服务支持 Orcale 到 ADB 的实时同步,亦可通过快速并行批量导入完成一次性迁移。同时 ADB 本身基于 Greenplum 内核技术演进和云原生架构升级,第三方生态工具兼容性好。

3、业务双跑验证。在此阶段可引入灰度机制,过渡到业务割接。

4、业务完成割接到 ADB。从升舱项目启动至今,ADB 目前已在金融(银行,保险,证券),运营商,政务等行业有较多成功案例和标杆,既包括对已有业务系统中对 Teradata,Oracle,DB2,Greenplum 的替换升级,也有新业务的首次上线。

总结

本文从升舱背景、数仓技术演进及业务需求出发,首先介绍了阿里云云原生数据仓库 AnalyticDB 的整体架构、使用场景与生态集成、产品形态与硬件平台支持,然后逐一介绍了自研向量化执行引擎、多态化存储引擎、自适应优化器、多租户资源隔离和云原生架构升级等升舱中用到的核心技术。

在自研技术层面,按单机 PostgreSQL 本身对应能力,Greenplum 在 PostgreSQL 上改造后的对应能力,以及业界主流产品的相关能力和技术,再对 AnalyticDB 对应能力构建和具体技术设计实现路线进行了技术讲解。

最后总结了具体升舱四步流程。希望通过本文能让读者对 ADB 的产品架构和核心技术有全面的了解,可用于评估业务的升舱可行性。

参考链接: [1]https://www.aliyun.com/product/gpdb

[2]https://arxiv.org/pdf/2103.11080.pdf

[3]https://www.postgresql.org/

[4]https://www.postgresql.org/docs/11/jit.html

[5]https://www.youtube.com/watch?v=Hn4l8XC3-PQ

[6]https://www.youtube.com/watch?v=DvhqgmRQuAk

[7]https://medium.com/@tilakpatidar/vectorized-and-compiled-queries-part-2-cd0d91fa189f

[8]https://www.ibm.com/docs/en/xl-c-and-cpp-linux/16.1.0?topic=performance-reducing-function-call-overhead

[9]https://en.pingcap.com/blog/linux-kernel-vs-memory-fragmentation-1/

[10]https://www.geeksforgeeks.org/computer-organization-and-architecture-pipelining-set-1-execution-stages-and-throughput/

[11]https://www.geeksforgeeks.org/correlating-branch-prediction/

[12]http://ftp.cvut.cz/kernel/people/geoff/cell/ps3-linux-docs/CellProgrammingTutorial/BasicsOfSIMDProgramming.html

[13]https://cvw.cac.cornell.edu/codeopt/memtimes

[14]https://www.geeksforgeeks.org/computer-organization-and-architecture-pipelining-set-2-dependencies-and-data-hazard/

[15]https://www.interdb.jp/pg/pgsql01.html

[16]https://aws.amazon.com/cn/blogs/big-data/amazon-redshift-engineerings-advanced-table-design-playbook-compound-and-interleaved-sort-keys/

[17]https://clickhouse.com/docs/en/guides/improving-query-performance/skipping-indexes/

[18]https://docs.aws.amazon.com/redshift/latest/dg/t_Sorting_data.html

[19]https://docs.aws.amazon.com/redshift/latest/dg/t_Sorting_data.html

[20]https://docs.snowflake.com/en/user-guide/tables-clustering-keys.html

[21]https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/

[22]https://docs.databricks.com/delta/optimizations/file-mgmt.html

[23]https://aws.amazon.com/cn/blogs/big-data/amazon-redshift-engineerings-advanced-table-design-playbook-compound-and-interleaved-sort-keys/

[24]https://docs.snowflake.com/en/user-guide/tables-clustering-micropartitions.html

[25]https://docs.singlestore.com/managed-service/en/create-a-database/physical-database-schema-design/concepts-of-physical-database-schema-design/columnstore.html

[26]https://www.postgresql.org/docs/10/rules-materializedviews.html

[27]https://gpdb.docs.pivotal.io/6-2/ref_guide/sql_commands/CREATE_MATERIALIZED_VIEW.html

[28]https://oracle-base.com/articles/misc/materialized-views

[29]https://docs.aws.amazon.com/redshift/latest/dg/materialized-view-overview.html

[30]https://docs.snowflake.com/en/user-guide/views-materialized.html

[31]https://www.postgresql.org/docs/current/routine-vacuuming.html

[32]https://www.postgresql.org/docs/current/routine-vacuuming.html

[33]https://docs.vmware.com/en/VMware-Tanzu-Greenplum/6/greenplum-database/GUID-best_practices-analyze.html

[34]https://www.aliyun.com/product/oss

[35]https://www.postgresql.org/docs/current/postgres-fdw.html

[36]https://docs.aws.amazon.com/redshift/latest/dg/c-getting-started-using-spectrum.html

[37]https://docs.snowflake.com/en/user-guide/tables-external-intro.html

[38]https://www.postgresql.org/docs/current/continuous-archiving.html

[39]https://docs.vmware.com/en/VMware-Tanzu-Greenplum-Backup-and-Restore/1.25/tanzu-greenplum-backup-and-restore/GUID-admin_guide-managing-backup-gpbackup.html?hWord=N4IghgNiBcIOYAcBOBTAzgFwPapAXyA

[40]https://www.aliyun.com/product/dbs

[41]https://15721.courses.cs.cmu.edu/spring2017/papers/15-optimizer2/p337-soliman.pdf

[42]https://gpdb.docs.pivotal.io/6-11/admin_guide/workload_mgmt.html

[43]https://gpdb.docs.pivotal.io/6-11/admin_guide/workload_mgmt_resgroups.html

[44]https://github.com/greenplum-db/diskquota

[45]http://event.cwi.nl/lsde/papers/p215-dageville-snowflake.pdf

[46]https://www.vertica.com/wp-content/uploads/2018/05/Vertica_EON_SIGMOD_Paper.pdf

[47] https://help.aliyun.com/document_detail/383266.html

点击下方“阅读原文”可查看阿里云数据库升舱计划实战峰会直播详情。

以“升舱”之名,谈谈云原生数据仓库 AnalyticDB 的核心技术

关注
打赏
1663816507
查看更多评论
立即登录/注册

微信扫码登录

0.0712s