Out of order database engine

文章讨论了无序数据库执行(OoODE)作为一种并行查询方法,它动态分解查询以充分利用执行期间的并行性,比串行执行和传统分区方法表现出更好的性能。作者通过实验验证了OoODE的效率提升,并将其与数据库设计原则和实际应用中的并行挑战进行了对比。
摘要由CSDN通过智能技术生成

1 阅读“Out of order database engine”相关材料,写出为何有这样的 database engine,谈谈自己的想法

查询内并行性是数据库软件为数据密集型查询提供可接受的响应能力的关键。许多研究人员已经研究了如何为数据库查询实现更大的执行并行性。分区是一种代表性方法,它将查询划分为多个子任务并并行执行它们。但是,给定一个新查询,最佳划分不一定是显而易见的。数据库软件利用启发式规则或统计信息来决定如何在执行之前划分查询。作为实现执行并行性的另一种方法,本文提出了无序数据库执行(OoODE),这是一种大规模并行查询执行方法,可一致地为数据库查询提供显着的加速。OoODE 通过充分利用在查询执行期间准备执行的每个操作的潜在执行并行性的确切知识来动态分解查询工作。使用OoODE,数据库软件可以自动挤出查询固有的执行并行性。因此,对于广泛的查询,OoODE的执行速度明显快于串行(非并行化)执行,同时它的性能优于或可与替代并行化方法相当,而无需在执行之前分割查询。本文介绍了我们使用原型数据库软件进行的实验,并证明OoODE比串行执行快两到三个数量级,而它比最佳分区情况快得多(高达2.07倍)。此外,OoODE的执行速度比主要的DBMS快两到四个数量级。

在文章中,作为实现数据库查询执行并行性的另一种方法,作者提出了无序数据库执行(OoODE),这是一种大规模并行执行方法,用于动态分解查询工作,方法是充分利用对查询执行期间准备执行的每个操作的潜在执行并行性的准确了解;数据库软件能够在 每次确定可以独立于其他任务执行任务时,查询工作的不相交部分的电荷。最终,查询被划分为要并行执行的大量任务,以便数据库软件可以自动挤出query固有的执行并行性。因此,如果底层基础架构足够强大,OoODE通过充分利用潜在的并行性来显着提高IO吞吐量并加快查询执行速度。文章介绍了 OoODE ,它可以通过动态分解关系查询工作并在运行时确切了解潜在的执行并行性来自动挤出查询固有的执行并行性。文章提出,对于广泛的查询,OoODE的执行速度明显快于串行执行,并且它的性能优于或可与替代并行化方法相当,而无需在提交或编译时分割查询。文章报告了性能实验,以证明OoODE比串行执行快两到三个数量级,而在串行执行方法中,它甚至比算法1执行数据库操作f(x,y)也快得多(高达2.07倍)。

用于执行数据库查询的设计原则可以大致分为两组,即在处理器和数据库存储之间交换的 IO,即全部提取和必要获取。全部提取原则扫描整个关系, 而不管关系中的每个元组对于给定的查询是否是必需的。一个典型的例子是哈希连接,它通常对要连接的两个关系执行线性扫描。对于每个元组,没有考虑必要性。因此,可能会产生过多的IO;但是,要请求的IO是微不足道的,因为人们可以知道,一旦查询到达,整个关系将被扫描。现有的查询并行化技术(例如并行哈希连接)利用这种特性,通过算法将 已知的线性扫描划分为一组多个扫描,以实现密集的并行性。该解决方案已被纳入现代DBMS,并形成了最近的并行编程框架(如MapReduce)的支柱。另一个组是必需的提取,它仅提取查询所需的元组。一个典型的示例是嵌套循环连接,它仅从要连接的关系中选取必要的元组。必要性决定是通过对每个元组的查询(例如连接条件谓词)和数据结构(例如 B+树索引)的组合做出的。

OoODE(无序数据库执行)是一个简化的统一执行公式,可始终如一地为各种数据库查询提供最佳实践中的 IO 并行性,其中“最佳实践”意味着在相同的物理环境和相同的数据集中优于或与现有查询执行技术相媲美。OoODE 的一个基本步骤是,每次该任务可分割时,都要划分查询任务。它的递归迭代最终会将给定的查询转换为执行代码,该代码利用查询固有的执行并行性。已划分任务的执行顺序是非确定性的。现有的并行化技术涉及密集的特定工作,例如算法优化和专家调整。OoODE消除了这种复杂性,为全部获取和获取提供了通用解决方案,以实现最佳的实践并行性并充分利用IO带宽。

