掌桥专利:专业的专利平台
掌桥专利
首页

日志结构合并森林中的交错合并

文献发布时间:2023-06-19 09:33:52


日志结构合并森林中的交错合并

相关申请的交叉引用

本申请根据PCT第8条要求于2018年9月14日提交的标题为“Staggered Mergingin Log-Structured Merge Forests(日志结构合并森林中的交错合并)”的美国临时专利申请No.62/731,630的优先权,其通过引用整体合并于此。

技术领域

可以在数据库中维护和索引数据。某些大型索引数据库可以实现大插入体积。数据库可以处理查询以在该数据库搜索一个或多个条目。

发明内容

本公开的至少一个方面涉及一种维护键值存储的方法。该方法能够包括由具有一个或多个处理器的数据处理系统在第一缓冲器上建立用于对第一多个记录进行排序的第一游程。第一多个记录能够由第一对应的多个索引值最初索引。第一多个记录中的每个记录能够具有键域中的第一键值。键域能够定义多个键值。该方法能够包括由数据处理系统使用合并索引来跟踪第一游程的第一多个记录到数据库上维护的合并级别上的合并。合并索引能够引用在合并期间添加到合并级别的第一多个记录中的记录的第一键值。该方法能够包括由数据处理系统与第一多个记录的合并并发地在第二缓冲器上建立用于对第二多个记录进行排序的第二游程。第二多个记录能够由与第一多个索引值不同的第二对应的多个索引值来索引。第二多个记录中的每个记录能够具有键域中的第二键值。该方法能够包括由数据处理系统确定跟踪第一多个记录到合并级别上的合并的合并索引满足分位点条件。分位点条件能够对应于键域中的多个键值中的至少一个。该方法能够包括由数据处理系统响应于确定合并索引对应于分位点条件而从第二缓冲器中标识第二游程的第二多个记录的子集。子集的每个记录能够具有满足分位点条件的所对应的第二键值。该方法能够包括由数据处理系统将第二游程的第二多个记录的子集添加到第一游程的第一多个记录到数据库上维护的合并级别上的合并。

在一些实现方式中,该方法能够包括由数据处理系统基于合并索引和由分位点条件指定的分位点索引的比值来确定转接键值。在一些实现方式中,该方法可以进一步包括由数据处理系统基于数据库的合并带宽确定带宽偏移。合并带宽能够指示数据库正在添加第一多个记录并且第二多个记录的子集被合并的速率。在一些实现方式中,确定合并索引满足分位点条件能够包括确定合并索引满足由带宽偏移调整的转接键值。

在一些实现方式中,该方法能够包括由数据处理系统使用游程索引来跟踪使用第二多个记录建立第二游程。游程索引能够引用在第二游程中排序的第二多个记录的数目。在一些实现方式中,该方法能够包括由数据处理系统确定由游程索引引用的第二多个记录中的记录的第二键值满足分位点条件。在一些实现方式中,添加第二多个记录的子集能够包括与建立第二游程并发地并响应于确定由游程索引引用的记录的第二键值满足分位点条件而发起将第二游程的第二多个记录的子集添加到合并。

在一些实现方式中,该方法能够进一步包括由数据处理系统标识在第一缓冲器上建立第一游程的第一游程生成速率。第一游程生成速率能够指示在第一游程中对第一多个记录中的记录进行排序的速度。在一些实现方式中,该方法能够包括由数据处理系统标识在第二缓冲器上建立第二游程的第二游程生成速率。第二游程生成速率能够指示在第二游程中对第二多个记录中的记录进行排序的速度。在一些实现方式中,该方法能够包括由数据处理系统基于第一游程生成速率和第二游程生成速率中的至少一个来设定用于将第一游程的第一多个记录添加到数据库上的合并带宽。

在一些实现方式中,该方法可以进一步包括由数据处理系统针对第一多个记录标识对应的多个第一键值在键域上的分布。在一些实现方式中,该方法可以进一步包括由数据处理系统基于所对应的多个第一键值在键域上的分布来确定包括分位点条件的多个分位点条件。

在一些实现方式中,该方法能够包括由数据处理系统在合并级别上合并第二多个记录的子集和第一多个记录的同时,确定第一游程的第一多个记录的全部都被添加到数据库上的合并级别。在一些实现方式中,该方法能够包括由数据处理系统响应于确定第一游程的第一多个记录的全部都被添加,从第一多个记录释放第一缓冲器以为第三游程接收第三多个记录。在一些实现方式中,该方法能够包括由数据处理系统与将第二多个记录的子集合并到数据库上的合并级别上并发地在第二缓冲器上维护第二多个记录。

在一些实现方式中,该方法能够包括由数据处理系统确定第二多个记录的子集和第一多个记录到数据库上的合并级别上的合并完成。在一些实现方式中,该方法能够包括由数据处理系统响应于确定到合并级别上的合并完成而初始化数据库上的第二合并级别以接收第二游程的第二多个记录的至少剩余子集的合并。

在一些实现方式中,该方法能够包括由数据处理系统接收对定义键域的多个键值中的至少一个的查询。在一些实现方式中,该方法能够包括由数据处理系统使用查询来搜索数据库上的合并级别,该合并级别包括来自多个游程的记录。

在一些实现方式中,合并第二多个记录的子集进一步包括使用第二合并索引来跟踪第二多个记录的子集到数据库上的合并级别上的合并。第二合并索引能够引用在合并期间添加到合并级别的第二多个记录中的一个的第二键值。第二合并索引能够基于分位点条件最初设定。

在该方法的一些实施方式中,建立第一游程能够包括使用快速排序或优先级队列中的至少一个在键域上按对应的多个第一键值对第一多个记录进行排序。第一多个记录能够通过第一对应的多个索引值来最初排列。在该方法的此类实现方式中,建立第二游程能够包括经由输入数据流从数据获取源接收第二多个记录以存储在第二缓冲器上。能够通过第二对应的多个索引值并且使用快速排序或优先级队列中的至少一个在键域上按对应的多个第二键值对第二多个记录进行排序来最初排列第二多个记录。

本公开的至少一个其他方面涉及一种用于维护键值存储的系统,包括具有一个或多个处理器的数据处理系统。数据处理系统能够在第一缓冲器上建立用于对第一多个记录进行排序的第一游程。第一多个记录能够由第一对应的多个索引值最初索引。第一多个记录中的每个记录能够具有键域中的第一键值。键域能够定义多个键值。数据处理系统能够使用合并索引来跟踪第一游程的第一多个记录到数据库上维护的合并级别上的合并。合并索引引用在合并期间添加到合并级别的第一多个记录中的记录的第一键值。数据处理系统能够与第一批多个记录的合并并发地建立用于对第二多个记录进行排序的第二游程。第二多个记录能够由与第一多个索引值不同的第二对应的多个索引值来索引。第二多个记录中的每个记录能够具有键域中的第二键值。数据处理系统能够确定跟踪第一多个记录到合并级别上的合并的合并索引满足分位点条件。分位点条件能够对应于键域中的多个键值中的至少一个。响应于确定合并索引对应于分位点条件,数据处理系统能够从第二缓冲器中标识第二游程的第二多个记录的子集。子集的每个记录能够具有满足分位点条件的所对应的第二键值。数据处理系统能够将第二游程的第二多个记录的子集添加到第一游程的第一多个记录到数据库上维护的合并级别上的合并。

在一些实现方式中,数据处理系统被进一步配置成基于合并索引和由分位点条件指定的分位点索引的比值来确定转接键值。在一些实现方式中,数据处理系统能够基于数据库的合并带宽确定带宽偏移。合并带宽能够指示数据库正在添加第一多个记录并且第二多个记录的子集被合并的速率。在一些实现方式中,数据处理系统能够确定合并索引满足由带宽偏移调整的转接键值。

在一些实现方式中,数据处理系统能够使用游程索引来跟踪使用第二多个记录建立第二游程。游程索引引用在第二游程中排序的第二多个记录的数目。在一些实现方式中,数据处理系统能够确定由游程索引引用的第二多个记录中的记录的第二键值满足分位点条件。在一些实现方式中,数据处理系统能够与建立第二游程并发地并响应于确定由游程索引引用的记录的第二键值满足分位点条件而发起将第二游程的第二多个记录的子集添加到合并。

在一些实现方式中,数据处理系统能够标识在第一缓冲器上建立第一游程的第一游程生成速率,该第一游程生成速率指示在第一游程中对第一多个记录的记录进行排序的速度。在一些实现方式中,数据处理系统能够标识在第二缓冲器上建立第二游程的第二游程生成速率。第二游程生成速率能够指示在第二游程中对第二多个记录中的记录进行排序的速度。在一些实现方式中,数据处理系统能够基于第一游程生成速率和第二游程生成速率中的至少一个来设定用于将第一游程的第一多个记录添加到数据库上的合并带宽。

在一些实现方式中,数据处理系统能够针对第一多个记录标识对应的多个第一键值在键域上的分布。在一些实现方式中,数据处理系统能够基于所对应的多个第一键值在键域上的分布来确定包括分位点条件的多个分位点条件。

在一些实现方式中,数据处理系统能够在合并级别上合并第二多个记录的子集和第一多个记录的同时,确定第一游程的第一多个记录的全部都被添加到数据库上的合并级别。在一些实现方式中,数据处理系统能够响应于确定添加了第一游程的所有第一多个记录而从第一多个记录释放第一缓冲器以为第三游程接收第三多个记录。在一些实现方式中,数据处理系统能够与将第二多个记录的子集合并到数据库上的合并级别上并发地在第二缓冲器上维护第二多个记录。

在一些实现方式中,数据处理系统能够确定第二多个记录的子集和第一多个记录到数据库上的合并级别上的合并完成。在一些实现方式中,数据处理系统能够响应于确定到合并级别上的合并完成而初始化数据库上的第二合并级别以接收第二游程的第二多个记录的至少剩余子集的合并。

在一些实现方式中,数据处理系统能够接收对定义键域的多个键值中的至少一个的查询。在一些实现方式中,数据处理系统能够使用查询来搜索数据库上的合并级别,该合并级别包括来自多个游程的记录。

在一些实现方式中,数据处理系统能够使用第二合并索引来跟踪第二多个记录的子集到数据库上的合并级别上的合并。第二合并索引能够引用在合并期间添加到合并级别的第二多个记录中的一个的第二键值。第二合并索引能够基于分位点条件最初设定。

在一些实现方式中,数据处理系统能够使用快速排序或优先级队列中的至少一个在键域上按对应的多个第一键值对第一多个记录进行排序。能够通过第一对应的多个索引值来最初排列第一多个记录。在一些实现方式中,数据处理系统能够经由输入数据流从数据获取源接收第二多个记录以存储在第二缓冲器上。能够通过第二对应的多个索引值来最初排列第二多个记录。在一些实现方式中,数据处理系统能够使用快速排序或优先级队列中的至少一个在键域上按对应的多个第二键值对第二多个记录进行排序。

各方面提供了用于合并数据如数据库中的记录的交错合并。与可能导致合并操作突发从而引起可能使同时发生的查询操作的性能严重地降级的计算负荷尖峰的先前方法相比,交错合并使得能够以连续且稳定的方式执行合并。交错可以基于分位点条件,即,当在合并期间满足分位点条件时,可以将第二游程添加到当前合并。分位点条件可以确定第二游程数据的要参与合并的子集。例如,当满足另一分位点条件时或者当当前合并完成且另一合并操作开始时,第二游程的剩余游程数据被遏制以便稍后合并。合并可以是分层的并且布置到合并级别中。在特定级别下的合并的输出可以提供用于在下一个级别下合并的另一游程。在所有级别下合并接着交错合并。在下面详细地讨论这些及其他方面和实现方式。前面的信息和以下详细描述包括各个方面和实现方式的说明性示例,并且提供用于理解所要求保护的方面和实现方式的性质和特性的概述或框架。附图提供对各个方面和实现方式的图示和进一步理解,并且被并入本说明书中并构成本说明书的一部分。能够组合各方面,并且将容易地领会,在本发明的一个方面的上下文中描述的特征能够与其他方面组合。能够以任何方便的形式实现各方面。例如,通过可以在适当的载体介质(计算机可读介质)上承载的适当的计算机程序,该载体介质可以是有形载体介质(例如磁盘)或无形载体介质(例如通信信号)。也可以使用合适的装置来实现各方面,该装置可以采取运行被布置成实现该方面的计算机程序的可编程计算机的形式。

附图说明

附图不旨在按比例绘制。在各个附图中,相似的附图标记和名称指示相似的元件。出于清楚的目的,可能不在每一附图中标记每一组件。在附图中:

图1示出图示使用旧策略和新拆分策略的在索引创建之后的痛苦的波动的两个曲线图。

图2是图示有时甚至同时在多个合并级别上由于偶尔的合并步骤而导致的负荷波动的图。

图3A和图3B示出图示在合并级别l上读取F个游程并在合并级别l+1上写入新游程的合并步骤的图。

图4A-4C示出图示合并如何紧接在游程生成已完成其第一游程之后开始的图。

图5是图示作为游程级别的函数的游程大小、游程计数和目前游程计数变化的图。

图6示出图示查询处理的图。查询能够首先检查最近的小游程。

图7示出图示转接键值如何能够用较低值替换的图。

图8示出描绘用于通过执行交错合并来维护键值存储的示例环境的框图。

图9A示出图示单路合并响应于合并索引达到目标分位点而变为双路合并的图。

图9B示出图示双路合并在正在并发地组装第三输入数据流的同时继续的图。

图9C示出图示双路合并响应于合并索引达到目标分位点而变为三路合并的图

图9D示出完成合并级别初始化的示意图。

图9E示出图示单路合并在竞争交错合并中响应于合并索引到达目标分位点而变为双路合并的图。

图10示出图示存储器内索引及其关联的键-指针对的图。

图11示出通过执行交错合并来维护键值存储的示例方法的流程图。

图12示出可以被采用来实现本文讨论的计算机中的任一个的说明性计算机系统的一般架构。

具体实施方式

为了阅读以下各个实施例的描述,对说明书的各部分及其相应内容的以下描述可以是有帮助的:

部分A描述交错合并。

部分B描述通过执行交错合并来维护键值存储。

部分C描述可以用于实现本申请中描述的元件中的一个或多个的一般计算机系统。

日志结构合并树(森林)擅长以高带宽为新插入加字幕,但是它们可能涉及重复合并步骤以便减少在每个后续查询中搜索到的b树分区的数目。对于有效的合并步骤,当存在足够数目的游程时合并在每个级别下反冲;此外,偶尔地,跨越多个合并级别的多个合并步骤可以立即接着彼此。

每个运行的合并步骤增加对处理器、缓冲池和I/O路径的竞争。活动和竞争的这些重复突发创建降低查询性能的波动,从而创建用户不满的波动。

本公开描述一种用于以使合并级别和游程(或分区)的数目稳定和最小化并且同时使所有合并活动平滑而没有任何明显突发的方式组织所有合并活动的调度。游程生成及其带宽驱动在每个合并级别下合并。本方法与其他合并策略的一个差异是游程一次一个地进入合并步骤,而不是像在所有此类其他合并策略中一样一次全部进入合并步骤。

日志结构合并树,例如b树或等效分区b树的森林,被广泛地用在数据管理平台中,特别地其中高带宽数据摄入例如对web日志的分析是重要的。实际上,日志记录的不断到达可能甚至给试图在多个维度上捕获并索引新信息以启用仪表板和离线分析的大规模集群造成压力。

