作者 | 恒义
背景
说到升舱,我们首先想到的是飞机经济舱升级到商务舱、头等舱。阿里云企业级云原生数据仓库AnalyticDB(以下简称ADB)[1]在帮助以金融机构为主的行业数字化转型和传统数仓升级项目中,也引用了“升舱(仓)”这个概念。
长期以来,企业级数据仓库构建主要以Teradata、Oracle、DB2、Vertica、Greenplum等为主,这些系统一方面功能完备,稳定可靠,另一方面成本高,部分有专用硬件限制,同时需要应对业务几何级数据量规模增长。以Hadoop生态为代表的的大数据系统主要解决了数据分析的大规模数据量问题,在功能完备性,易用性和维护性上与这些传统数仓相比,还是有差距。所以大部分金融机构都是在保留已有MPP数仓核心业务的基础上,尝试部署Hadoop系统用于创新业务探索,同时解决数据增长带来的成本问题。近年来,一方面国外涌现出了以AWS Redshift,Snowflake,Google BigQuery,Azure Synapse为代表的云原生数仓(公共云形态),有对传统数仓和Hadoop系统线下形态的替代和革命之势。另一方面随着上述传统数仓大厂在国内技术市场投入的减少,叠加政策等因素,同时金融、运营商等行业面临数据规模增长,数字化转型,和传统数仓升级需求,需要选型下一代数据管理和分析系统,另外由于国内外市场和政策的区别,我国金融、运营商、政务等行业的数仓构建,主要以混合云为主。在此背景下,企业级云原生数据仓库AnalyticDB提出了升舱计划,旨在承担和帮助金融、运营商、政务等行业构建下一代数据管理和分析系统,以应对不断增长的数据规模,业务数字化转型,和传统数仓替换升级需求。7月19日,“千仓万库,轻云直上——阿里云数据库升舱计划实战峰会”即将在线上召开。
产品介绍
整体架构
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 <table>进行排序),一个好的自动合并排序策略需要达到如下四个目标:
1.让大部分数据处于有序状态(理想状态是所有数据都有序)
2.减少数据文件数量和无效数据(来自delete和update)在数据文件中的占比(理想状态是一个文件包含了所有有效且有序数据)
3.让排序合并需要的资源开销(包括IO,CPU,MEM)最小化
4.对前端业务负载影响(如锁,资源竞争等)最小化
这块目前业界做的较好且有公开资料有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 实时物化视图
工作流程分为如下步骤:
1.视图创建:首先用户根据业务常用查询SQL创建对应的用于加速的实时增量物化视图
2.视图自动维护刷新:数据写入更新删除操作首先作用到User Table本身,同时生成对应的变更日志(包括新增数据和删除数据)同步到Delta Log,增量合并刷新则读取Delta Log,结合MV的具体定义,对每个支持的算子(包括过滤,投影,关联和聚集)应用增量合并刷新算法,更新物化视图内容。
3.查询自动改写:当前执行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。基于此架构,数据存储按需付费,灵活弹性扩缩容,和数据共享也就走进现实。ADB的云原生架构升级和数据共享之前已有文章分享和演示,这里不做进一步展开,感兴趣读者可查看:从托管到原生,MPP架构数据仓库的云原生实践实操宝典 | 如何借助实例间数据共享,破解数仓数据流转难题?[48]升舱流程
除了上面介绍的产品能力和技术外,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
[48]https://mp.weixin.qq.com/s/h15UK4--Js5ApFwuY96GKA