越来越多的数据被容纳到数据库中,商业和科学应用程序正在大量使用这些数据。根据作者的经验,分析师通常通过启动线性扫描查询来获取可用数据的广泛概述,然后通过迭代和交互式地调用以临时重点查询来深入研究数据,直到得出结论。由于决策速度很重要,因此整个流程中的并行化是首要关注的问题。尽管有需求,但现代DBMS和并行编程框架完全致力于获取所有内容。引入 OoODE 是为了提供最佳实践中的数据库查询并行性。与现有的并行化技术相比, OoODE 在全部获取方面可能执行相对较快的速度,同时它实现了显著的性能改进,而对于提取是必需的,为此,IO 的复杂性阻碍了密集的查询并行化。

文章介绍了OoODE的一种算法,该算法在执行期间动态分解关系查询,方法是每次可以独立于其他任务执行可爱的任务时,为数据库操作生成一个任务。设f(x,y)为数据库操作,其中 f 是关系数据库运算符,如σ(选择)和 1(连接),x 和 y 是运算符的输入。 x和y可以是存储在数据库或其它数据库操作输出中的关系(元组集)。我们假设,如果 f 是一元的,则 x 是无效的(∅),只有 y 是有效的;否则,两者都是有效的。例如,σ(∅,x)是单关系选择查询,((x,y),z) 是三向联接查询。作为引入OoODE算法之前的准备工作,作者首先在算法1中提出了一种常规算法,用于基于串行执行方法执行数据库操作f(x,y),这是基本而直接的,但对于许多数据库软件来说仍然很受欢迎。为简单起见,只考虑加法数据库运算符 ,省略一些实现技术,如谓词下推。对于一元数据库运算符 f,数据库软件以迭代方式从y获取一个或多个元组并应用 f,直到计算y的所有元组。在读取元组时,如果y是存储在数据库中的关系,则数据库软件会向存储数据库的存储系统发出 IO 命令以提取元组。相反,如果 y 是另一个数据库操作的输出,则数据库软件将递归地调用该操作并以相同的方式获取其结果。对于二元运算符f,数据库软件以嵌套循环方式执行相同的步骤,它以迭代方式从 x 获取元组(在外部循环中),并且对于从 x 获取的每个元组,进一步迭代地从 y 获取元组并应用 f(在内部循环中)。

作者在算法 2 中介绍了 OoODE 算法。不同之处在于,OoODE使数据库软件能够在运行时将查询执行动态分解为许多任务,并并行执行它们。每当数据库软件需要从存储在数据库中的关系中获取新元组时,它都会为关系的每个部分(一个或多个元组)调用一个新任务,并将其相关工作委托给该任务;新任务从分配的部件中获取元组,然后执行数据库操作。决策步骤在内部检查元组获取的必要性;只有当决策是肯定的时,OoODE才会调用新任务并分配一部分未提取(尚未获取)元组。运行时数据结构信息有助于做出此决定。与串行执行相反,OoODE不会被元组获取阻止。相反,通过充分利用关于每个数据库运算符元组获取必要性的确切知识,OoODE动态调用一个新任务,其中另一个元组获取并行执行。最终,OoODE 将查询工作分解为大量并行任务,以便 OoODE 可以实现查询固有的潜在 IO 并行性。

假设底层基础结构足够强大以支持这种执行并行性,则执行时间可以大大缩短,因为并行执行的步骤的延迟不会串行加速。最近的硬件正在容纳更多的处理器内核和存储设备。鉴于进入中端数据密集型市场,最近的Linux服务器通常具有数十个处理内核,每个内核能够运行数十到数十个内核管理的线程,而许多最近的存储系统(如磁盘阵列和闪存阵列)具有数十到数百个存储设备,每个设备能够为数十个以上的并发IO命令提供服务。通过这种方式,今天的硬件技术具有支持高执行并行性的巨大潜在能力。在这种硬件技术的帮助下,OoODE似乎显着地加快了查询执行速度,并自动达到查询固有的查询执行并行性和底层基础架构支持的硬件执行并行性所确定的限制。

分区是并行化查询执行离子的代表性技术。它在编译时将给定的查询划分为多个子任务,然后并行执行它们; 每个子任务通常分配给具有 特定不相交属性的数据库部分。许多DBMS都采用了这种方法。OoODE 能够在每次生成新的独立任务时将查询工作动态分解为独立任务。因此, OoODE 可以充分利用查询固有的并行化机会,其性能优于分区或与分区相当。

