转:MySQL HeatWave RAPID引擎实现原理深入解析(上)

100人浏览   2025-01-10 10:31:23

说明


MySQL HeatWave使用的引擎,即为RAPID引擎。


一介绍

当前正处于数据量急速膨胀的时代,而大数据时代又决定了数据处理系统的硬件和软件的发展。现代企业对日常分析和商业智能类工作负载的要求,则强调了当今的IT系统在性能和功耗方面的局限性。为了应对这一趋势,现代数据处理系统需要重新思考软件设计和底层硬件的支持。而不是通过将软件和硬件隔离的方式来设计现代的数据处理系统。

纵观硬件的格局,可以看到,越来越多的晶体管被用于更多的处理核心、大型缓存、新的指令集以及其它高级功能。主存储器的成本也在不断降低。因此,现有的数据处理系统可以通过利用硬件的最新进展来提供更高的性能。遵循硬件的设计逻辑,系统需要通过更高的并行度、更大的缓存,以及更多针对互联的数据放置,和先进的矢量处理,从而进行扩展,以实现更高的绝对性能。

一般来说,当今的商用硬件,往往是针对通用业务提供最佳性能。因此,硬件虽然会增加功耗和复杂性,但是不一定就能够为特定应用提供最佳的性能表现。而这往往只会增加现代云数据中心的性能/电源要求的挑战。对于现代的云数据中心而言,系统除了能够提供高性能之外,还需要有功耗意识。

而从历史上看,数据处理系统的设计,是由商业硬件驱动的。其目标为,通过相应地调整软件设计来利用新的硬件性能。但是,我们也可以用相反的方式来思考这个问题:硬件应该如何为数据处理进行量身定制?高效的关系型数据处理,究竟需要哪些功能?同样,为了降低功耗和让处理器设计更简单,哪些不必要的功能又是可以放弃的?对以上问题进行回答,就可以将硬件设计进行收敛,从而紧密集成软件和硬件,以进行高效的数据处理。由于是从头开始重新设计架构,并能够充分考虑软硬件协同,因此就能够提供极致的查询执行性能,并为分析处理带来至少一个数量级的性能提升。

RAPID查询处理引擎,与被称之为数据处理单元(Data Processing Unit,DPU)的新处理器共同设计。DPU由32个被称之为dpCore的低功耗处理器核心组成。dpCore是一个简单的有序CPU,具有简单的分支预测功能、16KB的SRAM缓存,以及32KB的SRAM暂存器。每个dpCore均可以执行简单的类MIPS指令,且具有为数据库处理量身定制的单指令周期延迟。DPU并非缓存一致的,与DRAM之间的传输,是使用了称之为DMS的数据移动系统来明确编程实现的。DMS是数据shuffle和分区的核心,且无dpCore的参与。从本质上来说,DPU抛弃了许多复杂的组件,例如大型缓存、复杂的分支预测器、高级指令,以及缓存一致性,从而能够以更低的功耗和更小的尺寸来处理数据。

RAPID是一种关系型查询处理引擎,旨在支持现代的分析型工作负载,与现有的数据库系统相比,它更强调在低功耗的情况下的查询性能。RAPID是可插拔的,可以附加到OCI MySQL数据库云服务(MDS)以卸载分析类查询。


二RAPID DPU架构

RAPID DPU是一种低功耗、可编程的处理单元,专门被设计用来在40nm制造工艺下以5.8W的额定功率来加速数据处理。每个处理内核在800MHz下消耗51mW的动态功率。DPU的主要设计目标,是通过硬件设计,来加速处理分析类工作负载。

图1 RAPID DPU框架图

2.1 dpCore

DPU包含32个数据处理内核(dpCore),采用简单低功耗设计,可以协同实现数据并行性。dpCore被组织成4个宏,每个宏包含8个内核。dpCore使用了面向通用计算的64位MIPS类指令集架构(ISA)。为了加速分析类查询运算符(例如选择,连接等),ISA提供了单周期指令,例如位矢量加载(Bit-Vector Load,BVLD),过滤器(Filter,FLT),以及哈希码生成(CRC32)等。

dpCore实现了一个简单的双流水线,一个用于算术逻辑单元(Arithmetic Logic Unit,ALU),另外一个用于加载存储单元(Load-store Unit,LSU)。ALU支持低功耗乘法器,该乘法器可以将流水线分隔为多个指令周期,但是不支持浮点运算。doCore使用了一个简单的分支预测器来预测反向分支。内存处理模型则比较宽松,带有隔离挂起加载以及存储相关的指令。doCore没有内存管理单元,采用直接寻址方式。

2.2 DMEM与缓存

每个dpCore都包含一个32KB的SRAM暂存器,称之为数据存储器,简称为DMEM。DMEM主要负责dpCore的单周期延迟,以及快速临时的存储。由软件进行管理。