在其他方法中,偶尔地采用合并游程或分区。不是每一新游程都涉及后续合并步骤。可能在突发中发生合并。如果输入流继续,例如,因为生成日志记录的活动继续,则合并和游程生成能够同时地发生。时常,甚至多个合并步骤能够与游程生成并发地运行。随着合并活动开始和停止,并发查询处理遭受无法预测的性能并且用户不满变得不可避免。解决查询处理性能和用户满意的降级要求连续地、高效地并以处理、缓冲池和输入/输出(I/O)资源上的持续负荷运行的游程生成和合并的模式。

当前公开引入游程生成和合并的调度(或逻辑),在本文中称为交错合并。合并逻辑能够连续地并以与游程生成相同的带宽(例如,每秒记录)运行。总体上,例如在例如在每记录比较次数或每记录I/O往返次数方面,本公开中描述的合并过程可以与在外部合并排序中一样高效。

B树索引常用在数据库、键值存储、文件系统和信息检索中。例如,B树能够用于在数据库中搜索数据或对其进行排序。另外,B树能够允许实现对文件系统的特定文件中的任意块的快速随机访问。B树索引在数据库、键值存储、文件系统和信息检索中普遍存在。B树索引有许多变体和优化。例如,b树键可以是多列(例如,复合索引)、散列值(例如,有序散列索引实现高效的创建、有效的插值搜索和容易的幻像保护)、空间填充曲线(例如,用于多维数据和查询谓词的空间索引)或异构键(例如,合并索引或主从聚类)。另外,键和值都能够被压缩,例如,作为位向量过滤器而不是行标识符序列。

B树创建能够从排序中受益,但是排序也能够从b树中受益。例如,形式为b树的外部合并排序中的游程或甚至单分区b树或线性分区b树内的所有游程都能够在合并步骤仍未完成的同时在合并以及查询处理期间实现有效的预读。这种预读能力是在下面讨论的日志结构合并树的基础。

即使初始b树创建在每个节点中留有一些自由空间,例如10%,插入也可能最终强制节点拆分的波动。如果在原始键值分布与插入的键值分布之间有高相关性,则节点拆分的这种波动可能急剧且高。节点拆分的第一波动能够拆分大多数或所有原始b树节点,从而使b树的大小翻倍。当b树的大小一次又一次地翻倍时,可能有后续波动。波动可能变得不太频繁、不太急剧且不太高。

图1示出图示使用旧策略和新拆分策略的在索引创建之后的痛苦之波动的两个曲线图。在创建在每个节点中有一些自由空间的新b树索引之后不久,插入能够引起节点拆分。如果插入和原始b树种群的键值分布高度相关,则可能在波动中发生节点拆分(或对此类拆分的调用)。节点拆分能够对处理、缓冲池和I/O资源强加额外竞争,从而降低查询处理性能、增加查询等待时间并且引起用户不满。

写入优化的b树

B树引发高写入惩罚。具体地,修改单个字节、字段或记录强制随机页写入到持久性存储。写入优化的b树试图通过将随机写入调谐成顺序写入来降低这种成本。更具体地,写入优化的b树以页粒度采用仅附加存储,从而跟踪b树结构内的新页存储位置。每个页移动涉及父页中的指针更新。因此,写入优化的b树包含闪存转换层(FTL)的功能。它们不允许同级节点之间的邻居指针,然而,它们允许通过每个页中的栅栏键例如祖先页中的分支键的副本进行全面一致性检查(联机/连续或脱机/实用程序)。

写入优化的b树可能在具有高访问等待时间(例如,寻道和旋转延迟)的存储设备上遭受差扫描性能。一种可能的优化是将键范围划分成多个段、将每个段存储在连续存储中并且在段内回收替换页。每段的键范围可以是动态的,因为每叶节点的键范围在b树中是动态的。所得设计组合了写入优化的b树和SB树的元素和优点。在闪存存储中,段可以与擦除块重合。

外部合并排序

在外部合并中,存在各式各样可能的排序键,例如b树索引中的搜索键。外部合并的主要阶段包括游程生成和合并。高效的游程生成通过替换选择来使每个游程的平均大小翻倍,也称为具有优先级队列或堆的游程生成。高效的合并要求平衡的合并,其中所有键值都参与比较的相等或类似计数,并且以高扇入合并,这也减少合并级别的数目。

存在用于使游程生成和合并交错的多种策略。使游程生成和合并交错的一种策略是懒散合并,其包括用于游程生成的单独的运算符阶段、中间合并步骤和最终合并步骤。在用于使游程生成和合并交错的所有策略当中,懒散合并涉及游程的最大目录。与策略谱相反的另一策略是急切合并,其中每个合并级别内的目录大小限于扇入,并且当任何级别上的游程计数达到扇入时调用合并步骤。在这两种策略之间,半急切合并将每个级别下的目录大小限制为扇入的两倍并且半懒散合并跨越所有级别使用单个目录并限制其大小,从而每当目录满时就合并类似大小的游程。大多数数据库产品使用懒散合并。像Napa一样的大多数日志结构合并树采用急切合并。SQL Server过去使用半懒散合并。Volcano使用了半急切合并。

游程生成和合并能够集成分组,诸如重复去除或聚合。只要最终输出适合存储器,在游程生成期间分组就对于任何输入大小实现存储器内分组。在写入游程的同时分组确保没有游程包含重复键值并且没有游程大于最终输出。

日志结构合并深林

如果b树索引中的大多数更新是插入,则最有前途的存储结构是日志结构合并树,其是树的合集(森林),或使用人工前导键字段作为分区标识符的分区b树。

日志结构合并森林被广泛地用在NoSQL数据库、键值存储以及消耗并索引连续数据流的应用中。其用于最新未排序输入数据的存储器内索引反映对于游程生成采用存储器内索引的外部合并排序(与读取-排序-写入循环中的快速排序或用于替换选择的优先级队列相对)。合并b树或b树分区的使用反映外部合并排序中的合并。一个困难的问题可以包括合并扇入的选择。在外部合并排序中,扇入受到可用于输入缓冲器的存储器限制。在日志结构合并森林中,扇入由用于最好合并效率的高扇入与低扇入之间的张力确定,使得随时存在很少的分区并且查询将检查很少的分区。日志结构合并森林的一些真实世界实现方式采用二进制合并步骤,从而使查询性能优于合并效率。

至今有另一问题被忽略。急切合并步骤造成有时没有活动合并、有时有一个合并、有时有多个合并步骤的剧烈负荷波动。

图2是图示有时甚至同时在多个合并级别上由于偶尔的合并步骤而导致的负荷波动的图。似乎高度地期望在合并效率、查询响应性(等待时间)与连续系统负荷之间实现更好的权衡。

交错合并

交错合并包括立即将每个完成的游程集成到其下一个合并步骤中。例如,每当游程生成完成级别0游程时,形成级别1游程的合并步骤就立即将其拾取。级别1游程完成后,合并步骤会立即拾取它,并且依此类推。如果时间游程生成产生级别0游程的全集,例如,和所期望的合并扇入F一样多,则合并步骤能够消耗并合并相同的数据体积。

与外部合并排序相比,差异是每个游程允许寻找具体键值并从那里继续排序的扫描。因此,每个游程不是排序的文件而是b树或等效存储结构。实际上,在合并逻辑内处于相同级别的游程集可能是单个线性分区b树。如果是这样的话,则根到叶搜索能够完全在存储器中发生。

每个合并级别下的稳定状态

在稳定状态下,存在F个完成的级别0游程加上正由游程生成形成的一个未完整游程。当游程生成完成一个游程并进行到下一个游程时,新完成的游程立即加入合并逻辑。为了实现那个,在先游程从合并逻辑中丢掉。由于合并逻辑在游程生成创建F个新游程的同时通过键域进行一次,所以原理可能是新完成的游程不是以其最低键值而是以当前正被合并的键值加入合并逻辑。因此,大多数游程参与两个合并步骤:第一合并步骤消耗高于给定转接键值的所有键值,第二合并步骤消耗低于转接键值的所有键值。

对于F个合并输入中的每个合并输入都有不同的转接键值。理想地,转接键值被选取成近似分位点。一个合并输入可以一次切换。能够在第一合并步骤期间设定初始转接键值。能够递增地调整它们。

图3A和图3B示出图示在合并级别l上读取F个游程并在合并级别l+1上写入新游程的合并步骤的图。游程i和较早游程已经被合并,能够在级别l+1下找到其内容,并且这些游程因此已经被删除并且它们在临时存储上的空间被回收。合并逻辑当前消耗从游程i+1到i+F的记录。合并(从合并级别l-1起)或游程生成(如果l=0)继续在级别l下添加游程,当前写入游程i+F+1。合并逻辑在-∞处添加了游程i+1,随着合并遍历键域而添加了游程i+2等,并且最近添加游程i+F。

合并逻辑当前接近+∞。那应该与游程生成或完成游程i+F+1的较低级别合并重合。那时,级别l上的游程创建将切换到游程i+F+2。从级别l到级别l+1的合并将丢掉(并删除)游程i+1,添加游程i+F+1,在游程i+2至i+F中从+∞卷绕到-∞,在合并级别l+1上完成游程j并切换到游程j+1,并且恢复合并。

每个合并级别的初始化

游程生成一完成其第一游程,合并就开始。首先,合并扇入为1。当游程生成完成其第二游程时,合并逻辑应该已达到等于键值分布的1/F分位点的键值。合并两个游程从此分位点键值继续。现在忽略第二游程的第一1/F小部分;它将进入第二合并输出游程。当游程生成完成其第三游程时,合并逻辑应改已达到等于2/F分位点的键值。合并三个游程从此分位点键值继续。

以这种方式,实际合并扇入在通过键域的第一遍期间从1增长到F。当合并逻辑达到键域的末尾时,能够从合并中(并且实际上从临时存储中)丢掉一个游程,并且合并逻辑能够添加第F+1个游程。

图4A-4C示出图示合并如何紧接在游程生成已完成其第一游程之后开始的图。最终,来自合并级别0的游程0至F-1形成合并级别l的游程0。由于合并以琐碎扇入1开始,所以合并级别l上的游程0将在其最低键范围内具有很少的记录。当游程生成完成第二游程并且合并逻辑达到第一转接键值时,琐碎的单输入合并变为真实两输入(二进制)合并。随着游程生成完成更多的游程并且合并逻辑达到进一步的转接键值,合并扇入增长以达到全扇入F。此扇入被从最后转接键值起用至合并步骤的结束。合并逻辑从级别0到级别1继续全扇入,直到无限地对于流输入耗尽所有输入为止。当合并逻辑第一次达到+∞时,它在级别l上完成第一游程,并且合并逻辑从级别l开始直到级别2。

初始合并努力不如全F路合并有效。然而,合并排序的其他方法甚至直到游程生成已完成F个游程才开始合并。当F个游程完成时,目前的交错合并以F个游程的全扇入达到全效力。它持续完全有效直到输入结束(对于流永远)为止。

初始转接键值可以是键域内分位点的任何合理估计以及键值在未排序输入中的分布。可以非常适度地递增调整转接键值。

每个合并级别的关闭

如果未排序输入流是有限的,则合并逻辑在每个合并级别下继续,直到其输入被全部处理并且已从合并逻辑并从临时存储中丢掉所有游程为止。一个困难是在不同合并级别中对转接键的选择不同。

系统状态

相同的转接键值和所有合并级别有关。实际上,用于合并级别0游程的整个设计延续到合并级别i游程以形成级别i+1游程的所有级别。换句话说,第一合并一完成其第一输出游程,下一个级别合并就开始,虽然最初以琐碎合并扇入开始。因此,在每个级别下,存在F个完成的游程并且当前馈给合并逻辑,而且当前正在形成另一个游程。总是有顶级合并当前正在被初始化;一旦那个合并在它完成其第一输出游程时达到其稳定状态,下一个合并级别的初始化就开始。顶级合并(在任何时间点)能够以不到全扇入F运行。所有较低的中间合并级别都能够以全扇入、以平衡的输入大小并且因此以最大效率和效力运行。

在每个合并级别下的带宽与游程生成的带宽相同。每个合并级别能够处理和游程生成从其未排序流输入产生的一样多游程行或页(每单位时间)。存储消耗像游程大小一样逐级以指数方式(按等于合并扇入F的系数)增长。合并逻辑通过键域进行的速度(也按系数F)逐级慢下来。

图5是图示作为游程级别的函数的游程大小、游程计数和目前游程计数的变化的图。左侧部分示出游程的大小如何从一个合并级别向下一个合并级别增长。实际上,这些大小以指数方式增长,所以除非在对数标度上指示大小,否则三角形不是精确正确的形状。中央部分示出跨越整个排序活动在每个级别下创建并合并的游程的计数。右侧部分示出在任何时间点在每个级别下存在的游程的计数。除合并仍处于其初始化阶段中的当前最高合并级别以外,此数字跨越F+1(F个合并输入,1个游程生成或较低合并级别的输出)下的所有合并级别是恒定的。(在这里未图示合并关闭)。

在任何时间点,数据的大块是在最高级别中或者它当前正被合并并移动到该级别。第一游程一在新级别下完成,就在游程的那个级别中存在和在每个在先级别中一样多的数据。这也是合并在此级别下开始并且此级别变为新顶级的时间。

作为具体示例,考虑高度并行集群中的单个节点以50MB/s将输入吸收到1GB的初始游程中并以10的扇入合并它们。在6个合并级别之后,合并逻辑已读取并写入每个记录6次,游程大小将为1EB(每节点),总处理带宽(跨越游程生成和所有合并级别)将为350MB/s,当前现有游程的计数将为66(包括在每个合并级别下形成的一个),并且在每个查询中搜索的游程的计数将为60。注意,1EB/50MB/s=20M秒

查询处理

查询处理能够确定要搜索哪些游程,然后高效地搜索它们。如果每个游程是b树或b树内的分区,则在每个游程内搜索是容易的。在所有现有游程当中,查询能够搜索满足以下条件的任何游程:(1)游程完成—没有写入器将更多数据附加到此游程,既不是游程生成也不是合并;(2)游程尚未被完全合并到下一个合并级别下的游程中—合并步骤仍在读取游程;以及(3)当前合并位置高于游程的转接键值—在下一个合并级别下没有已经持有游程内容的完成游程。

图6示出图示查询处理的图。查询能够首先检查最近的小游程。如果查询引用具体时间范围,则能够跳过一些游程。对于范围查询,可能有必要将查询谓词一分为二,即游程的转接键值是否落在查询谓词内。如果排序输出是期望的,则查询执行计划将合并来自多个b树(或分区)的扫描输出。由于每个单独的扫描提供排序键值,所以可能不从头开始执行排序,也不将所有扫描结果的并集视为未排序的。

交错合并的概述

总而言之,交错合并将未排序输入流变成有序索引。它以日志结构合并树的样式采用游程生成和合并。合并是高效的,因为它是平衡的,使得在每个合并步骤中,所有输入记录都已参与了相同数目的较早比较(舍入误差除外)。能够选取合并扇入以在合并效率与在任何时间存在的游程(b树、分区)如查询要检查的游程的数目之间获得最佳权衡。

在每个合并级别下,合并逻辑连续地循环通过键域。定义特性是不同的游程以不同的键值进入合并步骤;在整个键域之上通过一个全循环合并每个游程。当前最高级别的合并步骤递增地增加其合并;所有较低的合并步骤始终按所选取的扇入而运行。

此合并策略使在任何时间点存在的游程的数目最小化。它也可以在每个合并级别以及整体合并级别下使此数字保持稳定。与以上设计比,在下面讨论的变体试图甚至更进取地查询较高级别的游程。

调整转接键值

对转接值的良好选择是分位点。然而,对分位点键值的最好当前估计能够随着时间的推移而改变。因此,转接键值的集合能够改变。以下文本和图集中于调整单个转接键值。