原型可以大致分为两个组件,查询处理器和存储引擎。查询处理器在 OoODE 方法中执行给定的查询。OoODE调用了大量的并行任务,查询处理器需要管理每个任务的执行状态。有多种实现选项,但经过深入的探索,作者终于将两种线程机制结合使用;单个内核线程分配给每个处理器内核 ,并将许多用户线程分配给每个内核线程。单个任务的执行状态在与任务关联的用户线程中进行管理。在发出命令时,查询处理器会标记相关用户线程的标识符。当读取完成发出信号时,查询处理器将检查标识符并恢复用户线程,以对提取的数据执行关联的数据库操作。两种线程机制的结合在今天的多核架构中非常有效。首先,内核线程对于在多个处理器内核之间传播代码是必需的,但是线程间上下文切换成本高昂,因为每个切换都会施加内核交互。仅将单个内核线程绑定到每个处理器内核并在每个内核线程中放置多个用户线程有利于利用所有可用内核,同时减少上下文切换开销。其次,最近的处理器采用NUMA架构,其中远程内存访问成本高昂。组合策略允许数据库软件在每个处理器内核的本地内存中显式存储执行状态,从而有助于最大限度地减少远程内存访问。

作者的原型基本上采用了元组/入门级查询分解这种策略来充分利用并行化的机会。但是,某个数据库运算符(例如线性扫描运算符)尝试以笨重的方式获取存储在相同页面中的多元组。对于此类操作,为每个元组调用独立任务看起来不是一个好的解决方案。存储引擎管理来自/到存储数据库的存储系统的 IO。为了有效地操作许多并发 IO,作者选择利用异步 IO 机制,存储引擎发出异步 IO 请求,并在完成后通知查询处理器,以恢复相关任务和提取的数据。

2 阅读“论骑车穿越美国与实现Postgres的相通之处”相关材料,谈谈自己的想法

迈克尔·斯通布雷克是美国工程院院士,2014 ACM图灵奖的获得者,美国麻省理工学院教授。他的主要研究方向为数据库研究和开发。在文章中,迈克尔·斯通布雷克讲述了两个故事,一个是他和他夫人在 1988 年夏天骑车穿越美国的旅行;另一个是从1984年到1995年,Postgres的商业版 Illustra的设计、实现、商业化以及最后被收购的故事。

1988年,迈克尔·斯通布雷克和他的夫人骑双人自行车从华盛顿州出发前往波士顿,他们没有长时间骑行和骑车爬山的经验,也有着双人车骑行和照顾女儿的困难,但他们并没有被未来的迷茫和困难打倒,他们出发了。他们在华盛顿州的温思罗普翻越了第一座高山,过程很艰难,但作者非常乐观,因为这证明了他们有能力翻过其他高山。在克服了第一个困难后,作者抵达了蒙大拿州的边境,从这到芝加哥的道路一马平川。天公不作美,当他们到达了蒙大拿州东侧的北达科他州时,夏日的美国刮起了狂风,作者吃力地迎风前行。幸运的是,作者的朋友闻讯后前来援手,他决定陪作者骑行一周,他们一起团结协作克服了种种困难,终于离开了北达科他州。在第38天的时候,他们穿越了威斯康星州,抵达了密歇根州的拉丁顿。他们距离波士顿只有不到 1000 英里了,上中西部已经在背后,这是胜利的曙光。但是好景不长。在骑行第 49 天的时候,他们到达了位于纽约州和宾夕法尼亚州交界处的埃利科特维尔。那天很不幸,他们出发时在酒店的大理石地面上骑车滑倒,作者的膝盖磕破了。雪上加霜的是,他们在接下来的路途中又遇到了一座高山,一路上的起起伏伏对于作者的膝盖而言是莫大的折磨。在第 56 天的时候,他们抵达了马萨诸塞州的边境,他们绕过了那座连绵起伏的大山,横在他们面前的是抵达目的地前的最后一座山,再往后的路都十分好走。在第 59 天的时候,他们抵达了波士顿,他们把双人车骑行到大西洋边的海滩来结束我们的旅程。作者的路途充满了曲折,但他没有放弃,坚持骑行穿越了美国,这真是个让人激动又感动的故事。

对于作者而言,骑车穿越美国与实现Postgres是有着相通之处的。当被问到为什么要讲关于自行车骑行的故事呢?作者乐观地用一个泛化的骑行穿越美国的算法伪代码来证明他是会写代码的。作者曾花了 5年的时间获得博士学位,这是一个“动手实现”的过程,因为要写一篇能让导师签字通过的毕业论文并不容易,他甚至在博士资格考试中失败过一次。之后他在加州大学伯克利分校做助理教授,花了 5年时间获得终身教职,也是“动手实现”的过程。另外,花两个月的时间骑车穿越美国也是“动手实现”的过程。骑行故事是设计实现大型软件系统的一个隐喻。要设计实现 Postgres 系统,首先需要有几个好主意,然后花费5年时间实现一个原型系统,这是一个“动手实现”的过程。在这期间别忘了,什么时候扔掉所有代码重新来过都不晚。在这之后就可以创立一家公司,雇用一些绝顶聪明的人,完成构思的产品,这也是一个“动手实现”的过程。这期间就像在一个长长的沼泽里爬行一样。简而言之,设计实现 Postgres 只需要一个好主意并“动手实现”。可是这花费了作者10年的时间,期间起起落落,甚至比获得终身教职还难。有人可能会问既然如此之难,那为什么还要设计实现 Postgres呢?这和骑行穿越美国是一样的,那是作者要做的(That’s what I do)。

