摘要
为了监控关键基础设施,以高频率采样的高质量传感器被越来越多地安装。然而,由于产生的数据量很大,只存储简单的聚合。这将删除异常值并隐藏可能表明问题的波动。作为一种解决方案,我们提出了一种基于模型的方法,我们称之为多模型组压缩(MMGC)。MMGC在用户定义的错误范围(可能为零)内使用一组可扩展的模型自适应地压缩一组具有维度的相关时间序列。为了将时间序列划分成组,我们提出了一组原语,以有效地描述不同大小数据集的相关性。我们还提出了高效的查询处理算法,用于在模型而不是数据点上执行多维聚合查询。最后,我们提供了我们的方法的开源实现,作为基于模型的时间序列管理系统(TSMS) ModelarDB的扩展。ModelarDB与Apache Spark和Apache Cassandra的现有版本进行接口,从而可以重用现有的基础设施。通过评估,我们表明,广泛使用的系统相比,我们扩展ModelarDB提供11倍摄入由于高压缩,更好65倍压缩由于MMGC的自适应性,快92倍聚合查询模型上执行,和接近线性可伸缩性,同时可扩展和支持在线查询处理。
1 介绍
维护关键基础设施(如能源生产)的公司受益于高度覆盖的监控和高频率采样数据点。为了在能源领域促进这一点,风力涡轮机等实体由具有有线电源和连接的高质量传感器监控。因此,无效、缺失和无序的读数很少,除缺失值外,所有读数都可以使用既定方法进行校正。除了数据点之外,还为每个时间序列存储元数据,例如位置和传感器类型,以支持多维分析。然而,由于产生了大量的数据点,因此只存储简单的聚合,从而消除了异常值和波动。作为补救措施,基于模型的存储允许在已知误差范围(可能为零)内压缩时间序列[32,21]。模型是在已知误差范围内重构原始时间序列的任何表示。通过多模型压缩(MMC)和基于模型的组压缩(MGC),基于模型的时间序列存储得到了改进。MMC利用时间序列的结构随时间变化,并使用多个模型压缩每个时间序列[26,27,31,14,23]。MGC利用时间序列是相关的,例如,非常接近的温度传感器可能报告相似的值,并将相关的时间序列压缩为一个模型流[32,16]。MGC如图1所示。在该示例中,由v = a × t + b给出的线性函数用于表示三个相关的时间序列,为在该时间戳观察到的三个值创建从时间戳t到近似值v的映射。
然而,据我们所知,没有一种MMC方法利用了时间序列之间的相关性,而现有的MGC方法都只利用了单一类型的模型。本文主要研究利用MMC和MGC对自定义维数的相关时间序列进行分组压缩的新问题。我们将这种新的压缩类型命名为多模型组压缩(MMGC)。我们通过使用MMGC扩展开源的MMC TSMS ModelarDB[23],证明了MMGC适合与TSMS一起使用。为了区分ModelarDB的两个版本,我们将在原始版本中使用modelardbv1,在使用MMGC扩展的版本中使用modelardbv2。我们还演示了如何在模型上比在数据点上更有效地执行多维聚合查询。因此,modelardbv2为时间序列数据提供了高压缩比,为可伸缩性提供了分布式存储和查询处理,为低延迟提供流处理,并有效支持时间序列的多维聚合查询。综上所述,我们在大数据系统领域做出了以下贡献:
- 多模型分组压缩的概念和压缩时间序列分组的现有模型的扩展。
- 用于根据维度层次结构和用户提示将时间序列划分为相关时间序列组的原语。
- 用于对表示多个时间序列的模型执行简单聚合和多维聚合查询的算法。
- TSMS ModelarDBv2 实现了我们的分区、多模型组压缩和查询处理方法。
- 评估ModelarDBv2及其用于分区、多模型组压缩和查询处理的算法。
论文结构如下。定义见第2节。第3节概述了ModelarDBv2。第4节记录了我们的划分原语,而第5节描述了我们对现有模型的MGC扩展。第6节描述了我们的查询处理算法。第7节给出了对ModelarDBv2is的评估。第8节介绍了相关工作。最后,第9节提供了我们的结论和未来的工作。
2 预备知识
我们现在提供在论文中使用的定义。我们还通过示例提供了对定义的直观理解。由于ModelarDBv1扩展了ModelarDBv1,定义1–6来自[23]。
Dimension(维度):…
Time Series Group (时间序列组): …
3 架构
3.1 概述
ModelarDBv2是一种新颖的基于分布式模型的tms,它被设计为一个可移植的库ModelarDBv2 Core,可以很容易地与现有的软件进行接口。我们用现有版本的Apache Spark进行查询处理,用Apache Cassandra进行存储,以实现主/工作者架构。ModelarDBv2通过添加分区器组件并对ModelarDBv1的所有组件[23]进行更改来实现MMGC。分区程序接受一组维度时间序列作为输入,并根据用户提示将它们划分为组。为了防止数据倾斜,每个组都被分配给拥有最多可用资源的工作人员。在摄入过程中,系统自动为每个时间序列组的每个动态大小的子序列选择适当的模型。ModelarDBv2核心包含了三个模型,扩展为支持MGC: PMC- mean模型(PMC)[25],线性摆动模型(Swing)[15],以及为tms Gorilla (Gorilla)[28]提出的浮点值无损压缩算法。用户可以选择通过扩展API实现更多模型,而无需重新编译ModelarDBv2。对于查询处理,modelardbv2使用SQL并展开ModelarDBv1[23]建议的段视图和数据点视图。段视图允许在段上有效地执行聚合,例如,在线性模型上使用常量时间执行SUM,而在数据点视图上的查询则在重构数据点上执行。ModelarDBv2中每个工作节点的体系结构被分为三组组件,如图4所示。在图4中,每个组件都用提供该功能的软件进行了注释,并且为ModelarDBv2修改的组件以灰色梯度显示。虚线之外的组件作为主节点的一部分实现。数据摄取摄取时间序列并在用户定义的错误范围内构造模型;查询处理缓存最近构造和查询的段,并在段或数据点级别处理查询;段存储为持久段组存储提供了一个统一的接口,其中包含谓词下推。总之,modelardbv2很容易部署在集群中,同时在一个系统中提供最先进的摄取率、压缩和查询性能。modelardbv2实现这一点的方法是,使用ModelarDBv2Core中的模型(可选用户定义)来压缩多个维度相关的时间序列。
3.2 空隙的摄取和表示
在每个采样间隔为SI的模型中,ModelarDBv2将一个模型与一组时间序列中的数据点相匹配,而不是像模型Bv1那样每个时间序列一个模型。两者都将模型视为黑盒,具有允许任意用户定义模型的公共界面。ModelarDBv2分四个步骤执行摄取:(I)接收来自组中每个时间序列的数据点,并将其添加到缓冲区中,(ii)验证当前模型是否能适合新的数据点,如果不能,则使用下一个模型,(iii)当最后一个模型不能适合更多的数据点时,将提供最佳压缩比的模型刷新到内存和磁盘中,(iv)最后,从缓冲区中移除由刷新的模型表示的数据点,并从序列中的第一个模型重复该过程。在继续摄取之前,任何间隙都存储为当前片段的一部分。为了简化间隙管理并改进查询处理期间的过滤,为每个段存储了开始时间和结束时间。此外,由于不像连接的段那样存储重叠的数据点,段被不连接地存储以提高压缩率[26,27]。因此,使用在用户定义的误差范围(可能为零)内提供最佳压缩的模型,每个片段代表一组时间序列中的动态大小的子序列。为了存储间隙,我们考虑两种方法。第一个以三元组(Tid,ts,te)的形式存储间隙,即T id指示的时间序列中间隙的开始时间和结束时间。第二种方法是在出现间隙时创建一个新的段,并将间隙存储为T ids,如图5所示。本例中的组由三个时间序列组成,因此模型在t1处拟合三个值。在时间ts,在时间S2出现一个间隙,并且一个新的模型被拟合到仅来自两个时间序列的值。为了表明这个模型只代表时间序列的一个子集,没有代表的时间序列的T标识被存储在段中,参见S2。当再次从所有时间序列接收到数据点时,重复该过程,参见蒂和S3。因此,一个段代表静态数量的时间序列的数据点。
对于ModelarDBv2,我们使用第二种方法,因为它:(1)简化了用户定义模型的实现,因为用第一种方法存储间隙需要模型考虑间隙的任何组合,(2)简化并减少了摄取、执行聚合查询和重建数据点所需的计算,因为这些操作必须跳过间隙。然而,这种选择是一种权衡,因为将间隙存储为三倍需要20字节,而新的段需要24+size of(M model)字节。因此,ModelarDBv2显著提高了压缩的水平,参见第7节,同时使用户定义的模型易于实现。
3.3 存储方案
ModelarDBv2用来支持MMGC的存储模式如图6所示。时间序列表包含每个时间序列的元数据和用户定义的维度,每个维度由一个T标识来标识。唯一需要的元数据是国际单位制。Gid表示时间序列被划分到哪个组,并由ModelarDBv2使用用户提示进行计算。缩放是一个常量,在摄取和查询处理过程中,ModelarDBv2会将它应用于每个值。用一个标度常数,不同值的相关时间序列可以被压缩在一起。模型表将一个模型标识映射到该模型的Java类路径。最后,段表包含作为动态大小段的所有摄取的数据点。
用数据仓库术语来说,段表的功能就像一个事实表,在摄取过程中不断地添加新的段。用户定义的维度作为时间序列表的一部分进行非规范化存储。但是,不需要显式的时间维度,因为时间维度中的聚合查询可以仅使用开始时间和结束时间来有效地计算,如第6.3节所述。对卡珊德拉来说,对一般模式做了两处修改。首先,为了更有效地支持谓词下推,Segment的主键改为Gid、EndTime、gap[23]。包含间隙是为了防止由于第4.2节中描述的动态分割造成的重复密钥。间隙中的值存储为整数,每个位代表组中该时间序列是否出现间隙。其次,由于“开始时间”列不用于索引,因此它会被更改,以便存储段的大小来节省空间。开始时间可以有效地重新计算为开始时间=结束时间(大小×国际单位制)[23]。
4 时间序列的划分
4.1 相关时间序列的划分
为了提供基于模型的存储和查询处理的优势,同时确保低延迟,模型必须在线安装[23]。但是,在分布式系统中,应该在一个节点上摄取压缩在一起的时间序列,以防止过多的网络流量限制系统的可扩展性。因此,为了防止集群中的数据迁移,必须仅基于元数据或以前收集的数据对时间序列进行分区。由于历史数据可能不存在,即使只有50,000个时间序列的小数据集也会产生(50,000 ^ 2)≈1.25×10^9对的可能非常大的时间序列来比较相关性,简单地从历史数据计算什么时间序列是相关的很快变得不可行。
我们提出了一组原语,这些原语可以组合起来,以有效地描述具有不同数量的时间序列和维度的数据集的相关性。原语在ModelarDBv2的配置文件中被指定为modelardb.correlation子句,一个子句中的多个原语隐式地与“与”运算符组合,而多个子句隐式地与“或”运算符组合。使用这些用户提示,ModelarDBv2将时间序列划分成组,以便一起摄取。原语允许将相关性指定为时间序列集、成员维度必须相等的级别或所有维度之间的距离(如下所述)。按照算法1所示进行分组。在第5行中初始化每个时间序列的组之后,算法迭代地组合组,直到组数中的一个固定点。第10行中的相关函数检查是否应该根据用户定义的相关性合并组。
当将相关性指定为时间序列时,必须提供它们的位置(文件或套接字),例如,4l 80 r9a Temperature.gz 4l 80 r9b Temperature.gz。对于相关但不包含相似值的时间序列,可以为每个时间序列添加一个比例常数。虽然这允许对组进行精确控制,但是随着时间序列数量的增加,这很快变得太耗时。其他基元基于这样的概念,即时间序列相关性可以从它们的维度中导出。例如,非常接近的温度传感器可能会产生类似的值。两组维度的相似性可以计算为它们的最低共同祖先(LCA)级别。最低共同祖先是维度中的最低级别,其中两组中的所有时间序列都具有从>开始的等效成员。计算最低共同祖先的一个例子可以在图7中看到。
要指定基于成员的相关性,用户必须提供由维度、级别和成员组成的三元组,或者具有维度和最低共同祖先的一对。例如,三重测量1温度指定在测量维度的第一级共享成员温度的时间序列是相关的。位置2对表示,如果位置维度的最低共同祖先等于或高于2,则时间序列是相关的。零表示所有级别必须相等,负数n表示除最低|n|个级别之外的所有级别必须相等。当为许多时间序列指定一个缩放常数时,可以为具有共享成员的时间序列定义一个包含维度、级别、成员和缩放常数的4元组。这些原语适用于维度少但时间序列多的数据集。
对于具有大量时间序列和维度的数据集,用户可以将相关性指定为距离[0.0;1.0]之间的尺寸。直觉是,成员之间有很多重叠的时间序列将是相关的。例如,对于图7中的位置维度,涡轮机级别的时间序列共享成员比仅共享国家级别的成员更有可能相关。距离0.0指定所有成员必须匹配才能对时间序列进行分组,距离1.0指定所有时间序列都应进行分组。中间值指定不同的重叠程度。用户可以通过使用默认值为1.0的权重来更改维度的影响,从而注入领域知识。由于用户定义的权重,距离超过1.0的距离将减少到1.0。对于基于距离的相关性,经验法则是对数据集使用最低非零值,以便只对具有许多重叠成员的时间序列进行分组。最小距离可以计算为(1/最大(级别))/|维度|其中级别是每个维度中的级别集,维度是维度集。
算法2中显示了计算两个时间序列组之间距离的伪代码。在第11行中,距离计算为(高度-祖先)/高度,以减少仅在层次结构顶部具有同等成员的组的影响。在第12行中,尺寸的距离乘以用户定义的该尺寸的重量,然后添加到累加器中。在第14-15行中,两个时间序列组之间的距离标准化为0.0-1.0范围,并与用户定义的阈值进行比较,以确定两个时间序列组是否相关。例如,对于图7所示的“位置”维度,时间序列(T id = 2和T id = 3)之间的归一化距离可以计算为1.0 ×((4-3)/4)= 0.25。
4.2 动态拆分组
由于外部事件可以改变时间序列接收到的值,例如,风力涡轮机可能被关闭或损坏,ModelarDBv2可以在其时间序列暂时不相关时拆分组。分割可以在一个段发射后执行,因为它表明时间序列的结构已经改变,因此下一个数据点将超过错误界限。为了尽量减少无益分割的次数和决定何时分割的开销,modelardbv2使用了两个启发式方法:较差的压缩比和摄入数据点之间的百分比错误。首先,ModelarDBv2检查新段的压缩比是否低于用户可配置的平均比例(默认为1/10)。如果压缩比较低,并且ModelarDBv2has未发出数据点,则执行算法3。如果缓冲数据点是相关的,该算法将时间序列分组,并可以创建大小为1的组,其大小与原始组相同。目前处于空白的时间序列被分组在一起。在第9-16行中,如果T s2的值在T S1的用户定义误差范围的两倍以内,则将T s2添加到TSGn中。使用双误差界是因为如果两个数据点超出这个界限,就不能近似在一起。组中的所有时间序列分组后,返回分割的新组。图8显示了拆分的示例。虽然ModelarDBv2丢弃了作为段发出的数据点,但图8显示了整个时间序列,以显示它们如何随时间变化。在tm组使用段发生器SG0摄入,然而,在tn组的所有时间序列都不再相关,压缩差的段被释放。因此,该组被分为两组,继续摄入sg1和SG2。sg0在分割后未使用,但没有回收分配,因为它同步分割的摄取以简化连接,并在分割组变得相关时将它们连接起来。然后在什一组被再次分开,每个时间序列现在被分开摄入。
恢复分裂组的算法如算法4所示,与算法3类似。然而,当加入组时,只需要比较每个组中的一个时间序列,因为组由相关的时间序列组成(否则就会发生分裂)。为了简化合并组,算法4只在每个SI结束时潜在地执行,这样所有组都在同一时间段内收到了数据点。由于发出的段表明组接收的值发生了显著的变化,拆分后的组仅在发出一些段之后才被标记为加入。每次尝试加入分离的组后,必须发出的段数将增加一倍,以减少加入的开销。直觉告诉我们,每一次失败的合并尝试都表明当前的分割是更可取的。继续图8中的例子,在tj,两个系列再次相互关联,合并为一个组。最后,在tk,所有的时间序列再次相关,所以sg0接管摄取。
5 多模型组压缩
要从MMGC中受益,需要一组模型。然而,由于大多数基于模型的时间序列压缩方法是为单个时间序列设计的[32,21],现有的模型在与ModelarDBv2一起使用之前必须扩展以支持MGC。我们首先描述了一种简单的方法,通过存储每个区段的多个模型来使用MGC中的任何模型,然后介绍了两种模型特定的方法,允许一个组使用每个区段的一个模型。
5.1 每个段多模型
将MGC支持添加到任何模型的基线方法是将接收到的数据点进行分割,并使它们适合作为一个片段的一部分存储在一起的单独模型。由于差距由模型管理,因此不需要对模型进行扩展。但是,要在一个段中为多个模型使用元数据,每个模型代表不同时间序列的值,模型必须代表相同的时间间隔。通过在拟合每个新数据点之前验证所有模型不会超过误差界限,这在直觉上很容易确保。然而,这是不必要的,如下所述。
当多个模型被更新时,会出现三种情况,如图9所示。对于情况(1),所有模型都可以表示从它们各自的时间序列接收的数据点。情况(二)则相反,因为第一个模型不能表示它在用户定义的误差范围内接收的数据点。对于情况(一)和情况(二),看到所有模型表示相同的时间间隔是微不足道的。在情况(三)中,第一个模型可以表示接收到的数据点,但是第二个模型不能。由于该段中的模型不再代表相同的时间间隔,因此该段的结束时间te不会简单地增加到te+ SI。
由于每个模型都代表所有先前摄取的值,因此可以以SI为增量安全地减少片段的结束时间te,直到ts> te。对于参数数量取决于拟合数据点数量的模型,如Gorilla,应删除剩余参数。然后,下一组数据点被拟合到一组新的模型。虽然存储在一个段中的n个模型的使用将重复元数据的数量从n个副本减少到一个副本,并且易于实现,但是它并不减少值所需的存储。为了进一步提高压缩率,每个模型必须使用一组参数来表示多个时间序列。
5.2 每个段一个模型
为了充分利用MMGC,必须提供一组模型,这些模型都使用单一模型压缩时间序列。我们发现ModelarDBv1can所使用的模型可以被扩展以使用基于两个一般思想的单个模型来有效地压缩一组时间序列。对于使用无损压缩的模型,例如大猩猩,来自多个时间序列的值应该存储在时间有序的块中。这允许在每个国际单位制中利用时间相关性和时间序列相关性。对于根据统一误差范数使用上限和下限来拟合摄取数据点的模型,例如PMC和斯温,只有具有每个服务指数的最小值和最大值的数据点才能修改界限并使模型无效。结果,对于时间戳t,值v的集合(其中v是⊂ R)可以被减少到由三元组va= (t,min(V),max(V))表示的值的范围。我们现在详细展示如何使用作为ModelarDBv2Core的一部分提供的三个模型高效地执行MMGC。
对PMC来说,一组时间序列中的一组值表示为误差范围内的平均值 ε min(V)和max(V),max(V)-min(V)= 2ε作为最大范围。因此,PMC不需要改变,因为模型只跟踪当前的最小值、最大值和平均值。参见图10中的PMC。
由于Swing产生的线性函数保证通过初始数据点,因此可以使用PMC来计算初始点。那么,当Swing模型保持一个线性函数的上界和下界时,这个线性函数可以表示接收到的所有数据点的值在ε之内,然后一次附加一个数据点。参见图10中的摆动。对于Gorilla,来自具有相同时间戳的数据点的值存储在块中。由于一个组中的时间序列是相关的,每个块中的n-1值与第一个值相比只有很小的增量,并且只需要几个位来编码。参见图10中的Gorilla。为了展示我们的MGC扩展的优势,我们压缩了三个代表同处一地的风力涡轮机温度的实时时间序列。与仅使用MMC相比,在ModelarDBv2中启用MMGC可将所需存储减少28.97%,误差范围为0%,1%减少29.22%,5%减少36.74%,10%减少44.07%。
6 查询处理
6.1 查询接口
作为模型M,可以重构其所表示的误差范围?内的数据点,并对这些数据点执行查询。然而,许多聚合查询可以直接从一个模型中得到答案,例如,对于常数和线性函数,MIN, MAX, SUM和AVG查询可以在常数时间[23]中得到答案。为了支持这一点,modelardbv2提供了一个带有模式的段视图(Tid int、StartTime timestamp、EndTime timestamp、SI int、Mid int、Parameters blob、gap blob、维数)和一个带有模式的数据点视图(Tid int、TS timestamp、Value float、维数)。维表示存储非规范化用户定义维的列。用户定义的维度缓存在内存中并将其添加到段和数据点在需要时查询处理过程中使用的散列连接与一个数组用来代替一个哈希表(T id是整数(从1开始),使用细分视图ModelarDBv2supports执行聚合查询段使用用户定义的聚合函数,这对于简单的查询是后缀为年代,例如,在时间维度中执行聚合的MAX s函数在时间层次结构中以聚合和级别作为后缀,例如CUBE AVG HOUR。作为迭代步骤的一部分,所有聚合函数将结果除以每个时间序列的缩放常数。使用用户定义的维度层次结构执行聚合的查询可以在Segment视图中的适当列上使用GROUP BY执行,将问题简化为在段上计算简单聚合。因此,在本节中,我们将描述如何在分布函数和代数函数[17]的段上执行时间维中的简单聚合查询和多维聚合查询。
6.2 聚合查询
为了允许在时间序列级别而不是时间序列组级别表达查询,使用来自时间序列表的元数据在查询处理中执行gid和T id之间的映射,如图6所示。因此,用户提供的查询和ModelarDBv2返回的结果只引用T id,使用gid简化谓词下推,因为段存储只需要为每个段索引一个id。虽然modelardbv1仅支持Tid、StartTime和EndTime[23]的谓词下推,但ModelarDBv2也支持用户定义维度的谓词下推,方法是将WHERE子句中维度成员的所有实例重写为包含该维度成员的时间序列的组的gid。
使用Segment视图执行聚合查询的伪代码如算法5所示。在第8行,在将查询发送到每个工作节点之前,通过将SQL查询WHERE子句中的T id和成员替换为主节点上的匹配gid, SQL查询被重写为按照时间序列组查询段。在第9-10行中,每个worker节点初始化存储中间值的内存,并从其数据存储中检索相关段。然后对于每个段,在第11-13行中,作为参数传递的聚合函数将在每个段上执行。最后,在第15行中,为了同时支持分配函数和代数函数,必须对中间结果执行计算。图11显示了在Segment视图上执行的一个简单聚合查询示例。首先,查询中的所有T id都被重写为对应的gid。然后对每个段执行查询中指定的聚合函数。聚合函数也应用缩放常数。计算完所有分段的合计后,根据中间结果计算最终合计,例如计算平均值。
6.3 时间维度上的聚合
由于图6所示的模式将开始时间和结束时间存储为每个段的一部分,所以可以仅使用段表计算时间维中的聚合,而不需要与单独的时间维进行昂贵的连接。在时间维度上使用Segment视图执行聚合查询的伪代码见算法6。该算法采用与算法5相同的结构。首先,在第9行中,在每个worker初始化用于存储中间结果的内存并在第10-11行中检索相关段之前,根据gid(而不是T id和成员)重写查询。在第12-26行中,该算法遍历每个段,并为每个请求的时间间隔计算中间聚合。最后,在第28行计算并返回最终结果,以支持分配函数和代数函数。图12显示了用户定义维度和使用分段的时间维度中的聚合示例。该查询计算T id = 1、T id = 2和T id = 3的时间序列的每小时总和,使用函数立方体总和小时高效地计算分段而不是数据点上的结果。重写查询后,将计算从ts= 00:13到01:00的时间间隔的聚合,这是分隔两个聚合时间间隔的下一个时间戳。然后,计算从01:00到02:00的时间间隔的聚合。最后,计算从02:00到02:48的时间间隔(包括te= 02:48)的聚合。最后一个值计算时包含结束时间为ModelarDBv2,以增加压缩比,不存储连接的段[23]。