图7示出图示转接键值如何用较低值替换的图。在没有这样的变化的情况下,合并逻辑将紧接在丢掉游程0.2之后添加输入游程0.F+2。如果较低的转接值是期望的,则合并逻辑将在较低的键值处稍微较早地添加0.F+2。因此,合并逻辑临时具有多于F个输入。如果增量变化是足够的,则合并逻辑能够在降低转接键值时限于最大扇入F+1,而在较高的转接键值是期望的时限于最小扇入F-1。

总之,日志结构合并树理想地适合于通过索引多个维度上的新信息来组合高带宽数据摄入和高效的查询处理。另一方面,其他实现方式涉及偶尔的合并步骤,这些合并步骤给CPU、缓冲池和I/O设备强加负荷,这继而使查询处理慢下来并且由于不可预测的响应性而引起用户混乱。

如果每个合并步骤具有平衡的输入,则排序和合并是最高效的。在每个合并级别下连续合并在游程生成和每个合并级别中实现相等的带宽并且对于游程的每个级别实现固定存储要求。在每个级别下合并变为连续过程而不是预期突发行为,这稍微让人想起游程生成通过依靠替换选择(例如,利用优先级队列)而不是读取-排序-写入循环(例如,利用快速排序)而变为连续过程。通过避免负荷尖峰和性能陡崖,所提出的合并策略避免了其他方法中的“痛苦之波动”。

日志结构合并树和分步合并树是提供有利于高带宽数据摄取或低等待时间索引搜索的权衡选择的许多b树的森林。b树或分区的高效合并即很少的合并级别要求最大扇入;但是高效的搜索即一次很少的分区要求最小扇入,即二进制合并步骤。不能消除这种紧张关系,但是两种技术能够改变查询中的合并扇入与分区计数之间的关系。在典型情形下,合并扇入提高了2

下文是与日志结构合并森林中的交错合并的方法、装置和系统有关的各种构思以及其实现方式的更详细描述。可以以许多方式中的任一种实现在上面介绍并在下面更详细地讨论的各种构思,因为所描述的构思不限于实现方式的任何特定方式。

B树索引数十年来在数据库、键值存储、文件系统和信息检索中普遍存在。他们擅长随机插入和删除、点和范围查询以及混合工作负荷。此外,它们具有极好的操作特性,包括排序之后高效的索引创建、高效的一致性检查、通过锁定键值及它们之间的间隙进行可串行化细粒度并发控制以及使用排序流的高效的查询执行,例如有序扫描之后的流内聚合和合并加入。索引连续的大量数据流例如日志和历史表不算什么优势,因为即使最小的更新或插入也需要读取并写入至少叶子页(在大多数上下文中)。换句话说,大部分插入应用遭受等于阻塞系数(每页记录,例如几百个)的写入放大。读取(用于更新)的计数等于写入的计数(忽略缓冲器影响,假定索引比可用或分配的缓冲池大得多)。

引言

可以在数据库、键值存储、文件系统和信息检索中使用B树索引。他们擅长随机插入和删除、点和范围查询以及混合工作负荷。此外,它们具有极好的操作特性,包括排序之后高效的索引创建、高效的一致性检查、通过锁定键值及它们之间的间隙进行可串行化细粒度并发控制以及使用排序流的高效的查询执行,例如有序扫描之后的流内聚合和合并加入。索引连续的大量数据流例如日志和历史表不算什么优势,因为即使最小的更新或插入也需要读取并写入至少叶子页(在大多数上下文中)。换句话说,大部分插入应用遭受等于阻塞系数(每页记录,例如几百个)的写入放大。读取(用于更新)的计数等于写入的计数(忽略缓冲器影响,假定索引比可用或分配的缓冲池大得多)。

日志结构合并树以及分步合并树是具体地为索引日志和历史表而设计的。它们能够采用大顺序读取和写入,写入放大等于合并深度(例如,约十),并且读取计数等于写入计数。然而,它们支持在合并的同时搜索,包括所需要的并发控制和恢复技术。引入日志结构合并树的研究演示了对于其目标应用,日志结构合并树在资源效率和数据中心成本方面大大优于b树。

此研究一直以真实应用捕获、索引和查询日志记录为动机。具体示例可以包括按时间严格地排序的数据库恢复日志加上按数据库页标识符排序和索引的日志存档以便实现单页修复以及即时重新启动、即时还原、即时故障转移、自我修复索引等;或许多并发用户需要组装并分析用户会话的web服务(在用户标识符上对日志记录进行排序、索引和聚合)。

