PolarDB-PG是云原生数据库,具有存储计算分离的架构。可以根据用户需要弹性扩充存储节点,也可以根据用户的计算需求弹性扩充用户的计算节点。但是如果使用原生的PolarDB-PG处理HTAP场景,在处理AP场景时会遇到两个挑战。
第一,单机的PG只支持单机的串行与单机的并行,不支持多机查询和跨机查询,无法发挥多个计算节点的特性,CPU和memory无法横向的scale out,只能单机scale up,即必须增加CPU和memory的实例规格。
第二,原生的PG直接套用到PolarDB上,无法充分发挥共享存储池的大吞吐能力,因为只能利用单机计算节点上的RO能力。
而根据TP和AP在存储和计算上是否共享与分离的维度,可以分为三种:
第一,TP和AP在存储计算上都分离,即分为TP与AP两套独立的系统。TP的数据需要导入到AP系统中,存在延迟、时效性不高的问题。同时两份存储也增加了冗余、存储成本以及运维难度。
第二,TP和AP在存储和计算上都共享。该模式对TP和AP查询时或多或少都会造成一些影响。同时,受限于TP查询,AP比重增大时,无法弹性scale out,同样也只能在单机上调整自己的CPU与memory。
第三,TP和AP在存储上共享,在计算上分离,即PolarDB云原生HTAP的方案。
PolarDB云原生HTAP的整体架构如上图所示。底层为共享存储池,上层为多个计算节点,每个计算节点内包含了一个读写节点和多个RO节点。
由于TP和AP共享一套存储,减少了存储成本,可以提高查询的时效性,能提供秒毫秒级的数据新鲜度。
其次,TP查询受限于RO节点与RW节点,而AP查询仅受限于部分RO节点,因此可以实现TP与AP的物理隔离,并杜绝了CPU与memory的相互影响。
另外,该架构具备Serverless的弹性扩展能力,可以在任何RO级联上发起分布式MPP查询,可以弹性调整MPP执行节点的范围,可以弹性调整单机MPP的单机并行度。
最后,该架构消除了数据的存储倾斜和计算倾斜,在执行过程中也可充分考虑到PG Buffer Pool的亲和性。
由于PolarDB底层存储在不同节点上是共享的,因此不能像传统MPP一样扫表。我们在原先的单机执行引擎上支持了MPP分布式执行引擎(跨机执行引擎)。同时对Shared-Storage做了优化,基于Shared-Storage的MPP是业界首创。其基本原理为借助Shuffle算子屏蔽数据的分布,借助ParallelScan算子屏蔽共享存储。
上图是典型的火山模型,扫描A表,再扫描B表进行HashJoin,最后做聚合输出。
而PolarDB的MPP场景下,对A表和B表进行了虚拟分区。两个只读节点上默配置了一个worker。左侧只读节点上的worker会扫描A表的Virtual Partition-1,右侧节点上的worker会扫描A表的Virtual Partition-2。B表同理。
通过对Virtual Partition-1和Virtual Partition-2虚拟表的共同扫描,屏蔽了共享存储。通过Shuffle算子的分发之后,分发到上层进行HashJoin的时,已经屏蔽了数据的分布。
而上述执行计划必然需要有优化器的支持。我们基于社区的ORCA优化器扩展了能感知共享存储特性的Transformation Rules。使得能够探索共享存储下特有的Plan空间,比如:一张表在PolarDB中既可以全量扫描,也可以分区域扫描,这是与传统MPP的本质区别。
上图中的A表按照分片扫描,但是如果B是小表,则可以做全表扫描。每个子节点都会扫描B的全量数据,构建一张哈希表。扫描B表的数据不需要下发到各个节点上。
上图灰色部分是PolarDB内核PORCA优化器的适配部分。下半部分是ORCA内核,灰色模块是我们在ORCA内核中对共享存储特性所做的扩展。
接下篇:https://developer.aliyun.com/article/1223065?groupCode=polardbforpg