dpCore也支持通用的缓存分层结构,包含私有的16KB L1-D缓存,以及8KB的L1-I缓存。同时在宏内部,dpCore之间也共享256KB的L2缓存。为了降低芯片的复杂度和功耗,硬件不负责缓存之间的数据一致性。相反,ISA则为软件管理的一致性提供了缓存刷新和无效指令。

2.3数据移动系统(DMS)

RAPID DPU具备DMS这一片上可编程数据移动引擎,用于在DRAM和dpCore之间移动数据。大多数的数据访问,都是使用DMS来通过DMEM的。与使用CPU缓存和硬件预存器的传统方法相比,DMS更节能,并且可以处理不规则的数据访问模式。DMS支持在传输数据时涉及水平hash/范围分区,以及分散/聚集的复杂访问模式。DMS能够将数据直接放入DMEM,使得dpCore立即可用,且无需任何开销。

2.4片上通信

被称之为原子事务引擎(ATE)的硬件,允许dpCore之间进行通信。ATE包含1个连接了8个dpCore和4个宏的2级交叉开关,用于管理消息传递,并保证通过该互联的数据能够进行点对点的排序。在每个dpCore上,硬件ATE引擎管理DMEM指针并传递消息和中断。ATE使得我们能够在硬件的支持下进行有效地消息传递和原语同步(例如互斥锁、隔离)。

2.5 DPU总体组织

总而言之,图1就描绘出了整个RAPID DPU片上系统(SoC)的示意图。4个dpCore宏,以及DMEM就构成了执行大部分操作的dpCore复合体。此外,SoC还包括一个电源管理单元(PMU或者M0),两个ARM Cortex-A9双核处理器、一个邮箱控制器(MBC,MailBox Controller,是一个硬件队列,用来进行A9、dpCore,以及M0之间的通信),以及一些外围组件,例如PCIe以及DRAM控制器等。


三RAPID软件架构

RAPID引擎可以集成到Oracle的OCI MySQL 数据库云服务(MDS)上。图2就描述了这一集成的RAPID高级架构。

图2 RAPID软件架构图

与MySQL集成的主要目标,是能够在用户应用或者查询不做修改的情况下,也可以加速分析类工作负载。是否卸载此类操作,则依赖于RAPID所支持的操作,以及在RAPID中所估计的执行成本。查询的卸载部分在RAPID当中执行,结果被发送回MySQL进行进一步的处理。在这里,MySQL就是RAPID引擎中的数据来源,因此需要将其中的表加载进RAPID当中,并且在源表数据发生变化时,需要将这些更改传播到RAPID当中。

3.1查询编译和优化

MDS的SQL查询分析器对RAPID使用的成本模型进行了扩展,从而能够基于成本进行卸载决策。MySQL接收SQL查询,然后进行解析、语义分析、规范化、分解,常量处理,以及数个查询重写阶段。MDS的执行计划生成器将会考虑:i)完全卸载:只使用RAPID引擎;ii)部分卸载:卸载查询的某些片段;iii)完全不卸载。

如果a)RAPID支持某一查询片段的关系运算符,并且b)该片段中的运算符所使用的表已经被加载进RAPID引擎,则该查询片段就是卸载操作的候选对象。基于成本的优化器采用了自下而上的工作方式。对于每个候选片段,都会考虑RAPID的执行、结果的网络传输,以及后继处理的累积成本。

一旦执行计划生成器确定了成本最低的执行计划,就可以生成查询的执行计划(Query ExecutionPlan,QEP)了。并且作为代码生成的一部分,也将会构建逻辑运算符树。它通常包含一个或者多个占位符节点,用于标记哪些子树会被用于RAPID卸载。对于占位符节点下的每个子树,都会执行RAPID编译(参见5.2小节)。它会在占位符节点中生成、序列化,以及存储RAPID 的QEP。

3.2查询执行卸载模型

MDS中的执行范例,是基于拉取方式的,并遵循迭代器模式。每个运算符都实现了一组方法:allocate()、start()、fetch()、close(),以及release()。执行自上而下进行,结果自下而上进行传播。一旦MDS在RAPID运算上调用start(),就会检查查询对RAPID的可接受性以确保事务语义(可参见3.3小节)。在成功的准入检查之后,RAPID QEP将会被发送到每个RAPID的执行节点上。RAPID节点然后实例化接收到的QEP并调度执行。

RAPID端的执行,则是基于推送方式的。数据以流式的方式推送到QEP的运算符,当数据从根运算符流出时,则通过网络进行传输,并以RDMA(Remote Direct Memory Access,远程直接内存访问)的方式放入MDS的内存缓存区。一旦MDS的RAPID运算符检索到了数据,就会进行后继处理,例如解码或者其他转换操作等。

如果不满足接受标准,或者在RAPID当中运行失败,则RAPID运算符就会报告失败,或者是退回到MDS生成的替代执行计划。

