查询引擎和存储引擎不一样(但RDBMS不存在这种区别,由于存储引擎是专有的,并由查询引擎的同一供应商提供。MySQL是个例外,它能链接到各类存储引擎)。算法
假设使用查询引擎时,SQL是主要的API(也有其余API支持其余数据模型。您能够将其中某些API映射到SQL,您也能够扩展SQL以支持没法容易映射的API),在该假设前提下,查询引擎必须作到如下几点:数据库
同时,存储引擎必须至少具有如下能力:缓存
它还能够具有如下能力:安全
部分功能能够在存储引擎中,能够在查询引擎中,也能够共享在这两个引擎中。例如,查询和存储引擎须要协做,以提供高并发性和一致性。服务器
以上列表仅列出部分信息,它们仅说明了查询和存储引擎之间协做的复杂性。数据结构
如今,咱们已定义了不一样类型的工做负载、不一样角色的查询引擎和存储引擎。在本报告中,咱们将深度分析构建一个支持全部工做负载和众多数据模型的系统所面临的挑战。架构
查询引擎很难支持单一操做、BI或分析工做负载(事实证实,不一样的专有平台会相互支持)。可是,对于一个服务于全部工做负载的查询引擎来讲,它必须知足比过去更多的需求。因此,咱们正在接触一个充满障碍的新领域,让咱们探讨其中的一些挑战。并发
要处理这些不一样类型的工做负载,查询引擎必须首先肯定它正在处理哪一种类型的工做负载。假设它是单行访问,若是结构中没有用来减小扫描的键入访问或机制,单行访问可能意味着对一个庞大表格中的全部行进行扫描。查询引擎须要了解该表的键结构,以评估提供的谓词是否涵盖整个键或只是一部分键。若是谓词包含整个惟一的键,那么查询引擎将会了解这是一个单行访问,支持直接键入访问的存储引擎便能迅速地对它进行检索。dom
人们在谈论“分片”(sharding)时,经常将其等同于“分区”(partitioning)。分片是基于某种逻辑实体(例如,区域和客户ID等等)对跨多个集群的数据进行分离。一般,该分离和其机制由应用程序进行指定。若是要跨分片访问数据,在查询引擎层面之上还须要具备联邦功能。
分区是在集群中利用多个文件对数据进行分布,以平衡分配跨磁盘或节点的大量数据,实现对数据的并行访问以减小查询的总执行时间。每一个磁盘能够有多个分区,并经过对表的键列指定散列、范围或二者结合来管理数据的分离。大多数查询和存储引擎支持此功能,对应用程序相对透明。
任什么时候候都不该该将分片等同于分区。从规模、性能和操做可管理性的角度来看,分区替代分片的成本很高。事实上,您能够认为分片和分区在解决应用程序的扩展性时相互补充。如何使用分片和分区是一种应用程序架构和设计决策。
应用程序须要具有分片功能。对跨服务器或集群的数据进行分片能提升扩展性,某些查询引擎可能会为此提供便利。可是,在处理分区数据时,跨分片扩展并行查询比跨MPP集群使用单个并行查询引擎更局限和低效。
若是每一个分片具备大量能够跨越大型集群的数据,那么使用分区并对该分片执行并行查询是一种不错的方法。然而,跨分片对数据进行传递、从新分区和传播以实现数据链接却很是复杂和低效。但若是跨分片链接数据查询是不合理的,或跨分片处理较为罕见,此时建议跨集群分片。本报告着重讨论分区。
查询引擎尝试使用其余查询引擎时会遇到不少相同挑战,例如,Postrgre SQL或Derby SQL。在这种状况下,查询引擎从本质上变成了一个跨分片的数据联合引擎(本报告后面部分将对此进行讨论)。>
当查询引擎尝试生成查询计划、或了解一个工做负载是运营型或分析型时,统计必不可少。在前面讨论的单行访问状况下,若是在查询中使用的谓词仅包含某些键列,那么引擎必须肯定谓词是否包含前导键列或主键列。假设在前导键列上指定了等式谓词,那么查询引擎须要了解有多少合格行,它须要访问的数据分布在节点上的状况。基于此分区方案——即数据如何分布在节点和这些节点内的磁盘上,查询引擎须要断定它是否应该生成一个串行计划或并行计划,或者是否能依赖存储引擎作出高效断定,并访问和检索正确的行数。为此,查询引擎须要了解符合条件的行数。异步
查询引擎想要了解合格的行数以生成有效的查询计划,惟一的方法是提早收集有关数据的统计信息以肯定合格数据的基数。若是涉及多个键列,则极可能这些键列的组合基数比它们各自基数的乘积小得多。所以,查询引擎必须对键列有多列统计信息。能够收集各类统计数据,但至少须要了解惟一的记录数、列的最低值和最高值,或第二最低值和第二最高值。
倾斜是另外一个须要考虑的因素。当数据分布在大量节点上,可能出现大量数据最终只被少数几个节点处理的状况,这些少数节点击败了其余大多数节点,影响了集群上运行的全部工做负载(假设大多数须要这些节点来运行),而其余节点须要等待这些少数节点执行完查询,在此种状况下便产生了倾斜。若是查询引擎须处理的惟一类型的工做负载是OLTP或运营工做负载,则不须要处理大量数据,所以也无需担忧数据倾斜。除了数据分区层,还可经过选择较佳的分区键来控制数据倾斜。但若是查询引擎同时处理BI和分析工做负载,倾斜可能成为一个重要的要素。倾斜还取决于用于执行查询的并行计划的数量。
在数据倾斜存在的状况下,数据库没法彻底依赖于传统的、大部分数据库系统所采用的等宽直方图。在等宽直方图中,基于所找到的最低值和最高值以及计算出的惟一记录数,根据数值范围,收集的统计数值被划分为相等区间。然而,若是发生倾斜,就很难了解哪一个值有倾斜,由于它会落在某个特定区间里,而在该区间范围中存在许多其余数值。所以,查询引擎必须收集更多信息以了解倾斜或使用等高直方图。
等高直方图在每一个区间中有相同的行数。所以,若是存在倾斜值,那么它可能跨越更大数量的区间。固然,肯定正确的区间高度和由此产生的区间数、调整并突出显示倾斜值与非倾斜值(全部区间可能有不一样尺寸),同时在不丢失倾斜信息的状况下最小化区间数,这很难作到。实际上,计算这些直方图更加困难,并会带来不少操做挑战。一般状况下,抽样能快速收集这些统计数据,由于必须对数据进行分类以将它们放入这些区间中。因此,应制定相应策略以逐步更新这些统计信息和肯定更新信息的频率。这些都是来自于它们自身的挑战。
当谓词不在前导键列而在某些键列上时,事情将变得很是棘手。若是遇到IN或NOT IN谓词,状况将会变得更加复杂。当前导键列值未知时,多维度访问方法(MDAM,Multidimensional Access Method)可提供高效访问。在这种状况下,须要了解不带谓词的前导键列的多列基数,以判断用这种方法访问数据是否比全表扫描更快。若是有不带谓词的中间键列,则它们的基数也是必不可少的。因此,除了那些能够按键值等有效索引进行的查询,例如,运营型的查询以外,则必须考虑多键列。
非键列中存在谓词。这些键列的基数也是很重要的,由于它为减小查询上层需处理(例如,链接和聚合)的行数大小提供了一个方案可能。
上述全部键入和非键入访问基数都有助于肯定数据链接策略和并行度。
若是存储引擎是一个列存储引擎,那么其使用的压缩方式(字典、运行长度等)会影响扫描的性能。在这种状况下,因为想尽快减小更多行数,谓词的评估顺序是很重要的,因此,应首先从能够达到最大简化的列的谓词开始。此处,汇集访问、全表扫描或减小对列值扫描的有效机制相当重要。
接下来讨论索引。存储引擎支持哪些类型的索引,或者哪些索引是由存储引擎顶部的查询引擎建立?索引为数据访问提供了更高效的备用访问路径。有一类索引仅为索引扫描而设计,经过涵盖查询中须要返回的全部相关列从而避免访问基表。
如今咱们来看物化视图。物化视图对于复杂的工做负载十分有用,能够经过对数据的预链接和聚合来提升访问效率。物化视图的实现很是复杂,系统须要断定给定查询是否能够利用现有的物化视图,这被称为物化视图查询重写。
有些数据库对索引和物化视图使用不一样的名称,例如投影(projection),但最终目的都是为了判断有哪些可用的备用访问路径,以实现有效的键入访问或聚合访问,从而避免大型全表扫描。
固然,一旦添加索引,数据库就须要保持它们的同步。不然,总响应时间将随其在更新时必须维护的索引数的增长而增长。数据库系统必须为索引提供事务支持,以保持与基表一致。可能还需考虑其余因素,例如,索引与基表的位置相关性。数据库必须处理惟一约束。一个典型的例子是在BI和分析环境中(以及一些其余场景),数据的批量加载须要一个有效机制来更新索引,并确保它的一致性。
索引更多用于运营工做负载,不多用于BI和分析工做负载。另外一方面,物化视图主要用于BI和分析工做负载,它是在基表中对数据的物化链接和/或聚合,相似于提供快速访问的索引。在当今商业环境中,客户对支持运营仪表板的业务需求的增长可能会改变这些传统观点。若是物化视图的维护须要与更新同步,则可能会大大加剧更新或批量加载的负担。假设可使用审计日志或版本控制来更新物化视图,即物化视图采用异步方式维护,则影响不会很严重。一些数据库支持用户定义的物化视图,为用户带来更高的灵活性,而且不会给运营更新形成负担。查询引擎应尽量自动重写查询,以充分利用物化视图。
存储引擎还使用其余技术(例如,布隆过滤器和哈希表)来加速访问。查询引擎须要了解存储引擎全部可用的备用访问路径以获取数据。查询引擎还需了解如何利用或执行自身的功能,以便为运营和分析工做负载提供高性能。
到此,咱们已了解如何扫描一个特定的表,能大概估计存储引擎完成扫描后返回的行,也明白了数据如何跨分区传输。如今,咱们能够同时考虑串行和并行执行策略,并对并行策略可能的更快响应时间和并行的开销进行平衡。
是的,并行也存在开销。您须要在多个节点上分配更多进程,每一个进程都占用内存,在其节点中竞争资源,并且该节点可能会出现故障。您还必须为每一个进程提供执行计划,全部进程必须作一些设置以完成执行。最后,每一个进程必须将结果发送到单个节点,这个节点整理全部数据。
全部这些结果将可能会致使进程之间有更多信息传递,增长数据倾斜的可能性等。
在给定上述开销的状况下,优化器须要经过使用多个潜在的串行和并行计划来计算处理这些行的成本,并评估哪些是最有效的。
若是要为全部工做负载(包括在秒级或亚秒级时间内执行大量并行查询的EDW工做负载)提供很是高的并发性,优化器须要对每一个查询所需的并行度进行评估。为了在最短响应时间内最高效地利用资源来执行查询,查询引擎应将须要处理的行的基数做为每一个操做并行度的依据。一般状况下,扫描经过筛选行、链接和聚合能大量减小数据。例如,若是用5个节点能达成目标,那么就没有必要用100个节点。不只如此,经过处理数据的基数,您能获得查询所需的最大并行度,即查询会被分配到集群中的分段,或集群中的节点子集。若是集群被分红多个相等的分段,为了高效地使用集群,能够将查询分配给这些分段或分段集合,以大幅增长并发。这不只能提升使用系统资源的效率,还能经过减小并行度来获取更高的弹性。如图1-2所示。
图1-2 基于查询所需的并行度的节点。每条垂直线表明一个节点(共计128个节点),每一个色带是32个节点组成的分段。恰当分配查询能够增长并发、效率和弹性,同时下降并行度。
随着集群扩展和更新的技术用于新节点,新节点比集群上现有节点可能拥有更大的资源容量,分配更多查询给新分段能更高效地使用容量。
迄今讨论的选项为优化器提供了大量潜在的良好查询计划。目前,有各类各样的技术,例如,NonStop SQL(如今是Apache Trafodion的一部分)和Microsoft SQL Server使用的Cascades算法,它是很好的优化器,但缺点是查询计划的搜索空间过大以致于难以计算出结果。对于长时间运行的查询而言,经过扩大搜索空间、并花费更多时间来寻找更优计划能够得到巨大回报。但对于运营查询而言,寻找更优计划的回报减小地很是快,用于寻找更优计划的编译时间成了一道难题,由于大多数操做查询须要在几秒甚至在亚秒内完成。
解决运营查询编译时间问题的一种方法是提供查询计划缓存。查询缓存的命中策略不只仅是使用简单的字符串匹配方式,更复杂的作法是实现排除查询语句中的常量和变参,但这仍是不够的。自上次执行计划生成后,表定义可能发生变化。在这种状况下,须要使缓存计划失效。表的schema可能更改,但在查询文本中没有不一样。处理数据倾斜查询计划与处理无数据倾斜查询计划有显著不一样。所以,须要复杂查询计划缓存机制来减小编译时间,同时避免陈旧或低效的计划。查询计划缓存须要主动管理,须要从缓存中删除最近最少使用的计划,保留常用的计划。
优化器能够是基于成本的优化器,但必须是有规则驱动的。经过添加经验和规则,优化器获得升级,从而能很是高效地和轻松地处理不一样工做负载。例如,它能识别模式。星型链接不可能出如今运营查询中,但对于BI查询,它能检测出此类链接。所以,它能使用为该目的设计的专用索引,或者它能决定作维度表的交叉乘积(优化器会避免),再对事实表进行嵌套链接,而不是扫描整个事实表并对维度表执行重复的哈希链接。
上面的讨论为咱们引出了链接类型的问题。对于运营工做负载而言,数据库须要支持嵌套链接并为嵌套链接创建缓存。对于嵌套链接而言,外表的非排序属性每每会致使对内表的访问会出现重复,在这种状况下,在内存中为内表创建缓存将有助于提升链接性能。
对于BI和分析工做负载而言,合并或混合哈希链接可能更有效。有时嵌套链接对于此类工做负载可能有用,然而,随着将要链接的数据量的增加,嵌套链接性能将会急速降低。
因为错误的选择会对查询性能产生严重影响,所以您须要对成本增长必定的权重,而不是仅仅根据成本选择计划。即尽管存在一个比哈希链接成本稍低的嵌套链接,优化器也不会选择它,由于它更多是一个错误的执行计划,并且基数评估也只是评估,并不精确。若是选择了嵌套链接或串行计划,并且运行时符合条件的行数等于或低于编译时估计,那么这是一个优质计划。反之,则嵌套链接或串行计划就变得不是仅仅有点儿糟糕,而多是毁灭性的。因此,预估嵌套链接和非并行计划时应增长成本权重,使哈希链接和并行计划更受青睐,以免生成糟糕执行计划的风险。因为不一样工做负载对成本有不一样要求,您能够调整成本权重,尤为是在考虑运营查询和BI或分析查询之间的平衡时。
对于BI和分析查询而言,若是哈希链接或排序处理的数据很大,检测内存压力和恰当溢出到磁盘就很重要。固然,运营型查询一般不须要处理大量数据,所以,对运营型查询而言,不会面临这样的问题。
查询引擎的架构须要能处理具备BI和分析工做负载的复杂操做的大型并行数据流,以及快速直接访问运营工做负载。
对于可能处理大量数据的BI和分析查询,查询执行架构应该能在多个级别并行。第一级是分区并行性,它使操做的多个进程并行处理,例如,链接和汇集。第二级是运算符级别或运算符并行性,即扫描、多个链接、聚合以及执行查询的其余操做能并发运行。在同一时间内,查询不该仅仅执行一个操做,或许应像MapReduce同样将磁盘上的中间结果进行物化。
全部进程的执行都应该与数据流从扫描到链接、再到其余链接和聚合的操做同时执行。这带来了第三种并行,即管道并行性。在查询计划中容许一个运算符(例如,一个链接)使用由另外一个运算符(例如,另外一个链接或扫描)生成的行,一组上下进程间消息队列,或进程内的内存队列,用于保持这些运算符之间的数据流的一致(见图1-3)。
图1-3描述了优化器如何根据行基数,预估每一个运算符在执行某一步骤时所需的并行度。这能够表现为并行度为二的扫描,另外一个扫描和并行度为三的GROUP BY,以及并行度为四的链接。正确的并行度能被执行查询的每一个运算符使用。这比每一个操做都使用整个集群的设计更高效。本文第13页的“并行度”部分也对此进行了讨论,并介绍了肯定整个查询并行度所需的信息,见图1-2。>
图1-3 利用不一样层次的并行度
但对于OLTP和运营查询,该数据流架构(图1-4)会来带巨大开销。若是您正在访问单独一行或几行,则不须要队列和复杂数据流。在这种状况下,您能够进行优化以减小路径长度,快速访问和返回相关行。
图1-4 数据流架构
当您使用快速路径优化OLTP查询时,对于BI和分析查询而言,您须要考虑预取数据块,前提是存储引擎支持该功能,而查询引擎正忙于处理前一个数据块。所以,查询引擎处理不一样类型的工做负载(处理的本质截然不同),它还须知足不一样工做负载的需求。
图1-5至1-8解释了处理不一样情景的不一样方法:能够是从单行或单个分区访问串行计划、复杂并行访问、或BI和分析查询多层次的并行处理,以帮助完成复杂的聚合和链接。
图1-5 汇集在键列的单行或一组行的读取和写入的串联计划。例如,为客户插入、删除或更新某一单行,或访问某一特定交易日期的全部数据,这些数据都驻留在同一分区。
图1-6 串行或并行计划,基于成本计算,其中主进程跨区直接访问多个分区的行。这种状况发生在主进程将要处理少许几行或者并行聚合/链接不是必需或没有帮助时。例如,须要访问的客户数据基于交易日期分布在多个分区。
图1-8 在并行计划中,大量数据须要处理,多个链接或链接都须要从新分区和广播数据。
HTAP面临的最大挑战之一是处理混合工做负载,即在同一个集群、节点、磁盘和表中同时运行OLTP查询、BI和分析查询。查询引擎的工做负载管理功能根据数据源、用户、角色等对查询进行分类,容许用户对工做负载区分优先级、并为某些工做负载分配比其余工做负载更多的CPU、内存和I / O资源。或者,能够优先处理较小的OLTP工做负载,再处理BI和分析工做负载。根据不一样查询的需求,进行不一样的资源配置。
可是,还须要优化存储引擎。存储引擎应自动下降耗时较长查询的优先级,并在执行高优先级查询时,暂停执行其余查询,待高优先级查询处理完后,再返回处理耗时较长的查询,这被称为防止饥饿机制。由于当单个查询要占用全部资源时,您不但愿因处理相同优先级或低优先级的查询而不能知足高优先级的查询。解决此问题的另外一种方法多是,在存储引擎能保证一致性的状况下,将特定行的更新操做路由到主分区,而将查询操做路由到复制集群。
愈来愈多的应用须要源源不断地处理实时数据流,对这些数据进行转换和汇总,并触发相应的操做,一般根据行数或时间窗口处理时间序列数据。这与处理保存在磁盘或内存的表格数据所使用的统计性或用户自定义函数、复杂运算、聚合、甚至OLAP窗口函数有很大不一样。虽然Jennifer Widom在2008年提出了新的SQL语法来处理流式数据,但目前尚没有标准的SQL语法来处理流数据。查询引擎必须能处理这种新的数据处理范型。
最后,您须要为运营和分析工做负载提供支持的功能列表。运营工做负载这些的功能包括参照完整性、存储过程、触发器;各类级别的事务隔离和一致性;物化视图;快速/批量提取、转换和加载(ETL)功能;以及OLAP,时间序列、统计、数据挖掘等功能,以及为BI和分析工做负载服务的其余功能。
这两种类型的工做负载有不少共有功能。查询引擎须要支持的一些功能是标量和表映射用户定义函数(TMUDF),内、左、右、全外链接; 子查询优化(例如,将嵌套子查询扁平化、将相关子查询转成链接)、谓词下推、排序回避策略、常量折叠和递归联合等(本文不一一列举)。
为不一样工做负载提供全部这些功能,须要巨大的资源投入。
关于做者
Rohit Jain是Esgyn的联合创始人和首席技术官。Esgyn是一家开源数据库公司,致力于构建融合型分布式大数据平台。2015年,惠普将Apache Trafodion(企业级大数据MPP SQL数据库)捐赠给了Apache软件基金会。在Apache Trafodion的基础上,EsygnDB的愿景是创建一个能处理任何数据、任何大小和任何工做负载的融合型分布式大数据平台。在过去的28年中,做为一个资深数据库专家,Rohit在应用程序和数据库开发领域曾为Tandem、Compaq和Hewlett-Packard工做过。他经验丰富,主要涉及在线事务处理、运营数据存储、数据集市、企业数据仓库、BI和大规模分布式并行系统的高级分析。