在文章中,作者先详细介绍了Postgres 的设计蓝图。1984年,商业化的Ingres已经 4 岁了,继续在学院版的Ingres上实现作者的一些想法和原型系统已经不现实了,因为它很难比得过商业版的 Ingres。于是,作者决定抛弃所有的 Ingres 代码,重新设计并实现一个新的数据库系统 Postgres。亦如他决定放下一切骑行横穿美国一样,作者决定开发支持抽象数据类型的数据库系统。为了支持抽象数据类型,需要新的索引结构来索引新的数据类型。1981 年,克里斯·戴特 (Chris Date) 提出了完整性约束。完整性约束主要是处理主键约束和外键约束的。在作者看来,任何一个新的数据库系统都必须实现外键约束,当然也包括 Postgres。作者的想法是实现一个统一的规则系统,它能处理几乎所有的规则。作者提出的解决方案是在命令中增加一个“always”关键字来处理这些规则。在更新操作中附上“always”关键字将会保证后面的条件一直成立。思考出来一个难题,亦如骑行翻越高山,山后是一望无际的平原。Postgres 的第三个计划是无重写存储。20世纪70年代,大家都认识到了处理宕机恢复的重要性。为了确保用户绝对不会丢失他们的数据,我们必须非常认真地对待宕机恢复的问题。在当时,所有人采取的方式都是分开存储数据和日志。每次做更新操作的时候,需要把数据更新前和更新后的样子都写入到日志里。所以有两个数据存储地点,其中一个用来管理数据,另外一个用来管理日志。作者提出统一存储日志和数据,并且在更新操作的时候,不覆盖当前的数据,作者做的仅仅是插入一条更新后的数据,并加上时间戳,这样就可以绕过宕机恢复,而且还能顺便实现“时间旅行”的功能。

理想是远大的,然而现实是残酷的。先是由于编程语言的开发不成熟,作者浪费了大量的时间和精力。接着又因为客户的需求和先前设计的不足,作者抛弃了大量的代码,重新实现了传统的规则系统。1987 年到 1990 年的三年时间里,作者的进展非常缓慢,做了很多修修补补的工作。这一段时间就像是在泥潭和沼泽里艰难地爬行。1993 年,在几次错误的尝试之后,作者最终把自己建立的新公司命名为 Illustra。作者的朋友出任临时首席执行官,他们当时的计划是把查询语言从 QUEL 转化为当时的标准查询语言 SQL,优化代码以及提升性能。他们成功地吸引了几个初始用户并融到了更多资金。最重要的是,他们雇用了一个真正的管理团队,包括首席执行官、主管市场的副总裁以及主管销售的副总裁,公司走上了正轨。一个初创企业从零开始融资,每一轮都有个估值,风险投资商会以一定的价格获得这个企业的一些股票。当初创企业的钱用光后需要再进行一轮融资,这时企业的估值通常会更高,股票的价格也会更高。但是如果新的一轮融资的估值变低了,这轮融资就叫做贬值融资。作者就经历了一轮贬值融资,这是比企业破产更糟糕的事情。1995 年,奇迹突然出现。互联网蓬勃发展,网络公司受到大家的热烈追捧。此时,作者的产品不再仅仅是一个拥有扩展数据类型的数据库,而是一个真正意义上的互联网数据库,可以存储互联网上所有类型的东西,例如文本、图像和音频。然而此时数据库系统出现了处理事务性能不良的问题。1996 年 2 月,奇迹再次突然出现了。作者的一个竞争对手同时也是一家大公司,提出要收购 Illustra。这直接解决了作者前面的两个问题,首先解决了作者的一些客户需要大型应用商的第三方库的问题,因为大型应用商很乐意和这家用户量巨大的大公司合作。其因为大型应用商很乐意和这家用户量巨大的大公司次,这家大公司有非常高效的事务处理引擎,这解决了作者的产品事务处理的性能问题。被收购之后,作者成功地把 Illustra 的很多特性移植到了这家大公司的系统中。

骑车穿越美国与设计和实现 Postgres 有什么相通之处呢?第一,动手实现 ;第二,有突然出现的奇迹。我想,这突然出现的奇迹,与其说是运气,更不如说是实力的沉淀;无论是朋友的雪中送炭还是大公司的合作收购,都离不开迈克尔·斯通布雷克长年累月的奋斗和坚持。这需要面对困难永不言弃的决心和信念,更需要永不言败的乐观主义精神。正如作者不断翻越高山的勇气和执着,他克服了一个又一个的困难,设计出了一款性能优良的数据库系统,实现了自己的人生价值,到达了大西洋边的海岸。

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值