示例上下文的相关特性是:信息捕获过程每分钟添加一排序游程;每个游程包含一分钟有价值的有序索引的新条目;索引是每分区有b树(或分区b树)的b树森林;并且按键值查询往后最多一个月(28-31天×24小时)。在31×24×60=44,640的总合并扇入情况下,单级合并(例如,每月一次)是不切实际的,并且两级合并需要扇入212(每212分钟≈3

表1.一个月内的合并和搜索分钟数。

表1示出针对此示例的更多计算。扇入列隐式地指示合并一分钟分区之间的分钟数。在本公开中可互换地使用术语增量、游程和分区,术语(游程的)合并和(增量的)压实也是如此。在所有情况下每月有一次最终合并。搜索努力指示每个查询要搜索的分区的平均(预期)数目。它是合并级别、所需扇入F和常数1.5的乘积,其反映在每个合并级别上的分区的数目在F与2F之间以锯齿模式振荡。对最小合并努力(2个合并级别)的选择暗示搜索成本(以及因此查询等待时间)为最佳成本的14倍(636对45个分区);对最小查询等待时间的选择需要为最佳五倍以上的合并努力(10对2个合并级别);并且平衡的选择需要两倍最佳的合并努力(4对2个合并级别)和两倍最佳的搜索努力(90对45个分区)。对搜索等待时间的近似最佳选择仍然需要为最佳三倍以上的合并努力(6对2个合并级别)。这是抽象承诺具体改进系数的情况。

此研究的目标是对这些选择、数据结构和算法进行改进。例如,存储结构可以是分区b树的线性形式;存储器内数据结构可以是在存储上管理游程生成和游程的有序索引;并且算法可以是消除等待合并的游程、从而在对日志结构合并树重要的一些度量方面在外部合并排序上改进的交错连续合并逻辑。

外部合并排序

外部合并排序具有三个阶段:输入阶段,也称为游程生成;输出阶段,也称为最终合并;以及必要时一些中间合并步骤。游程生成用生产者流水线化,而最后合并用消耗者流水线化。例如,合并加入可能在其最终合并中消耗其来自两个排序操作的输入并且将其加入结果产生到另一排序的游程生成逻辑中,可能为准备不同加入列上的另一合并加入准备。

游程生成可以采用读取-排序-写入循环,例如,使用快速排序,或连续替换选择,例如,使用优先级队列。通过读取-排序-写入循环生成中的游程是所分配的存储器的大小。通过替换选择的游程生成在最坏情况(反向排序输入)下产生此类游程,在预期情况(随机输入)下产生两倍的游程大小,并且在更好和最好情况(几乎或完全预排序的输入)下长得多。失败者树优先级队列以最少的比较实现替换选择。诸如在次序保留二进制串中对整个键值进行编码的键归一化减少每比较成本。偏移值代码化即一种前缀截断的形式避免许多字节-字符串比较并减少剩余字节-字符串比较的字节计数。硬件支持能够加速失败者树优先级队列和偏移值代码化。归一化键和偏移值代码化都经由临时存储上的游程文件和合并步骤从游程生成携带到排序输出和查询执行,例如,流内聚合或合并加入。

存储器内索引能够支持读取-排序-写入循环和替换选择。除了对输入记录进行重新排序之外,存储器内索引还能够支持聚合,从而实现和基于散列的分组一样高效的基于排序的分组(重复去除和聚合)。顺便提及,如果存储器内索引支持多种类型的记录,则两种类型的算法都受益,具体地一组任选地不是由中间聚合记录而是由输入记录表示。例如,对于遍及具有分组键和一个量度的表对最小值、最大值和平均值的查询,输入记录能够比具有最小值、最大值、总和和计数的中间记录更紧凑地表示一组。

对于用于临时存储上的游程的最小I/O,外部合并排序使用最大合并扇入。扇入受到缓冲器大小、页大小以及预读和后写缓冲要求限制。近似地,页大小应该(近似地)等于临时存储的等待时间和带宽的乘积。例如,如果临时存储使用磁盘驱动器,则10ms×100MB/s=1MB可以是合理的页大小。

例如,外部合并排序的主要设计思想能够适用于存储器层次中的任何步骤,不仅适用于溢出到外部(临时)存储的内部存储器,而且还适用于溢出到主存储器的CPU高速缓存或者适用于溢出到磁盘的闪存存储。从内到外排序的转变应该是递增的,是为优雅降级并因此避免“性能陡崖”而设计的。引入中间合并步骤从具有单个(最终)合并步骤的外部合并排序到具有多个(中间)合并步骤的外部合并排序的转变也是如此。再次,这种考虑事项适用于存储器层次中的所有步骤。

日志结构合并树

用日志结构合并树的发明人话说,日志结构合并树(LSM树)是被设计来为在延长时段期间经历高速率的记录插入(和删除)提供低成本索引的基于磁盘的数据结构。LSM树使用推迟并分批处理索引变化从而以让人想起合并排序的高效方式通过一个或多个磁盘组件将来自基于存储器的组的变化级联的算法。此外,“LSM树在索引插入比检索条目的查找更常见的应用中最有用。例如,这似乎为历史表和日志文件的常见性质。”除了其具体示例之外,据信该技术在需要在高带宽下进行连续信息捕获并遍及旧和新(最近的)数据进行搜索查询的任何上下文—换句话说,任何数据仓库、对web日志的任何分析、基于预写日志记录的任何重新启动或还原操作等中是适用的。

日志结构合并树在永久存储上采用分区,常常作为单独的b树,而不是在临时存储上采用排序游程。查询可以随时搜索分区。此外,日志结构合并树采用与外部合并排序明显不同的合并模式。他们重复地将存储器内容与所有现有数据合并。在激励示例方面,它们保存第一分钟的数据,将第二分钟与第一分钟合并,将第三分钟与前两分钟合并,将第四分钟与前三分钟合并等。最终,例如,在半小时之后,他们单独留下该分区并以一、二、三等分钟重新启动。在另一半小时之后,它们将第二半小时与第一半小时合并,然后将第三半小时与第一小时合并,将第四半小时与前一个半小时合并等。最终,例如,在一天之后,它们将单独留下该分区等。换句话说,如在外部合并排序中一样有多个合并级别,但是在每个级别内也有合并步骤。注意,这些合并步骤是二进制的。它们精确地组合两个输入,并且常常不平衡,因为它们组合大小非常不同的输入。

同这种非平衡的合并模式对比,平衡的合并可以减少合并努力但是它增加搜索努力。在平衡的合并模式中,如果具有扇入F的每个合并步骤在F个输入游程完成时开始并在另一F个输入游程准备好在同一级别上进行下一个合并步骤时结束,则通过每个查询搜索的游程(分区)的数目重复地从F增长到2F。平均而言,每个查询搜索1.5F分区,如引言中针对表1的计算中所使用的。设定合并扇入F的权衡或策略决策有利于合并或搜索:小扇入有利于高效的搜索,大扇入有利于高效的合并。(这里假定是往返于临时存储或在存储器内移动数据是合并中的主要努力和成本,并且键比较的成本在此优化中可忽略。)二进制合并使在通过每个查询搜索的分区的任何时间点存在的游程的数目最小化,但是(在所有平衡的合并策略当中)使合并努力最大化。最大扇入通过使合并级别的数目最小化来使合并努力最小化,但是它使查询努力最大化。

日志结构合并树的原始设计采用两种附加技术。首先,逻辑更新映射到替换记录的物理插入,逻辑删除映射到“墓碑”记录的物理插入,而在合并步骤中和在查询执行中的逻辑聚合正确的最新内容。第二,即使大块删除的这种方法未提供关于删除记录(若有的话)的数目的任何立即反馈,“范围删除”也将特殊类型的单个记录用于整个键范围的逻辑删除。

分区B树和自适应合并

分区b树是实际上包含许多b树的单个b树。每个索引条目中的人工前导键字段保持分区标识符。前缀截断实际上避免任何附加存储需求和比较开销。分区的创建并去除可能需要键插入和删除,但是没有目录事务或文件系统更新。分区b树中的搜索逻辑与用于b树的Tandem多维访问方法的逻辑相同。搜索将枚举当前存在的分区标识符并搜索每个分区。利用连续分区标识符,对键值的搜索需要每分区一次根到叶搜索。

存储器内分区吸收小事务,包括替换记录和墓碑记录的插入。记录通过与利用替换选择的游程生成类似的增量溢出向存储溢出。合并分区可能需要对具体分区的仅附加访问,其是除了在分区b树的最后分区中外的插入。

分区b树能够实现作为“在有趣调度上合并排序”的自适应合并,或作为查询执行的副作用合并查询谓词的整个键范围,因为数据库破解是“在有趣调度上快速排序”,在每个范围查询中拆分一个或两个现有分区。自适应合并在第一查询(游程生成,不仅仅复制键值)中且在每个查询中需要比数据库破解更多的努力,直到索引被完全优化(变成单个分区)为止,但是它以类似的总努力(约N log

分区b树可以采用几种附加技术。首先,大插入(加载操作)可能直接转向新分区或甚至多个新分区,使得加载操作可能需要游程生成逻辑但不需要合并逻辑。第二,冗余存储结构例如次级索引和物化(索引)视图可能过时,同时新索引条目在初级存储结构中在合并步骤期间传播。这种推迟的维护仍然允许仅索引检索,但是它将检查初级存储结构中的最近分区。第三,从存储器内分区向持久性存储溢出可以任选地保留“流行的”索引条目。这在基于排序的分组(重复去除和聚合)中特别有用。在用于预写日志记录的恢复日志中,分组和聚合意指通过计算跨越多个原始日志记录的“净变化”进行日志压缩;保留流行的索引条目意指集中于数据库热点的日志压缩。第四,在跨越多个分区的昂贵搜索之后,可以将最新记录作为替换记录重新插入到存储器内分区中。在具有时间局部性的应用和查询中,这种类似LRU的逻辑可以实现明显的节约。第五,对“若不存在则插入”的请求可以涉及索引搜索。替代地,特殊“若不存在则插入”索引条目的插入延迟从更新到查询执行的决策,避免在插入期间搜索,并且实际上免费作为合并逻辑的一部分执行检查。然而,它不会立即指示键值是否已经存在。第六,“若存在则插入或更新”索引条目的插入也可以避免在插入期间搜索。

与B树有关的其他方法的概述

日志结构合并树定义索引流、具有并发低等待时间查询的连续高带宽插入。他们可能需要在这两个目标之间进行折衷。分区b树是用于日志结构合并树的可能的表示或存储结构。自适应合并将合并和查询执行与合并查询执行的副作用组合。接下来的两个部分介绍分区b树以及在日志结构合并树中合并的变体。

线性分区B树

作为数据结构,线性分区b树既是b树又是链表,或者实际上是许多链表。可以有一个存储器内分区被组织为b树(或等效的东西,例如2-3-树)。存储上分区可以具有叶节点但没有分支节点(父节点、祖父母节点、祖先节点)。替代地,叶节点可以保持多种类型的数据记录,其中的一个是键-指针对,并且每个分区j能够在其叶中包括分区j-1的父条目(键-指针对)作为数据记录,其中存储器内分区为最近的存储上分区保持键-指针对。即使所有存储上分区缺少分支节点并且因此看起来并不像树,它们的数据页也仍将被称作叶节点。存储上分区j中的每个叶节点x不仅保持分区j-1的父条目,而且还保持到分区j-1中的叶节点的指针,该指针对应于叶节点x中的最低键值。

由于线性分区b树中的叶节点支持至少两种记录类型以及针对它们的共享排序次序,所以它们似乎对合并b树理想。为了对复杂对象的组件进行聚类,合并b树基于其公共属性并因此基于公共排序次序组合多个单表索引。利用合适的键结构,可以随意添加并去除单表索引。为了高效地去除许多索引当中的一个索引,“范围删除”记录可能被设计为影响仅一种记录类型。

线性分区b树的存储要求等于b树的存储要求,因为尽管它们在不同的地方,但是它们具有相同的父条目;并且在线性分区b树中缺少b树的祖父母和另外的祖先级别,这些线性分区b树具有几个附加父和祖父母条目,因为叶级别中的父条目扩展叶级别并且因此可能需要几个更多的祖先节点。

线性分区B树中的搜索和合并

确切匹配(相等)查询在存储器内分区内执行根到叶b树搜索,然后访问像链表一样的较早分区内的正确页。在此搜索中,查询访问包含感兴趣键值的数据页或者将在存在键值的情况下包含它。通过避免重复的根到叶搜索,线性分区b树中的查询比在分区b树中的查询更高效。范围查询在每个分区内扫描,其中分区j-1中的扫描由分区j中找到的指针引导。

合并步骤组合紧接在存储器内分区之前的相邻分区。合并逻辑删除在存储器中用于合并输入的键-指针对并且插入用于合并输出的键-指针对。在合并输出中,合并逻辑将键-指针对抑制到其他合并输入,但是保存引用紧接在合并输入之前的分区的键-指针对。

注意,此数据结构容易支持多级外部合并排序。在任何时间点,存储器内分区为游程生成服务。每当(紧接在存储器内分区之前)存在适当数目的级别0游程时,它们就被合并并用级别1游程替换。类似地,每当存在正确数目的级别1游程时,它们就被合并并用级别2游程替换。注意,存在当这些级别1游程紧接在存储器内分区之前时的时间点—这是合并它们的时间。相同的逻辑适用于附加合并级别。

线性分区B树的变化

线性分区b树支持对排序结果进行相等搜索和范围扫描。相等搜索从根到叶遍历存储器内分区,然后在存储上分区中遍历链表。范围扫描从对低键值的搜索开始,然后合并通过嵌入在存储器内索引中的键-指针对所引导的所有分区和这些分区。在数据结构和算法方面存在在一些情况或应用中可能有用的一些变化。

首先,存储上结构可以包括b树分支节点和链表两者。这对仅在分区的一小部分中出现的罕见搜索键的搜索可能有用。例如,如果键值仅出现在所有分区的5%中,则即使在CPU努力方面不是高效的,在I/O方面执行几次根到页遍历比跟随20倍以上的分区到分区指针也可能更高效。可以使用也称为布隆滤波器的位向量滤波器来计算要搜索的分区数目的估计以及具体分区的保守估计。与b树和线性分区b树的默认设计相比,冗余父条目(既在父节点中又在下一个分区的叶节点中)适度增加存储要求。这种变体使线性分区b树与Tokutek索引树有些类似。

第二,非常大的分区可能需要非常多的父条目,从而可能为存储器内分区创建空间竞争。在那种情况下,非常大的分区可以具有父节点(紧接在叶节点上方),但是没有祖父母节点或另外的祖先节点;存储器内分区中的键-指针对然后引用在前分区中的父节点而不是叶节点。可以想象更极端的变体,例如,如果每个游程是b树,则下一个分区可以包含仅根的键-指针对,从而使所有其他b树级别保持具有叶,例如,具有数据页。使用这种技术,即使对于极其大的分区,也似乎容易能够将下一个分区中的键-指针对限制为可能100或1,000个。注意,此变体不影响存储要求,它将要求从后续分区移动到数据分区。

第三,代替通过所有分区的链表,存储器内分区可以保持来自多个分区例如按其年龄或创建时间仔细地选择的几个分区的键-指针对。这些分区也可以具有后续存储上分区中的键-指针对,或者存储器内分区中的键-指针对可能是唯一可用的访问路径。再次,此变体不修改总空间要求,但是它将空间要求从后继分区移动到存储器内分区。

最后,每个键-指针对可以使区过滤器附连。所包括的位向量滤波器、最小值和最大值以及任选的次最小值和次最大值概括下一个分区中的数据。不概括所有后续分区。因此,它们能够保存对数据值的搜索,而不保存对键-指针对的搜索。

线性分区B树的概述

总之,能够通过后面是链表遍历的单个存储器内根到叶遍历来搜索线性分区b树。存在多个变化;此外,这些变化的任何组合是可能的,例如,存储器内分区为多个分区中的叶节点和分支节点保持键-指针对。

最终标记:然而分区b树是在每个键值中有一个人工前导键字段的单个b树,线性分区b树具有可能根本不实际上为b树而是简单为排序游程的存储上分量,并且它们可以形成文件系统中的单个文件或者可以存在多个单独的文件。换句话说,线性分区b树能够使用允许直接访问页的任何存储上文件格式。

交错合并

合并过程是连续的,没有合并步骤的突然开始和停止。游程可以以除-∞和+∞以外的键值进入和退出合并步骤。在其他合并逻辑中,每个合并输入游程对确切一个合并输出游程做出贡献,然而在交错合并中,每个合并输入游程在大多数情况下对两个合并输出游程做出贡献。

为了开始以特定键值合并输入游程,需要在游程内进行高效的搜索。b树在游程创建期间以很少的额外成本提供该能力。存在将游程组织成b树的多种方式。线性分区b树提供一个有吸引力的选择。

存储器内有序索引(可能为b树)为存储上分区保持数据记录以及键-指针对。存储上分区可能没有它们自己的分支节点;换句话说,它们可以是任何格式的平面排序文件。游程(分区)被按级别组织;每个合并级别的游程形成链表并且每个合并级别的这些链表的锚点位于存储器内索引中。

查询从最近的分区开始搜索存储器内索引并遍历链表。合并步骤如以下子部分中所描述的那样修改存储器内索引。对临时存储的增量释放的讨论被延迟到“存储空间回收”部分。

现在参考图8,描绘的是通过执行交错合并来维护键值存储的系统或环境800。环境800能够包括至少一个计算机网络810。网络810可以是计算机网络,其能够包括一个或多个局域网、广域网、专用网、公用网和因特网。环境800能够包括至少一个数据获取源855。环境800能够包括至少一个数据处理系统805。数据处理系统805能够包括至少一个存储介质815。存储815可以包括任何计算机可读存储介质。数据处理系统805能够包括至少一个游程生成器825、至少一个合并处理程序830、至少一个合并跟踪器835和至少一个查询处理程序840。数据处理系统805能够包括至少一个数据库845。在一些实现方式中,数据处理系统805能够包括数据获取源855。在一些实现方式中,存储815和数据库845可以是数据处理系统805上的同一数据存储的一部分。

系统800的这些组件(例如,网络810、数据处理系统805的存储815、游程生成器825、合并处理程序830、合并跟踪器835、查询处理程序840和数据库845以及数据获取源855)能够使用本文结合图12详细地描述的计算系统1200的组件来实现。例如,数据处理系统805能够包括服务器或其他计算设备。数据获取源855也能够包括服务器或其他计算设备。数据处理系统805的组件中的每一个均能够执行本文结合部分A和B详述的功能性。

数据获取源855能够获取、接收或标识数据记录(在本文中有时通常称为记录)。每个数据记录能够包括至少一个键值(有时在本文中通常称为值)。键值能够包括字母数字字符(例如,字符或字符串)或数字(例如,双精度、整数和浮点值)的集合。可以将键值定义为在键域内。数据记录的键值的键域能够定义记录的键值的范围。在一些实现方式中,键域能够具有最小键值和最大键值,其中键域包括介于最小键值与最大键值之间的键值。例如,键域可以是能够通过传感器测量飞机上的热量来读取的温度的范围(例如,-150℃至1500℃)。

由数据获取源855获取的每个数据记录也能够包括与数据记录的创建次序相对应的索引值(例如,时间或序列号)。索引值可以与定义键值的键域不同。在一些实现方式中,索引值可以对应于由数据获取源855接收数据记录的时间。数据获取源855能够生成时间索引并使其与每个数据记录相关联。数据记录可以是例如结构模板、由某些值填充的计算机系统中的存储器的区域或诸如类或C类结构的数据结构。在一些实现方式中,数据获取源855能够生成包括一个或多个键值的数据记录。例如,数据获取源855可以是与飞机中的传感器耦合的计算系统,该传感器能够以一定时间间隔对温度值进行测量和采样。在此示例中,数据获取源855能够生成包括基于传感器的温度读数的键值和基于数据获取源的当前时间值的键值的数据记录。

数据获取源855能够经由网络810将数据记录传送到数据处理系统805以维护数据记录。在一些实现方式中,数据获取源855能够在连续流中传送数据记录。在一些实现方式中,数据获取源855能够以规则时间间隔提供数据记录(例如,每十毫秒一个数据记录)。在一些实现方式中,数据获取源855能够以可变时间间隔排程传送数据记录。在一些实现方式中,数据获取源855能够经由通信接口将数据直接传送到数据处理系统805。在一些实现方式中,数据获取源855能够基于与时间无关的排程提供数据记录。

在数据处理系统805上执行的游程生成器825能够经由网络810从数据获取源855接收数据记录。在接收到数据记录情况下,游程生成器825能够在存储815上存储并维护数据记录。游程生成器825能够访问数据处理系统805的存储815以将所接收到的数据记录布置、存储或写入到一个或多个缓冲器。每个缓冲器能够对应于存储815中的存储器的分配区域。每个缓冲器能够包含由游程生成器825从数据获取源855接收到的数据记录中的一个或多个。在一些实现方式中,可以在不同的存储815上存储并维护每个缓冲器。在不同的实现方式中,可以在同一存储815上存储并维护每个缓冲器。在准备排序时,游程生成器825能够基于从数据获取源855接收的次序将数据记录按顺序写入或存储到缓冲器上。

使用存储在存储815上的记录,游程生成器825能够建立至少一个游程820A-N(在下文中通常称为游程820)(有时在本文中称为分区或增量)。为了建立游程820,游程生成器825能够访问在存储815上维护的缓冲器中的至少一个。在一些实现方式中,游程生成器825能够访问在数据库845上维护的合并级别850A-N中的至少一个。在本文中在下面提供在数据库845上维护合并级别850A-N的细节。存储815(或数据库845)中的缓冲器中的记录集能够最初按索引值(例如,时间戳或序列)布置或索引,并且可以在键域之上未排序。例如,由游程生成器825接收的数据记录可以对应于跨越多个客户端对内容项的交互。数据记录能够包含两个键值:一个与交互的时间相对应,而另一个标识内容项。游程生成器825可以最初以接收的次序将数据记录存储在存储815上的缓冲器中。为了准备记录以进行交错合并,游程生成器825能够通过内容项索引来对数据记录进行排序。

在建立游程820时,游程生成器825能够执行排序算法以针对游程820对缓冲器的记录进行重新布置和排序。用于建立游程820的排序算法能够包括快速排序、优先级队列、合并排序、堆排序、插入排序、冒泡排序、二叉树排序、基数排序和桶排序等。为了执行排序算法,游程生成器825能够标识或建立键域,在该键域之上它可以将数据记录排序成存储815上的游程820。如以上所讨论的,键域能够定义记录的键值的范围。此外,游程生成器825能够标识存储815的缓冲器中的每个数据记录的键值。使用缓冲器中的数据记录的键值,游程生成器825能够执行排序算法以重新布置数据记录。随着排序完成,游程生成器825能够将存储815中的缓冲器的记录建立为游程820。

由游程生成器825建立的游程820能够依照用于维护排序记录的数据结构。例如,游程820可以是如本文所描述的b树或b树的变体。在此示例中,游程生成器825能够从记录生成排序数据结构,例如b树或b树的变体。游程生成器825能够将游程820存储到为存储815中的游程820所指定的缓冲器中。游程820可以是排序的多个记录,每个记录包含键域的键值。游程820能够各自在存储815中占据缓冲器或存储器的区域。存储器的区域能够由数据处理系统805的游程生成器825或任何其他模块建立。在一些实现方式中,游程820各自是按键域的键值索引的排序b树。在一些实现方式中,游程820是不同类型的排序数据结构,按键域的键值索引或排序。在一些实现方式中,每个游程820占据存储815中的存储器的离散区域或缓冲器。在一些实现方式中,所有游程820占据存储815中的存储器的单个区域或缓冲器。在一些实现方式中,能够按键值以升序(例如,通过增加数值或以字母次序)对游程820中的每一个进行排序。在一些实现方式中,能够按键值以降序(例如,通过减小数值或以字母次序的反序)对游程820中的每一个进行排序。

随着游程820的建立,在数据处理系统805上执行的合并处理程序830能够将游程820中的一个或多个合并到数据库845上的至少一个合并级别850A-N(在下文中通常称为合并级别850)。在一些实现方式中,能够在执行诸如以上讨论的那些的排序算法的同时执行一个或多个游程820到一个合并级别850上的合并。排序算法能够包括例如合并排序,诸如外部合并排序。基于要合并的游程820的数目,合并处理程序830能够使用在存储815的缓冲器上维护的游程820中的n个来执行n路合并以产生合并级别850中的一个。合并级别850中的每一个均包括来自先前合并级别850的记录。在合并完成时,合并级别850能够包括来自先前合并级别850的排序数据记录的游程。例如,合并级别850B上的游程由来自第一合并级别850A的两个或更多个游程的合并生成。合并处理程序830能够跨越合并级别850中的任一个并发地执行合并。合并处理程序830也能够将一个或多个游程820合并到数据库845中的合并级别850中。例如,合并处理程序830能够将第一游程820A和第二游程820B合并成合并级别850A上的游程。

数据库845可以是被配置成存储按键值索引的一个或多个合并级别850的数据库。在一些实现方式中,数据库845在数据处理系统805内部,并且可以为存储815的一部分或者反之亦然。在一些实现方式中,数据库845可以存在于数据处理系统805外部,并且可以经由网络810来访问。在一些实现方式中,数据库845可以跨越许多不同的计算机系统或存储元件分布,并且可以经由网络810和/或合适的计算机总线接口来访问。合并级别850能够由与存储815上的数据游程820类似的数据游程组成。在一些实现方式中,合并级别上的游程的数目小于在其之前的合并级别上的游程的数目。例如,如果合并级别850B由4个游程组成,则合并级别850A能够由大于4个游程组成。

为了执行合并,合并处理程序830能够从一个或多个游程820访问数据记录。在一些实现方式中,由合并处理程序830访问的记录能够包括来自先前合并级别850的一个或多个游程820中的记录。合并处理程序830能够将来自不同游程820的数据记录添加到合并级别850上的游程中。对于级别0合并,可以将来自不同游程820的数据记录从存储815合并到数据库845上的第一合并级别850A中。在另一示例中,能够将第一合并级别850A上的第一游程820A和第二游程820B合并到第二合并级别850B上的第一游程820A中。能够使用合并排序算法来合并数据记录,使得第二合并级别850B的所得第一游程820A中的数据记录以基于键域中的键值的排序次序存储。合并处理程序830也能够执行1路合并,其中单个游程820的排序记录被合并到下一个合并级别上的游程820中。例如,在合并级别850A仅具有单个游程820A的情况下,合并处理程序830能够将合并级别850A上的第一游程820A合并到第二合并级别850B上的第一游程820A中。

在一些实现方式中,合并处理程序830能够将多个游程820添加到同一合并级别850上。例如,合并处理程序830能够开始将游程820A和820B合并到合并级别850A上的游程中。在合并中间,合并处理程序830能够添加游程830C,将为双路合并的东西调谐成三路合并,全部到合并级别850A上的相同游程中。合并处理程序830能够使用合并算法例如合并排序或外部合并排序来合并一个或多个游程。在一些实施例中,游程820被作为排序b树存储在存储815上。在此示例中,合并处理程序830能够使用外部合并排序算法来将游程820A和820B组合成合并级别850A上的单个排序b树。尽管本公开已描述了游程被按次序合并(例如,将820A和820B合并到合并级别850A上),但是合并处理程序830合并能够根据游程的任何次序或排列发生,并且可以将结果操作存储在存储815上的存储器的任何区域中的数据库845的任何合并级别上。

随着至少一个游程820的合并被执行,在数据处理系统805上执行的合并跟踪器835能够使用用于合并级别850的合并索引来跟踪由合并处理程序830对合并级别850执行的每个合并的进度。合并索引能够引用由合并处理程序830访问的当前数据记录的键值以确定与键域有关的合并操作的进度。在一些实现方式中,合并跟踪器835能够维护计数器以跟踪对于在由合并处理程序830进行的合并操作中添加的每个键值递增的合并。合并跟踪器835能够将一个或多个游程820之间的合并跟踪到合并级别850上。合并跟踪器835也能够跟踪在合并级别850中的任一个上的游程中的任一个之间的合并。例如,合并跟踪器能够用第一关联的合并索引将游程820A和820B之间的合并跟踪到合并级别850A的对应游程中。合并跟踪器能够用第二关联的合并索引并发地将合并级别850A上的一个或多个游程之间的合并跟踪到合并级别850B的对应游程中,依此类推。

当合并由合并处理程序830执行并由合并跟踪器835跟踪时,游程生成器825能够在存储815中并发地建立另一游程820。例如,合并处理程序830可以开始将第一游程820A和第二游程820B合并到数据库845中的第一合并级别850A中,同时使用新传入的记录来建立第三游程820C。合并能够由合并跟踪器835使用合并索引来跟踪。附加地,合并处理程序830可能正在跨越其他合并级别850执行合并,同时每个合并由合并跟踪器835用相应的合并索引跟踪。在发生这些并发合并的同时,游程生成器825也能够并发地接收数据记录并在存储815中的缓冲器中生成新游程,在此示例中为游程820C。

类似于合并跟踪器835使用合并索引来跟踪每个游程820的合并操作的进度,游程生成器825能够使用游程索引来跟踪游程820的建立的进度。游程生成器825也可以基于与键域有关的当前数据记录的键值来确定游程索引。例如,第一游程820A能够具有由游程生成器建立或接收的预定大小。游程生成器825能够从数据获取源855接收数据记录以得到每个数据记录,并且更新游程索引以反映游程的建立的进度。游程索引能够用于确定有多少个数据记录存在于游程中。游程索引也能够用于确定能够以与合并索引类似的方式发生合并操作的条件。

合并跟踪器835能够确定用于游程820的合并索引是否满足针对合并级别850的分位点条件(在本文中有时称为分位点、合并条件或切换条件)集中的一个。每个分位点条件能够为跟踪一个游程820到合并级别850的合并的合并索引指定对应值,在该对应值下将触发将记录从另一游程820添加到同一合并级别850上。在一些实现方式中,能够在键域之上定义分位点条件集。能够将每个分位点条件设定或定义成划分键域以使游程820中的记录的数目均匀地分布。例如,如果键域是范围从-200℃到2000℃的温度的范围,则能够在-100℃、0℃、100℃等处在键域内以均匀间隔定义分位点条件集。在一些实现方式中,能够将每个条件设定或定义成按任何其他分布划分键域。分位点条件也能够指定、指示或对应于合并到合并级别850中以触发从另一游程820添加记录的一个游程820的记录的数目。在一些实现方式中,能够基于每个游程820中的记录的数目来定义分位点条件集。例如,如果在每个游程820中有100个记录,则分位点条件集可以为25、50、75和100的合并索引值。也能够将分位点条件集定义成按任何其他分布划分每个游程820中的记录的数目。在一些实现方式中,可以在游程820的建立或合并的执行之前预先确定或固定分位点条件。在一些实现方式中,可以动态地确定分位点条件。

在一些实现方式中,合并跟踪器835能够使用任何数目的因素来确定对照来比较合并索引或游程索引的分位点条件。在一些实现方式中,合并跟踪器835能够通过确定转接键值来确定分位点条件。转接键值可以是使合并索引满足分位点条件的键值。在一些实现方式中,当合并索引等于转接键值时,它满足分位点条件。可以使用基于数据库845的合并带宽的带宽偏移来确定转接键值。数据库845能够具有指示可以添加新条目的速率的带宽。合并跟踪器835能够基于数据库845的带宽偏移来修改、调整或以其他方式设定转接键。

游程确定器825也能够在确定用于将游程820合并到合并级别850的一个或多个分位点条件时在一个或多个数据记录中标识键值在键域之上的分布。例如,游程生成器可以通过使用在特定数据记录集中接收到的最大键值和最小键值来确定特定键域中的最大键值和最小键值。使用键值的分布,游程生成器825能够确定可以用于组织合并操作的排程的一个或多个分位点条件。例如,游程生成器825可以标识键域中的键值范围是从0到999。在此示例中,游程生成器825能够基于后续合并级别的扇入(例如,当前游程级别上有多少个游程应该被合并到后续合并级别上的单个游程中)确定分位点条件。如果在此示例中合并扇入为四,则游程生成器可以将分位点条件确定为249、499、749和999。

游程生成器825也能够标识能够在存储815上建立游程820的速率。例如,建立游程820的速率可能受到游程生成器825能够将数据记录排序到对应游程中的速度限制。建立游程820的速率可能受到将数据记录排序到对应游程中所需要的计算努力限制。基于能够建立游程的速率,游程生成器825能够设定确定可以将记录合并到数据库845上的合并级别850中的一个上的速率的带宽。该带宽能够用于如以上所讨论的那样确定分位点条件。

合并跟踪器835能够确定合并索引不满足分位点条件中的任一个。当确定合并索引不满足分位点条件时,合并跟踪器835能够继续跟踪一个游程820到合并级别850上的合并。相反地,合并跟踪器835能够确定合并索引满足分位点条件中的一个。例如,如果合并处理程序正在执行合并级别850A上的游程820A到合并级别850B上的游程820A的单路合并,则合并跟踪器835能够跟踪合并的进度并且将合并索引与分位点条件进行比较。如果合并索引达到分位点条件,例如,合并索引等于预定值,则合并跟踪器835能够使合并处理程序830将合并级别850A上的另一个游程820B添加到单路合并以发起双路合并。在添加之后,合并跟踪器835能够继续跟踪游程820的合并的合并索引直到在满足连续分位点条件之后已完成游程820的合并为止。

当确定合并索引满足分位点条件时,合并跟踪器835能够发起将另一游程820添加到合并级别850以执行多路合并。合并跟踪器835能够标识要添加到合并级别850的游程820的子集。在一些实现方式中,合并跟踪器835能够确定游程820中满足分位点条件的数据记录的子集。确定数据记录的子集能够包括将数据记录中的键值与分位点条件进行比较。当数据记录中的键值大于分位点条件时,那么可以将这些数据记录添加到子集。例如,分位点条件可以对应于50℃的温度,合并跟踪器835能够将温度值超过50℃的数据记录的子集标识合并级别850。合并跟踪器845也可以基于合并索引标识子集。例如,数据记录的子集可以是在缓冲器中处于大于合并索引的位置中的任何数据记录。

继续此示例,如果达到第二分位点条件,则合并跟踪器835能够标识第三游程830C中满足第二分位点条件的记录的第二子集。响应于对记录的第二子集的标识,合并跟踪器835然后能够发起将所标识的游程820C的第二子集添加到820A和830B的合并以创建三路合并。合并跟踪器835能够在存在足够数目的分位点条件和发起多达N路合并的游程820A-N的情况下继续此过程,其中N在这种情况下是存储815中的游程的数目。合并跟踪器835也能够对数据库845中的任何合并级别850的游程执行此过程。

在一些实现方式中,合并跟踪器835能够确定游程索引已满足分位点条件。当游程索引已组装了游程820中超过阈值的许多键值时,它能够满足分位点条件。在一些实现方式中,当相应的合并级别850的游程索引满足分位点条件时,合并处理程序830能够将合并级别850的游程820添加到现有合并。例如,游程820A的单路合并正在合并级别850A上到合并级别850B上的游程820A中。当游程生成器825确定游程820B满足分位点条件时,合并处理程序830能够将合并级别850A上的第二游程820B添加到单路合并。合并跟踪器835也能够基于键域中的键值的分布确定一个或多个分位点条件。

在一些实现方式中,合并跟踪器835能够在执行合并的同时确定是否将游程820中的所有数据记录都添加到数据库845中的合并级别850。例如,合并跟踪器835能够确定第一游程820A与第二游程820B之间的合并的合并索引等于键域中的最大值。在此示例中,因为合并遍及键域从最小键值向最大键值进行,所以此条件将指示游程820A中的所有键值都已被合并到存在于数据库845上的合并级别850A中的游程中。因为具有不止一个游程820的合并是响应于合并索引被确定为等于分位点条件而发起的并且在合并索引处将附加游程添加到合并,所以在游程820B中可能存在尚未被合并到数据库845中的合并级别850A上的游程中的数据记录。在确定第一游程820的记录的合并未被全部添加的情况下,合并跟踪器835能够跟踪合并直到合并索引达到分位点条件或者合并被确定为完成为止。

在确定第一游程820的记录的合并被全部添加到第一合并级别850A的情况下,合并跟踪器835能够释放包含游程820A的存储815中的缓冲器以接收用于附加游程820的数据记录。例如,游程820A可以占据存储815中的一定量的空间,并且存储可以是有限的。在这种情况下,因为数据记录也存在于数据库845中的合并级别850A中的合并游程中,所以使数据记录保持在存储815中现在是冗余的。合并跟踪器835能够释放在存储815上由游程820A占据的存储器的区域。

在一些实现方式中,合并跟踪器835能够确定在数据库845上合并合并级别850是否完成。例如,合并跟踪器835能够跟踪第一游程820A中的记录和第二游程820B中的记录的子集到第一合并级别850上的合并。在此示例中,当合并的合并索引已达到最大键值,合并跟踪器835可以确定合并完成。在一些实现方式中,合并跟踪器可以确定游程820A中的所有数据记录都已被合并到数据库845上的合并级别850A中的第一游程中。当确定合并未完成时,合并跟踪器835能够跟踪合并直到合并索引满足分位点条件或者确定合并完成为止。

当确定合并完成时,合并跟踪器能够开始将第二游程820B中的数据记录的剩余子集从键域的最小键值合并到数据库845上的合并级别850B中的第二游程中。合并能够由合并处理程序830在每个合并级别850下通过将从先前合并留下的数据记录连续地合并到下一个合并级别的附加游程中而维护在稳定状态下。在一些实现方式中,合并处理程序835能够初始化数据库845上的另一合并级别850B上的另一游程820。合并处理程序835能够开始将游程820B中的剩余数据记录合并到数据库845上的合并级别850A中的第二游程中。在一些实现方式中,如上所述,合并处理程序835开始从最小键值起合并剩余数据记录。

查询处理程序840能够接收对在数据库845上维护的一个或多个记录的查询。查询可以由经由网络810连接的计算设备生成和传送。在一些实现方式中,查询处理程序840能够经由过网络810接收查询。查询可以是对一个或多个数据记录的请求,并且能够包括标识特定键值的信息。在一些实现方式中,查询能够包括对具有特定范围的键值的所有数据记录的请求。例如,查询处理程序840可以接收对于具有介于-50℃与-10℃之间的温度读数的所有数据记录的查询。查询处理程序840能够标识键域内满足查询中指定的条件的键值,并且开始搜索存储815和数据库845。

使用查询,查询处理程序840能够搜索在数据库845上维护的合并级别850中的至少一个。在一些实现方式中,查询处理程序840能够使用查询来在存储815上搜索游程820中的至少一个。搜索能够与游程820的建立以及游程820到合并级别850上的合并并发地发生。使用查询搜索的合并级别850能够包括来自一个或多个游程820(例如,来自先前合并级别850)的数据记录。合并到合并级别850上的数据记录的数目可以取决于分位点条件。例如,对于双路合并,可以将来自第一游程820A的所有记录包括在合并级别850中而可以将来自第二游程820B的记录的子集包括在合并级别850中。

在执行搜索时,查询处理程序840能够标识合并级别850中的至少一个。在一些实现方式中,查询处理程序840能够标识被确定为完成的合并级别850中的至少一个。以这种方式,查询处理程序840能够避免搜索具有未完成合并或未结束游程820的合并级别850,从而减少执行的搜索次数。由查询处理程序840标识的合并级别850可以对应于最近完成的合并。利用对合并级别850的标识,查询处理程序840能够标识所标识的合并级别850中的与查询匹配的数据记录。在一些实现方式中,查询处理程序840能够标识与由查询指定的键值匹配的数据记录。例如,查询处理程序840能够如查询中所请求的那样找到温度读数介于-50℃与-10℃之间的数据记录。在一些实现方式中,查询处理程序840能够确定与由查询指定的键值匹配的数据记录是否存在于数据库845上。

基于标识,查询处理程序840能够基于使用查询的搜索来生成响应。在一些实现方式中,查询处理程序840能够将与查询匹配的数据记录包括到响应中。在一些实现方式中,查询处理程序840能够包括指定数据库845是否在响应中包含与查询匹配的任何记录的指示。利用生成,查询处理程序840能够经由网络810将响应传送到发送了查询的计算设备。

步调良好的交错合并

上文描述了以交错方式将游程添加到合并。合并可以是一次又一次地遍历键域的连续合并、以分位点键值添加游程并且在遍及键域一个完整循环之后丢掉它们。对于合并扇入F,所期望的分位点键值可以为1/F分位点、2/F分位点等。合并每循环产生一个输出游程,当从+∞和-∞重绕时切换到下一个输出游程。能够估计分位点并且能够以在旧估计的分位点键值与新估计的分位点键值之间以F-1或F+1个输入游程临时运行合并步骤为代价调整估计值。

理想地,合并通过键域进行,使得当游程产生者例如游程生成结束其下一个输出游程时合并到达下一个分位点。在那种情况下,每个新游程紧接在它完成之后加入合并步骤。合并步骤通过键域继续其进度,所以新添加的游程以适当的分位点键值加入。

在合并级别的初始化期间,合并扇入建立,游程生成一结束其第一游程就作为“单路合并”开始,在游程生成结束其第二游程时变为二进制(2路)合并等。当游程生成结束其第F个游程时,诸如当合并模式开始其第一合并步骤时,它变为全F路合并。随着游程在每个分位点退出和进入合并逻辑,合并在合并级别的初始化之后仍保持稳定的F路合并。在初始化期间,合并带宽可以与其当前合并扇入成比例。

开始第三游程

现在参考图9A,描绘的是在合并级别的初始化期间的时间点。写入器920例如游程生成最近已结束了第二游程820B并已开始了第三游程820C。当那个发生时,读取器915例如合并级别0游程820以创建第一级别1游程925A变为二进制合并。在此示例中,合并索引905最近已越过分位点条件910A。在此事件之前,读取器915A正在执行单路合并,将第一数据游程820A的记录组装到合并级别1 850A的第一级别1游程925A的第一区域940A中。在合并索引905超过分位点条件915B之后,读取器915B开始从合并索引开始合并游程820A和820B二者。注意在此阶段,这使820B中的数据记录的子集保持未合并。820A和820B的双路合并的结果也被添加到级别1游程925A。表示双路合并的结果的925A的段被强调为940B。

在图8的上下文中,合并处理程序830能够执行使用第一游程820A的记录到第一合并级别850A上的第一合并915A。合并跟踪器835能够维护合并索引905,并且确定它是否已达到分位点条件910A。当它这样做时,合并处理程序830能够将第二游程820B添加到合并915A从而创建双路合并915B。第二合并的结果在合并级别850A中的游程925A中被维护在数据库845中。

合并跟踪器835能够使用合并索引905来跟踪第一合并915A。例如,合并跟踪器835能够通过确定合并索引905的键值来连续地跟踪第一合并915A的进度。如果键值满足分位点条件910A,则合并处理程序830能够将第二游程820B添加到合并915B。所得合并被存储在游程925A中的合并级别850A中,其中940A指示游程925A的与单路合并相对应的部分而940B指示游程925A的与双路合并相对应的部分。

游程生成器825能够将游程920写入到数据处理系统805的存储815中。游程生成器825能够与合并操作915A-B并发地写入游程920。在正在游程820A和820B之间发生双路合并时,正在生成第三游程820C并且将其存储在存储815中的对应缓冲器中。

结束第三游程

图9B示出在合并级别的初始化期间的稍后的时间点。写入器920即将结束其第三游程并且读取器即将将2路合并扩大成3路合并。

合并级别850A的第一游程925A现在包括第一多个数据记录940A以及第一和第二多个数据记录940B的合并。在此阶段,游程生成器825可能即将完成组装第三游程820C。由合并跟踪器835跟踪的合并索引905也可能即将达到另一分位点条件。当合并索引满足分位点条件并且游程820C可以完成时,合并处理程序830能够将第三游程820C添加到双路合并以创建三路合并。

开始第四游程

图9C示出在合并级别的初始化期间的另一时间点。当写入器结束了第三游程并开始了第四游程时,写入器将2路合并扩大成3路合并。

合并跟踪器835可能已检测到合并索引已满足第二分位点条件910B,并且游程生成器825已完成第三游程820C的生成。结果,已用读取器915C将第三游程添加到合并操作。合并级别845A现在进一步包括分别对第一、第二和第三多个数据记录940A-C的合并。并发地,游程生成器825开始通过将游程820D写入920到数据处理系统805上的存储815来组装合并级别0的第四游程820D。

完成合并级别初始化

图9D示出合并级别初始化的完成,其中第一全输出游程925A已完成。在此阶段,整个合并级别0游程820A已被合并到下一个阶段中,但是游程820B和820C仍具有保持未合并的数据记录。此时,第二合并级别l游程925B的合并开始。合并处理程序830从键域的最小键值开始与游程820B进行单路合并,从而将数据记录写入到合并级别850A中的第二游程925B。

在第一全输出游程之后,合并级别被完全初始化。那时,下一个合并级别开始其初始化。因此,可以始终在初始化中存在一个合并级别。其他合并级别可以以等于游程生成的带宽运行。因此,用于游程的每个级别的临时存储量保持恒定(舍入除外)。当前在使用中的临时存储量能够被用作为合并级别定步调的手段,每当其输入的大小超过所分配的临时存储时,合并级别就应该以全带宽运行。

随着合并定步调为使得当准备添加另一输入游程时输入游程被丢掉(在全循环之后),查询在每个合并级别下找到F个完成的游程。任何查询能够涉及在每个合并级别上搜索F个分区,但仍在初始化中的最顶层级别除外。与合并和搜索策略相比每合并级别的F个游程表示3:2的改进,(例如,从平均1.5F到固定F)。

急切交错合并

步调良好的交错合并丢掉输入游程j并且同时且以相同键值添加输入游程j+F。为了得到最好性能,它取决于随着输入游程j+F完成达到输入游程j的转接键的合并。相比之下,无论输入游程j是否已被完全地合并,每当游程完成时急切交错合并添加游程j+F。输入游程j+F的转接键值由在先合并步骤的当前进度设置;它可能低于或大于输入游程j的转接键值。

在急切交错合并中,合并扇入随着时间的推移而在目标扇入F附近变化。数据摄取带宽和当前与目标扇入的分数f/F应该引导合并进度的步调。然而,如果用于合并输入的临时存储超过阈值,则合并应该以最大(不受约束)带宽继续进行。阈值应该等于F个游程加上某个公差,例如20%。

竞争交错合并

一种替代方法集中于作为线性分区b树的游程表示及其在存储器内索引中的键-指针对。在这里,假定可以为相同合并级别的游程形成链表,存储器内索引为每个级别中的最近游程保持键-指针对,并且级别指示符和游程编号将键-指针对扩展为四元组。对于级别指示符,游程生成产生级别0的游程等;并且游程编号简单地对曾经已存在于给定合并级别上的游程进行计数。

在这种数据和存储结构中,存储器内索引将和表示游程和分区的文件一样持久。这要求存储器内索引是事务性的,具有不仅由于游程生成和多个合并过程并发地修改它而导致的并发控制而且具有诸如日志记录和恢复的耐久性。在稍后的部分中公开了存储器内索引的并发控制、日志记录和恢复的细节。在这里省略数据内容的日志记录和恢复的细节,例如,何时何地记录或镜像数据内容。

游程生成递增地将数据记录从存储器内索引溢出到存储上分区,从而将最近级别0游程的现有键-指针对(或实际上四元组,参见上文)移动到当前级别0游程中并将当前级别0游程的键-指针对保留在存储器内索引中。一旦在存储器内索引中提交了新键-指针对,它及其数据内容就可用于查询;并且一旦将键-指针对从存储器内索引移动到存储上分区,查询就能够间接访问它。合并过程在它们产生新游程作为合并输出时做与游程生成相同的事情:增量溢出、将现有键-指针对从存储器内索引移动到合并输出中等。

竞争交错合并

图9E示出读取器与写入器之间的竞争。写入器在键值方面一领先于读取器,读取器就扩大合并扇入。在这里,写入器仍在第二游程上工作,但读取器已经将其合并扩大为2路合并。与图9A相比,二进制合并开始得更早,其中写入键值等待甚至更少直到被读取为止。

合并跟踪器830能够使用合并索引905来跟踪竞争合并,并且一达到目标分位点910A就开始双路合并。在竞争合并的情况下,双路合并915B在已完全地建立第二数据游程820B之前开始。这意味着随着游程生成器825生成游程820B,写入器920和读取915B能够“竞争”到游程的结束。合并的结果是合并级别850A中的游程925。游程925的单路合并部分被标记为940A,而游程925的双路合并部分被标记为940B。

查询相比于合并输入而优选合并输出,从而搜索一个地方而不是F个地方。基于存储器内索引的事务性更新,创建输入分区的逻辑一达到高于合并步骤的键范围,合并步骤(级别)就包括新输入分区。如果查询能够搜索下一个合并级别,则查询应当从不要搜索分区。注意,写入新分区应当花费为在合并步骤中将其作为F个输入中的一个读取F倍的时间;因此,写入器将最终赶上读取器,然后保持领先于它。合并逻辑借助于键-指针四元组中的游程编号来注意附加合并输入。

在随机时间点具有随机搜索键的查询具有它花时间来搜索F个合并输入的50%概率和它可能搜索合并输出的相等概率。因此,平均而言,查询涉及在每个合并级别上搜索F/2个分区。与合并和搜索策略相比,这是3:1的改进。

索引内容和维护

存储器内有序索引能够促进游程生成以及对存储上游程的管理。对于具有输入数据记录的游程生成,索引支持替换选择,因此初始游程为存储器的大小的两倍。这在稳定状态和随机输入下假定游程生成;一些存储器因由于可变大小记录而导致的存储器内分段而丢失,并且一些存储器被前面游程的键-指针对占据。

存储器内索引也保持到指向在每个合并级别下最近的游程的链表的锚。对于较高的合并级别及其非常大的游程,游程可以具有父或甚至通用级别,并且存储器内索引中的条目指向这些级别。这些最近的游程指向同一级别上的较早游程。

图10图示存储器内索引1010如何引用两个合并级别上的游程中的页。存在一个级别1游程1020和两个级别0游程1005A-B,同时第三游程1005C正在开始。最近的级别0游程1005B保存引用较旧的级别0游程1005A中的页的键-指针对。合并索引1015由合并跟踪器830跟踪。

当驱逐扫描在游程生成中前进时,最近的级别0游程的数据记录和键-指针对都被写入到当前的级别0游程;当前的级别0游程的键-指针对被保存在索引中。每当存储器填满时此过程就运行,从而酌情从键值+∞和-∞卷绕并在那些时间开始新的级别0游程。在下面覆盖针对索引的并发控制和恢复。

每个合并级别大多数独立于游程生成和其他合并级别前进。关系是每个级别在完成初始化之后处理约相同的数据体积,使得所需要的临时存储对于游程的每个级别保持恒定。

每个合并步骤去除合并输入的键-指针对并插入其合并输出的键-指针对。它也将键-指针对移动到合并输出中,即在合并输出的级别上最近的在先游程的键-指针对。因此,存储器内索引继续为每个级别中最近的游程保持键-指针对。

现在参考图11,描绘的是用于通过执行交错合并来维护键值存储的方法1100的流程图。能够使用本文在上面结合图8详述的数据处理系统805或本文在下面结合图12描述的计算机系统1200来实现或执行方法1100。在简要概述中,数据处理系统能够接收数据记录(1105)。数据处理系统能够建立数据记录的排序游程(1110)。数据处理系统可以开始合并操作(1115)。数据处理系统能够跟踪一个或多个合并操作的进度(1120)。数据处理系统能够确定合并索引是否满足分位点条件(1125)。数据处理系统能够将另一排序数据游程添加到合并(1130)。

数据处理系统(例如,数据处理系统805)能够接收数据记录(1105)。数据记录能够包括与键域相对应的一个或多个键值。键域能够具有最小值和最大值。能够在方法的执行中自始至终连续地接收数据记录。能够例如经由网络810接收数据记录。还能够直接从数据获取源例如数据获取源855接收数据记录。方法还能够将与键值接收的时间相对应的键值添加到每个数据记录。

数据处理系统能够建立游程(1110)。数据处理系统能够从在(1105)中接收到的数据记录建立排序游程(例如,游程820)。能够按键值索引游程。例如,建立游程可以包括用在步骤1105中接收到的数据记录建立b树或b树数据结构的变体。能够通过索引存在于数据记录中的一个或多个键值并将它们插入到排序数据结构中来建立游程。也能够通过将每个数据记录插入到数据结构中、然后对该数据结构执行排序算法来建立游程。游程能够例如由游程生成器825建立。

数据处理系统能够开始合并操作(1115)。数据处理系统可以从所建立的一个或多个游程开始合并操作。合并操作能够为后续合并级别生成游程。合并操作能够从最小键值开始并且进行到键域中的最大键值。能够将合并的所得游程插入到数据库上的合并级别例如数据库的合并级别中。合并的所得游程能够包括在合并操作中使用的一个或多个游程中的所有数据记录。

数据处理系统能够跟踪合并操作(1120)。数据处理系统能够使用合并索引来跟踪合并操作的进度。合并索引能够跟踪合并操作的当前键值。数据处理系统能够通过将合并的当前键值与合并级别的键域进行比较来跟踪合并。数据处理系统也能够通过对已被合并到下一个合并级别中的记录的数目进行计数来跟踪合并。

数据处理系统能够确定合并索引是否满足分位点条件(1125)。数据处理系统能够将合并索引与分位点条件进行比较。分位点可以是某些键值,并且能够被预先确定或动态地确定。例如,如果合并索引等于键值,则已满足分位点条件。分位点条件也可以是许多合并的数据记录。例如,如果合并的数据记录的数目超过某个阈值,则合并索引满足分位点条件。如果确定合并索引不满足分位点条件,则数据处理系统能够重复(1120)的功能性。

如果确定合并索引满足分位点条件,则数据处理系统能够将数据记录的第二排序游程(例如,第二游程815B)添加到合并(1130)。数据处理系统能够将所建立的第二数据游程添加到合并中,从而在当前合并索引处开始双路合并,并且继续合并直到合并完成为止。数据处理系统能够继续向合并添加游程直到合并级别达到稳定状态为止。当数据记录可用于合并的速率等于合并数据记录的速率时,合并级别处于稳定状态。

这些插入应该随着合并进行而递增,从而在合并进度的开销和低等待时间递增统计之间取得平衡。当在合并输出中提交键范围时,新边界键(作为键-指针对)对于较低的键值指向新合并输出,而对于较高的键指向在前游程;此外,对于合并输入的级别上的游程,相同的键值将对于较低的键值指向在合并输入之前的游程,而对于较高的键值指向剩余的合并输入。再次,在下面讨论用于协调活动查询、将来查询等的并发控制。

大块删除

“范围删除”是已经包括在针对日志结构合并树的原始设计中的强大功能。这能够被概括成添加在查询优化中称作“可密封谓词”的扫描谓词。

特殊“范围删除”记录指定键范围以及任选地扫描谓词。它在该键范围中的有效记录之前“排序”。合并步骤应用范围删除并抑制合并输出中的范围删除记录。在一些情形下,可能要求单个“范围删除”记录拆分成具有互补键范围的多个此类记录。例如,如果合并步骤处理有限键范围并且如果该键范围在范围删除结束之前结束,则剩余键范围需要它自己的“范围删除”记录。稍后的部分覆盖在快照隔离和多版本存储的上下文中的删除范围。

存储空间回收

在合并步骤将数据从其输入游程(分区)拷贝到其输出游程(分区)之后,能够擦除输入数据并释放存储空间。然而,那有两个困难。首先,空间回收可以以页(或页组)的粒度进行;并且第二,虽然某个活动查询执行计划仍依靠输入分区中的一个,但是可能不释放该空间。第二关注是并发控制之一并且在稍后的部分中被解决。在这里提及快照隔离和多版本并发控制就足够了。在这里讨论第一关注。

存储页在它被擦除到最后指针时准备好释放。如果存在例如来自后续分区中的多个数据页的多个指针,则这些指针中的最右边指针很重要(在合并步骤通过键域从左向右进行的意义上)。换句话说,如果页指针在数据页中被擦除并且该同一数据页包含到下一个数据页的另一指针,则第一指针及其引用的数据页将变陈旧并且能够将该页回收为自由空间。

当数据页被回收时,它包含的页指针被擦除。除最右边的所有那些页指针都是到在前分区中的引用数据页的最右边指针;因此,那些数据页也被擦除。如果那些数据页本身包含页指针,则相同逻辑一直应用于合并级别的最旧游程(分区)。以这种方式,合并级别内的最近游程(分区)中的数据页的回收可以传播通过整个合并级别,通过同一合并级别中的所有游程。

存储器内索引中的页指针工作稍微不同但意图相同。如果合并步骤在存储器内索引中的键-指针对之上进行,则在前键-指针对变陈旧并且基础页可以被逻辑上删除,经受针对存储器内索引中的键-指针对的多版本并发控制。当逻辑删除变为物理删除并且存储器中的键-指针对被擦除时,然后能够回收基础存储页。该存储页的回收也可能遵循上述逻辑回收在前分区中的数据页。LRU缓冲池策略应该在此过程期间避免所有I/O。

为了正确应用范围删除,应该重复“范围删除”记录作为每个受影响索引节点中的第一键值,包括其时间戳。这在存储器内索引中开始并且合并步骤将“范围删除”记录带到其输出中的每个受影响索引节点并对其重复“范围删除”记录。查询查找“范围删除”记录并在它们自己的构造查询结果的合并逻辑中应用它们。

交错合并的概述

在交错合并的概述中,可以将线性分区b树用作用于高效合并和搜索的存储结构。存储器内有序索引可以保持数据和键-指针对(实际上为四元组)两者;临时存储上的数据能够采用允许直接页访问的任何存储结构,并且对于增量空间回收,可以使用逐页释放。交错合并与用于日志结构合并树的其他设计比消耗少得多的临时存储空间,并且对于给定合并扇入,它允许快得多的查询。

模式变化

存在各式各样可能的模式变化。在这里重要的是需要数据移动的模式操作与不需要数据移动的模式操作之间的区别。前者的示例是索引创建;后者的示例是丢掉完整性约束。此部分覆盖用于模式变化的数据移动的机制并忽略所有其他方面。

索引创建

索引创建可以涉及以日志结构合并树的形式创建新次级索引。b树索引的高效创建需要扫描数据源以提取新索引条目、对它们进行排序并且在将索引条目附加在叶节点上的同时构造分支节点。在这里,不需要排序;替代地,以随机次序插入新索引条目并且日志结构合并树中的逻辑确保高效的存储器内游程生成、合并游程、分支节点的创建和维护等。

一旦定义了新索引并确认了其存在,到数据库表中的所有将来的插入都插入适当新索引条目,就像它们会针对较旧的次级索引一样。为了用表中旧行的条目回填新索引,一个人能够扫描表或者一个人能够向表中的后续合并步骤添加副作用。表扫描可以将所有分区包括在其日志结构合并树内。

在这里省略用于从多个合并步骤得到正确的索引条目集的逻辑的细节。注意,如果所有新索引条目都来自合并步骤,则直到索引完成的延迟可以是相当大的。

新次级索引在其内容完成时变得可被查询执行利用。只要插入继续到基础表中,合并其分区就将继续。

索引去除

如以上所讨论的,用于索引去除的主要技术是范围删除。详情取决于已去除的索引如何适合日志结构合并树。如果已去除的索引与其他索引级联(例如,以最终排序次序已去除的索引表示连续键范围),则范围删除记录指定键范围。另一方面,如果已去除的索引与合并索引中的其他索引交错,则范围删除记录指定相当于合并索引的范围加上相当于已去除的索引的扫描谓词。

汇总创建和去除

汇总是由带有“按组”子句但没有加入的查询所定义的物化视图;汇总在能够在没有嵌套查询的情况下一次一行评估谓词的情况下可以具有选择。汇总被存储在初级索引中并且它可以具有次级索引。

这些索引的创建和去除,包括汇总在其初级索引中的物化,工作非常像如以上所讨论的表的索引创建和去除。

重新分区

重新分区的主要工作是数据移动。它可以作为删除和插入被实现。问题的一部分是插入需要扫描,但是这也是机会:扫描能够将删除实现为副作用。此外,扫描和删除可以是合并步骤的副作用。换句话说,所期望的是像“删除成”操作一样的东西,该操作扫描、删除并产生能够被重新分区然后馈给插入逻辑的输出流。插入使用具有游程生成和多个合并级别的标准插入逻辑来处理,好像这些记录是全新的信息一样。

模式变化的概述

总之,可以将需要数据移动的模式变化映射到扫描加上新索引“大块删除”条目的插入或适当的反问题。这些插入可以非常像由应用捕获的新数据记录一样经过存储器内游程生成和多级别合并。

操作

本部分覆盖包括初级索引和次级索引的同步、并发控制、日志记录和恢复的操作。当游程生成和合并将其所有活动记录在存储器内索引中时,并发控制、日志记录和恢复全部集中于存储器内索引或实际上键-指针对。暗示了对数据记录的并发控制(所有分区一旦被写入就是只读的),并且分区内容的恢复依靠在提交它们之前将其数据页强制到存储。

初级索引和次级索引的同步

存在使初级索引和次级索引同步的两个方面。首先,它们寻求包含相同的逻辑行,并且因此在每个事务之后,应该包含相同数目的索引条目。第二,在日志结构合并树的上下文中,从次级索引中的条目导航到表的初级索引中的对应条目应该是简单且高效的。

通过从输入流中的每行为每个索引创建一个索引条目来覆盖第一问题。这包括用于逻辑更新的替换条目和用于逻辑删除的墓碑条目。

能够通过使表的初级索引和次级索引的合并步骤同步来解决第二问题。虽然更复杂的设计是可能的,但是按照合并索引的精神将表的初级索引和所有次级索引放置到同一日志结构合并树中似乎已足够,其中索引标识符作为每个索引条目中的人工前导键字段。在这种情况下,合并步骤始终平等地影响所有索引。实际上,单个日志结构合并树可以保持多个相关表及其所有索引。通过对K个表和索引进行log

迟到达

迟到达是流处理和流索引中一个臭名昭著的问题。对于大多数数据项,在事件时间(也称为用户时间或现实世界时间戳)与到达时间(也称为系统时间和捕获时间戳)之间存在高相关性(和小差异)。迟到达是打破在事件时间与到达时间之间有大差异的相关性的例外。

如果用b树索引的表的列与另一列具有高相关性,则用另一列的键范围扩增b树中的每个父到子指针为该另一列创建非常有效的索引。这与关注表中所有列的最小值和最大值的区图(和其他小物化聚合体)有关。集成到b树结构中自然创建其分层变体。另一个明显变体省略与索引列的相关性弱的列的最小值和最大值。对于仅具有相等谓词的关系键和其他列,位向量过滤器可以替换或扩增最小值和最大值。除了最小值、最大值和位向量过滤器之外,区过滤器也允许第二至最小键值和第二至最大键值应付强异常值。

日志结构合并树也能够从区过滤器中受益。利用格式化为分区b树的日志结构合并树,在游程表示关于到达时间的分区情况下,并且在事件时间戳与到达时间戳之间有高相关性情况下,最小值和最大值允许对事件时间进行高效搜索。如果迟到达足够罕见,则事件时间戳的第二至最小值允许在索引结构中嵌入非常锐的过滤器。

这适用于任何索引和任何属性;相关性与分区属性(例如,捕获时间戳)而不索引属性相关。例如,web服务可以使用由分区b树表示的日志结构合并树来在用户标识符上索引其日志。附加到此b树内的每个父到子指针的区过滤器可以指示事件时间戳的范围。这些区过滤器对于父到子指针很可能无效,并且可以被省略。然而,在父到子指针在到达时间戳中使分区分离并因此使键范围分离的情况下,最小值和最大值按事件时间戳加快搜索。如果在web日志记录当中存在迟到达(例如,特别低的事件时间戳),则最小值可以是欺骗性的,然而附加到父到子指针的第二至最小值非常精确地引导任何将来的搜索。

按索引和按键范围进行自适应合并

分区b树中的自适应合并扫描并删除多个游程中的键范围并且将这些索引条目合并到较高级别的游程中。它通常但不一定是查询执行的副作用。键范围可以遵循查询谓词,但是不一定。例如,在许多索引级联的合并索引中,合并步骤可以集中于那些索引中的一个。在那种情况下,索引标识符是在分区标识符之后的前导键字段并且索引标识符上的相等谓词界定自适应合并步骤。

一个问题是针对具体键范围的自适应合并使严格地从左向右合并的假定无效。因此,起始键值需要在存储器内索引内特别注意协调日志结构合并树中的所有合并和搜索活动。在日志结构合并树的键域内,自适应合并步骤的起始键值在存储器内索引中需要新键-指针对。如果自适应合并步骤从所有游程中提取并删除索引条目,则新键-指针对包含空指针;否则,它指向自适应合并步骤中未包括的最近的游程。在存储空间回收中,引用较旧的游程的键-指针对允许释放由较低的键值引用的页。

在除了初级索引之外具有次级索引的表或视图中,在单个索引内按键范围合并破坏初级索引和次级索引中的分区之间的一对一映射。在那些情况下,查询可能试图通过访问匹配分区来解析行指针,然后视需要转向较大的分区(例如,合并输出)。

并发控制

游程生成和合并修改游程文件及其在存储器内索引中的条目,然而相同的存储器内索引引导检查相同分区的查询;因此,将执行某种并发控制。幸运的是,并发控制集中于存储器内索引;游程或分区一旦被写入就保持只读直到被删除为止。

存储器内索引保持每个合并级别上最近的游程的键-指针对以及用于游程生成的数据记录两者。这些数据记录被用于游程生成;除协调线程以保护存储器内数据结构的低级并发控制外不需要并发控制。键-指针对可能需要事务性并发控制。具有两个存储器内索引,一个用于数据记录且一个用于键-指针对,可能似乎是一个好主意,但是那种设计需要棘手的合并和存储器管理逻辑以便实现所有期望的功能性又始终利用所有存储器。

在查询执行计划结束其工作同时合并步骤根据其合并进度替换键-指针对情况下,存储器内索引需要对于只读查询具有快照隔离的多版本并发控制、在合并步骤中锁定索引更新以及在条目变陈旧时进行垃圾收集。

在数据库索引中,删除事务将有效的索引条目变成重像(也称为伪删除记录)并且在重像索引条目上保留空间和锁两者。后续插入事务可以通过调用系统事务(也称为嵌套顶级动作)来擦除未锁定的重像。在具有多版本记录的存储结构中,重像是在最旧的活动只读事务之前提交了删除或替换的版本记录;当所有在前版本记录都消失并且墓碑被解锁和提交时,墓碑记录就是重像。到存储器内索引中的插入无论是数据记录还是键-指针对,都通过调用系统事务以进行重像去除来执行所需要的垃圾收集。

恢复

对于分区文件的内容(例如,数据记录),游程生成和合并步骤刷新完成的游程和甚至其输出游程内完成的键范围。这包括引用在前分区的所有键-指针对以及附加到这些键-指针对的任何区过滤器。这里的技术通过存储器内索引中的键-指针对的可靠事务恢复来应用于游程的管理。

似乎逻辑预写日志记录能够提供从所有故障(除日志故障以外)中恢复所需要的信息和可靠性。利用对日志记录的合适的组织,例如,恢复日志中的日志记录和日志存档中的部分地排序的日志记录的向后链,所有形式的即时恢复都是可能的,包括单页修复、即时重新启动、单阶段还原、即时还原、即时故障转移等。所有这些技术都依靠按需逐页还原和按需逐事务回滚。

逻辑恢复意味着数据库页标识符没有作用或意义;替代地,逻辑恢复集中于附加到唯一键值的版本号。日志记录按唯一键值包含向后链并且检查点日志记录包含可能脏的(未写入)唯一键值的列表。相当于刷新脏页是写入唯一键值和所有关联的信息。

日志记录

预写日志记录可能是存储器内索引中的影响键-指针对、其索引值及其在索引中的放置的变化所需要的。逻辑日志记录和恢复为这样的存储器内数据库最好地服务。利用逻辑日志记录和恢复,在系统故障(因存储器丢失而导致)之后重新启动创建包含键-指针对的新存储器内索引,准确地它们在故障之前已被提交。因此,所有合并级别的游程保持可访问。用于存储上游程的存储逻辑可以去除未提交的部分游程和键范围。

替代设计包括日志记录和恢复中的数据记录和存储上游程,其优点是针对所有恢复的单代码库和统一保证,但缺点是日志体积和数据体积一样高(或者甚至稍微更高)。

操作的概述

总之,所提出的用于日志结构合并树的技术,包括存储器内索引和交错合并算法承诺极好的操作特性。除了合并带宽和查询等待时间之外,它们还承诺稳定连续的操作而没有性能陡崖,支持冗余次级索引和物化分组视图或汇总以及对于对查询性能影响最小或中等的迟到达的容忍度。可能最重要的是,用于并发控制、日志记录和恢复的被证明技术能够向中央数据结构、存储器内索引以及所有游程和分区提供并发性、可靠性和可用性。

对于物理恢复,日志记录是指数据库页和字节偏移;对于“生理”恢复,日志记录是指数据库页和槽号;对于逻辑恢复,日志记录是指索引和唯一键值;而对于语义恢复,日志记录是指表和主键。可以在数据库系统中并以镜像的形式使用物理恢复,并且可以在许多文件系统中使用物理恢复;生理恢复一直是数据库中的默认选择;逻辑恢复能够在包括没有页的存储装置和存储器的完全不同的设备上还原数据库;并且语义恢复能够出于不同目的还原数据库,例如,事务处理对查询处理在诸如分区、索引选择和压缩的物理数据库设计方面具有不同的选择。语义日志记录和恢复在通过日志运送进行复制的上下文中特别有用,所述日志运送包括带有选择谓词的日志运送。逻辑恢复集中于附加到唯一键值的版本号。日志记录按唯一键值包含向后链并且检查点日志记录包含可能脏的(未写入)唯一键值的列表。相当于刷新脏页是写入唯一键值和所有关联的信息。用于逻辑恢复的日志存档按键值对日志记录进行排序。

介绍的示例

对于介绍的示例,新数据结构和算法实现合并性能与搜索性能(例如,合并带宽与搜索等待时间)之间的新平衡。差异是搜索努力在不影响合并努力的情况下缩小了2倍。或者,合并扇入能够在不影响搜索努力的情况下增长2倍。

表2示出针对扇入和合并级别的最新可用的选择。利用相同的合并努力(例如,6个级别),与表1相比搜索努力被消减至三分之一(从54个分区到18个分区)。利用相同的搜索努力(例如,54个分区),合并努力被消减至一半(从6个合并级别到3个合并级别)。平衡的选择需要两倍的最佳合并努力(4对2个合并级别)和两倍的最佳搜索努力(30对15个分区)。这也是表2中的接近最佳选择。与表1中的接近最佳选择相比,这些技术采用大21/2倍的合并扇入(在表1中为6对在表2中为15),并且如摘要中所承诺的那样,以快几乎2倍的搜索(在表1中为54个分区对在表2中为30个分区)允许快11/2倍的合并(在表1中为6个合并级别对在表2中为4个合并级别)。

在激励此研究的应用中,替代性能度量是这样的:如果每个查询可以搜索有限数目的增量,例如多达30个增量,则查询结果可以有多接近于实时?例如,在表1中,实时查询因30个增量的限制而是不可能的。30个增量的严格限制将查询限制为查询较旧的数据,从而造成从数据摄取到首次查询的人为等待时间。例如,在表1中扇入4需要8个合并级别。在平均而言每合并级别为6个游程情况下,能够查询5个合并级别。能够从查询中省略最近的3个合并级别上的游程。因此,人为延迟是1分钟乘以43或超过一个小时。

表2.改进的一月内的合并和搜索分钟数。

替换地,50个增量的较弱限制需要8、10或甚至16个合并级别用于实时查询。换句话说,每个输入行在存储器与存储之间来回8、10或甚至16次。相比之下,利用以表2为基础的技术,4个合并级别足以将查询限制为30个增量。换句话说,一半合并努力(存储器与存储之间的每行旅行)允许无法使用以表1为基础的原始技术以任何合并扇入实现的从摄取到首次查询的等待时间。

另一示例

又如,考虑一年中的分钟数,其中60×24×366=527,040≈3

表3.一年内的合并和搜索分钟数。

表3示出针对遍及整年(366天)的一分钟游程的示例计算。两个合并级别大约每12

集中于替代性能度量,表3的6级别合并以及每查询30个增量的限制,用于日志结构合并树查询的合并模式在最高的两个合并级别(4天或较旧的数据)中运行;然而合并模式允许查询所有游程,其中有效实时的查询结果如对于监视和对于在线仪表板所期望的那样。

概述和结论

总之,可以将b树索引和日志结构合并树与本文描述的技术一起使用。线性分区b树和交错合并可能无法消解快速合并与快速搜索之间的紧张,但是它们通过减小要在每个查询中搜索的分区的平均(预期)数目并且通过在平衡或接近最佳折衷选择下减小合并努力和搜索努力两者来减轻痛苦。

总之,实际上任何数据仓库和任何web分析应用应该使用日志结构合并树以便使表及其索引连续地增长,但是它们应该使用最佳策略和机制。线性分区b树和交错合并可以节省大量数据中心资源和成本。

虽然本设计涵盖日志结构合并树中的信息捕获和增量合并的许多方面,但是其特别集中于协调所有合并和搜索活动的存储器内有序索引。本设计涵盖汇总(物化“按组”视图)以及次级索引(其可以被视为特别简单的物化视图),但是它不涵盖物化加入视图(组合两个或更多个表、索引或其他物化视图的视图)。详细设计留给将来的工作,但是可以在这里允许几个建议。

如果加入输入中的一个是流,则可以使用早先呈现的技术来索引该流。其他加入输入应该具有合适的索引,使得能够加入流输入并将结果应用于物化加入。应用加入输出本身可以使用上述技术。物化加入视图被物化并索引作为其初级索引以及任何次级索引的日志结构合并树。

如果两个加入输入是流,则它们都应当使用上述技术来索引。随着输入到达,它与其他表的索引加入在一起,并且加入结果被物化并索引为日志结构合并树,从而有望如本公开中所描述的那样优化。

C.计算机架构

图12示出根据一些实施方式的可以被采用以实现本文所讨论的任何计算机系统的说明性计算机系统1200的总体架构。计算机系统1200可以用于经由网络810提供信息以供显示。图12的计算机系统1200包括通信地耦合到存储器1225的一个或多个处理器1220、一个或多个通信接口1205、以及一个或多个输出设备1210(例如,一个或多个显示单元)和一个或多个输入设备1215。处理器1220可以被包括在数据处理系统110或系统800的其他组件中,诸如数据处理系统805。

在图12的计算机系统1200中,存储器1225可以包括任何计算机可读存储介质,并且可以存储诸如用于为相应系统实现本文所述的各种功能性的处理器可执行指令的计算机指令,以及由此生成或经由通信接口或输入设备(如果存在)接收的与其相关的任何数据。再次参考图8的系统800,数据处理系统可以包括存储器1225,以存储与用户标识符、生成的矢量等有关的信息。图12中所示的处理器1220可以被用于执行存储在存储器1225中的指令,并且这样做还可以从存储器中读取或向存储器写入按照指令的执行而处理和/或生成的各种信息。

图12中所示的计算机系统1200的处理器1220还可以通信地耦合到通信接口1205或控制通信接口1205以按照指令的执行传送或接收各种信息。例如,通信接口1205可以耦合到有线或无线网络、总线或其他通信装置,并且因此可以允许计算机系统1200向其他设备(例如,其他计算机系统)传送信息或从其他设备接收信息。虽然在图12的系统中未明确示出,一个或多个通信接口促进在系统1200的组件之间信息流动。在一些实施方式中,通信接口可以被配置(例如,经由各种硬件组件或软件组件)以提供网站作为对计算系统1200的至少一些方面的访问门户。通信接口1205的示例包括用户接口(例如,网页),用户可以通过该用户接口与数据处理系统1200进行通信。

例如,可以提供图12所示的计算机系统1200的输出设备1210,以允许结合指令的执行来查看或以其他方式感知各种信息。可以提供输入设备1215,例如,以允许用户在指令执行期间进行手动调整、进行选择、键入数据或以各种方式与处理器交互。本文进一步提供了与可用于本文所讨论的各种系统的通用计算机系统架构有关的附加信息。

本说明书中描述的主题和操作的实施方式可以在数字电子电路中或在包括在本说明书中公开的结构及其等同结构的有形介质、固件或硬件上体现的计算机软件中或其中一种或多种的组合实现。本说明书中描述的主题的实现方式可以实现为一个或多个计算机程序,即,计算机程序指令的一个或多个组件,其被编码在计算机存储介质上以由数据处理装置执行或控制数据处理装置的操作。可以在人工生成的传播信号,例如,机器生成的电、光或电磁信号上编码程序指令,该信号被生成以对信息进行编码以传输到合适的接收器设备以由数据处理设备执行。计算机存储介质可以是或包括在计算机可读存储设备、计算机可读存储基板、随机或串行访问存储器阵列或设备或它们中的一个或多个的组合中。此外,虽然计算机存储介质不是传播信号,但是计算机存储介质可以包括以人工生成的传播信号编码的计算机程序指令的源或目的地。计算机存储介质还可以是一个或多个单独的物理组件或介质(例如,多个CD、磁盘或其他存储设备)或包含在其中。

本文公开的特征可以在智能电视模块(或连接的电视模块、混合电视模块等)上实现,该智能电视模块可以包括处理模块,该处理模块被配置成将互联网连接与更传统的电视节目源(例如,经由电缆、卫星、无线或其他信号接收)集成在一起。智能电视模块可以物理地合并到电视机中,或者可以包括单独的设备,诸如机顶盒、蓝光或其他数字媒体播放器、游戏机、酒店电视系统以及其他配套设备。智能电视模块可以配置成允许观众搜索和查找web上、本地有线电视频道上、卫星电视频道或存储在本地硬盘上的视频、电影、照片和其他内容。机顶盒(STB)或机顶单元(STU)可以包括信息家电设备,其可以包含调谐器并连接到电视机和外部信号源,将信号调谐为内容,然后将该内容显示在电视屏幕上或其他显示设备上。智能电视模块可以配置成提供主屏幕或最高级屏幕,其包括用于多个不同应用,诸如web浏览器和多个流媒体服务的图标、连接的电缆或卫星媒体源、其他Web频道等等。智能电视模块可以进一步被配置成向用户提供电子节目指南。智能电视模块的伴随应用可以在移动计算设备上操作,以向用户提供有关可用节目的附加信息,以允许用户控制智能电视模块等。在可替代实施方式中,可以在膝上型计算机或其他个人计算机、智能手机、其他移动电话、掌上计算机、平板电脑或其他计算设备上实施特征。

本说明书中描述的操作可以被实现为由数据处理装置对存储在一个或多个计算机可读存储设备上或从其他源接收到的数据执行的操作。

术语“数据处理装置”、“数据处理系统”、“用户设备”或“计算设备”涵盖用于处理数据的所有类型的装置、设备和机器,例如包括前述的可编程处理器、计算机、片上系统、或多个或组合。该装置可以包括专用逻辑电路,例如,FPGA(现场可编程门阵列)或ASIC(专用集成电路)。除了硬件之外,该装置还可以包括为在讨论中的计算机程序创建执行环境的代码,例如,构成处理器固件、协议栈、数据库管理系统、操作系统、跨平台运行时环境、虚拟机或其中一个或多个的组合的代码。装置和执行环境可以实现各种不同的计算模型基础结构,诸如web服务、分布式计算和网格计算基础设施。

计算机程序(也称为程序、软件、软件应用、脚本或代码)可以用任何形式的编程语言编写,包括编译或解释语言、声明性或过程语言,并且可以以任何形式部署,包括作为独立程序或作为模块、组件、子例程、对象或其他适合在计算环境中使用的单元。计算机程序可以但是不必对应于文件系统中的文件。程序可以存储在保存其他程序或数据的文件的一部分(例如,存储在标记语言文档中的一个或多个脚本)、专用于讨论中的程序的单个文件、或多个协调文件(例如,存储一个或多个模块、子程序或部分代码的文件)中。可以将计算机程序部署为在位于一个站点或分布在多个站点并通过通信网络互连的一个计算机或多个计算机上执行。

可以通过执行一个或多个计算机程序的一个或多个可编程处理器来执行本说明书中描述的处理和逻辑流程,以通过对输入数据进行操作并生成输出来执行动作。过程和逻辑流程也可以由专用逻辑电路,例如,FPGA(场可编程门阵列)或ASIC(专用应用集成电路)执行,并且装置也可以实现为该专用逻辑电路。

例如,适于执行计算机程序的处理器包括通用和专用微处理器,以及任何种类的数字计算机的任何一个或多个处理器。通常,处理器将从只读存储器或随机存取存储器或两者接收指令和数据。计算机的基本元件包括用于根据指令执行动作的处理器和用于存储指令和数据的一个或多个存储设备。通常,计算机还将包括一个或多个用于存储数据的大容量存储设备,例如,磁盘、磁光盘或光盘,或可操作地耦合至大容量存储设备以从中接收数据或对其传输数据,或者两者。然而,计算机不必具有此类设备。此外,计算机可以嵌入到另一个设备中,例如,移动电话、个人数字助理(PDA)、移动音频或视频播放器、游戏机、全球定位系统(GPS)接收器或便携式存储设备(例如,通用串行总线(USB)闪存驱动器)。适于存储计算机程序指令和数据的设备包括所有形式的非易失性存储器、介质和存储器设备,例如包括半导体存储器设备,例如,EPROM、EEPROM和闪存设备;磁盘,例如内部硬盘或可移动磁盘;磁光盘;以及CD ROM和DVD-ROM盘。处理器和存储器能够由专用逻辑电路补充或被并入专用逻辑电路中。

为了提供与用户的交互,本说明书中描绘的主题的实施方式能够在具有显示设备和键盘与定点设备的计算机上实现,所述显示设备例如是CRT(阴极射线管)、等离子体、或者LCD(液晶显示器)监视器,用于向用户显示信息,所述定点设备例如为鼠标和轨迹球,用户能够通过其向计算机提供输入。其它类型的设备也能够用于提供与用户的交互;例如,提供给用户的反馈可以包括任何形式的感觉反馈,例如,视觉反馈、听觉反馈或触觉反馈;并且能够以任何形式接收来自用户的输入,包括声音、语音或触觉输入。另外,计算机能够通过向用户使用的设备发送文档以及从用户使用的设备接收文档来与用户进行交互;例如,通过响应于从web浏览器接收到的请求将网页发送到用户客户端设备上的web浏览器。

本说明书描述的主题的实施方式可以在包括后端组件(例如,作为数据服务器)或包括中间件组件(例如,应用服务器)或包括前端组件(例如,具有图形用户界面或web浏览器的客户端计算机,用户可以通过该图形用户界面或web浏览器与本说明书中描述的主题的实施方式进行交互)或者一个或多个此类后端、中间件或前端组件的组合的计算系统中实现。系统的组件可以通过数字数据通信的任何形式或介质(例如,通信网络)互连。通信网络的示例包括局域网(“LAN”)和广域网(“WAN”)、网际网络(例如,互联网)和对等网络(例如,ad hoc对等网络)。

诸如数据处理系统805的计算系统可以包括客户端和服务器。例如,数据处理系统805可以包括一个或多个数据中心或服务器场中的一个或多个服务器。客户端和服务器通常彼此远离,并且通常通过通信网络进行交互。客户端和服务器之间的关系是通过在相应计算机上运行并彼此具有客户端-服务器关系的计算机程序而产生。在一些实施方式中,服务器将数据(例如,HTML页面)传送到客户端设备(例如,出于向与客户端设备交互的用户显示数据并从其中接收用户输入的目的)。可以从服务器处的客户端设备接收在客户端设备处生成的数据(例如,用户交互的结果)。

尽管本说明书包含许多特定的实施细节,但是这些不应被解释为对任何发明或可要求保护的范围的限制,而应被解释为对本文所述的系统和方法的特定实施方式特定的特征的描述。在本说明书中在单独的实施方式的上下文中描述的某些特征也可以在单个实施方式中组合实施。相反,在单个实施方式的上下文中描述的各种特征也可以单独地或以任何合适的子组合在多个实施方式中来实施。而且,尽管以上可以将特征描述为以某些组合起作用并且甚至最初如此要求保护,但是在某些情况下,可以从组合中切除所要求保护的组合中的一个或多个特征,并且所要求保护的组合可以针对子组合或子组合的变体。

类似地,虽然在附图中以特定顺序描绘了操作,但是这不应理解为要求以所示的特定顺序或以连续的顺序执行这样的操作,或者执行所有图示的操作以实现期望的结果。在一些情况下,可以以不同的顺序执行权利要求中引用的动作,并且仍然实现期望的结果。另外,附图中描绘的过程不一定需要所示的特定顺序或连续顺序来实现期望的结果。

在某些情况下,多任务和并行处理可能是有利的。此外,在上述实施方式中的各种系统组件的分离不应被理解为在所有实施方式中都需要这种分离,并且应当理解,所描述的程序组件和系统通常可以被一起集成在单个软件产品中或打包到多种软件产品。例如,数据处理系统805可以是单个模块、具有一个或多个处理模块的逻辑设备、一个或多个服务器或搜索引擎的一部分。

现在已经描述了一些说明性的实施方式和实施方式,显然的是,前述内容是说明性的而非限制性的,已经通过示例的方式呈现。特别地,尽管本文呈现的许多示例涉及方法动作或系统元素的特定组合,但是可以以其他方式组合那些动作和那些元素以实现相同的目标。仅结合一种实现方式讨论的动作、元素和特征不旨在被排除在其他实现方式或实现方式中的类似作用之外。

这里使用的措词和术语是出于描述的目的,而不应被认为是限制性的。本文中“包括”、“包含(comprising)”、“具有”、“包含(containing)”、“涉及”、“特征为”、“特征在于”及其变体的使用意在涵盖其后列出的项目、其等同物以及附加项目,以及仅由其后列出的项目组成的替代实施方式。在一种实施方式中,本文描述的系统和方法由所描述的元素、动作或组件中的一个、多于一个的每种组合或全部组成。

对本文中以单数形式提及的系统和方法的实现或元素或动作的任何引用也可以包含包括多个这些元素的实现,并且在本文中对任何实现或元素或动作的复数形式的任何引用也可以包含仅包括单个元素的实现。单数或复数形式的引用无意将当前公开的系统或方法、它们的组件、动作或元素限制为单个或多个配置。对基于任何信息、动作或元素的任何动作或元素的引用可以包括其中该动作或元素至少部分基于任何信息、动作或元素的实现。

本文公开的任何实施方式可以与任何其他实施方式组合,并且对“实施方式”、“一些实施方式”、“可替代实施方式”、“各种实施方式”、“一个实施方式”等的引用不一定是互斥的,并且旨在指示结合实施方式描述的特定特征、结构或特性可以被包括在至少一个实施方式。如本文所使用的这样的术语不一定全部指代相同的实施方式。任何实施方式可以以与本文公开的方面和实施方式一致的任何方式与任何其他实施方式包含性地或排他性地组合。

对“或”的引用可以被解释为包含性的,使得使用“或”描述的任何术语可以指示单个、一个以上以及所有所描述术语中的任何一个。

对于附图、详细描述或任何权利要求中的技术特征之后跟有附图标记的情况,附图标记已被包括以增加附图、详细描述和权利要求的可理解性。因此,附图标记或其缺失对任何权利要求元素的范围没有任何限制作用。

在不脱离其特性的情况下,本文中描述的系统和方法可以以其他特定形式来实现。尽管本文提供的示例涉及控制信息资源内容的显示,但是本文描述的系统和方法可以包括应用于其他环境。前述实施方式是说明性的,而不是限制所描述的系统和方法。因此,在此描述的系统和方法的范围由所附权利要求而不是前面的描述指示,并且在权利要求的等同含义和范围内的改变被涵盖在其中。

相关技术
  • 日志结构合并森林中的交错合并
  • 基于日志结构合并树合并数据的方法、系统、设备及介质
技术分类

06120112212085