:拉取方式vs推送方式

拉取方式,即pull-based模型(即经典的火山模型);推送方式,即push-based模型。

推送和拉取两种模型中,其控制流和数据流的关系如下:

由上图可知,拉取模型的设计更加符合查询执行的直观印象,上层算子按需向下层算子获取数据并执行。其本质上,就是一层层的虚函数调用。

推送模型则刚好相反,通过将上层的计算下推到数据产生的运算符中,由数据的最终生产者驱动上层运算符对数据进行消费。

推送模式的问题主要是:1)无法使前一步产生的数据由下一步过程直接复用;2)虚函数的调用,会影响CPU的流水线执行(因为分支预测可能会失效),从而影响效率。

3.3一致的查询执行

按照事务语义的要求,查询所依赖的更改,在查询执行之前,都需要在RAPID引擎中可用。因此,为了满足这一要求,就需要使用在内存日志中收集的事务日志。查询检查点,是扫描、编码并将所有更改从关联表的内存日志发送到RAPID引擎的活动。为了避免在查询时遇到长时间运行的查询检查点,一般可以利用定期的后台进程来扫描和传播日志中的数据更改。

:在当前的MySQL HeatWave设置中,将表加载进HeatWave之后,每隔200ms,或者是当数据更改量达到64MB的时候,就会自动触发后台进程,将这些更改传播到HeatWave节点上。

此外,如果查询的系统改变号(SCN)——一个单调递增的时间戳——不比它所操作的任何表的SCN小,则该查询就可以被RAPID引擎接受。因此,在提交查询时,查询的SCN将会与片段访问的表的SCN进行比较。

3.4网络与其他组件

RAPID依赖于MDS和OCI对象存储来实现持久性和故障恢复。如果RAPID节点出现故障,则恢复协议会调出备用的RAPID节点,并使用正确的数据集分区进行加载。在恢复期间,除非有副本,否则无法使用RAPID集群进行查询卸载。RAPID元数据中,包含了有关加载到RAPID中的基表、系统状态、表统计信息、分区信息,以及列的编码信息。RAPID节点通过高带宽的Infiniband网络进行连接。同时,在顶部实现了一个自定义网络层,从而允许调度动态适应工作负载的网络传输。


四数据与存储模型

4.1数据与存储

RAPID将整个数据存储在主内存当中,而可靠性和持久性则由MDS和OCI对象存储来保证。RAPID引擎中的表,由一个或者多个水平分区组成。每个分区都包含称之为块(chunk)的数据水平切片。块内的数据,是以列式布局存储的一组表中的行。存储在块中的表中的每一列,都称之为矢量。它是列数据的平面数组。RAPID DPU中的矢量大小的最佳值为16KB,因为这里启用了双缓冲,以及DMS传输和计算的overlap。最后,运算符进行数据传输的单位为tile,包含64+行数据。表的整体存储组织如下图3所示。

图3 RAPID中表的存储结构

4.2数据编码

DPU中有意识地缺少了对原生浮点运算的支持。此外,内存寻址有着严格的对齐规则,这就使得可变宽度列的存储变得复杂起来。因此,RAPID使用固定宽度编码来处理所有常见的数据类型。尤其是,广泛使用了十进制缩放二进制数值编码(Decimal Scaled Binary Number,DSB)和字典编码。

在十进制编码中,将会使用每个矢量的公共标量,该标量被选为最小值,以避免值中的小数点。然后使用公共标量将DSB值解码回原始的十进制数字。DSB编码通过避免浮点计算而显著提示了性能。但是,对于一些极端情况(例如,像1/3这样的值),则需要存储异常值并单独处理。对于固定长度和可变长度的字符串,使用字典编码。该字典允许更新操作,以及范围查找来评估前缀扫描和范围扫描。此外,还在每个列矢量上面应用了其他编码,以进行轻量级压缩(例如,运行长度编码)。

4.3更新

RAPID支持对已加载的表进行周期性更新。这是通过对表的每个更新单元(Update Unit,UU)进行跟踪来完成的。UU包含了一组已更改的行、SCN,以及过期SCN。在RAPID端,跟踪器模块负责在查询处理期间获取具有有效SCN的数据矢量。跟踪器使用索引来访问有效的UU及其最新版本。因此,就可以同时处理来自查询处理和更新作业的访问请求。随着时间的推移,累积的更新会导致大量的过期矢量占据内存,因此又引入了定期的系统范围垃圾回收作业。

4.4高效的数据加载

这里采用了一种高效的机制将数据加载进RAPID节点。加载操作,从MDS的LOAD命令开始。将会有多个扫描线程协同工作,直接从磁盘上收集和缓冲数据记录。同时,并行度也会被自动进行调整,从而实现最大的磁盘带宽。此外,直接读取磁盘,就可以避免对内存缓冲池造成污染。


相关推荐