CN107209673A - 数据流加窗和触发 - Google Patents
数据流加窗和触发 Download PDFInfo
- Publication number
- CN107209673A CN107209673A CN201680007851.6A CN201680007851A CN107209673A CN 107209673 A CN107209673 A CN 107209673A CN 201680007851 A CN201680007851 A CN 201680007851A CN 107209673 A CN107209673 A CN 107209673A
- Authority
- CN
- China
- Prior art keywords
- data
- window
- time
- result
- processing hardware
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/90—Details of database functions independent of the retrieved data types
- G06F16/903—Querying
- G06F16/90335—Query processing
Abstract
一种方法包括:接收与流数据或者批量数据中的一个对应的数据(10)、和所接收到的数据的用于计算的内容。所述方法还包括:确定所述数据的用于对所述数据进行切分的事件时间;确定输出所接收到的数据的结果的处理时间;以及基于所述处理时间和所述事件时间来发射所接收到的数据的所述结果的至少一部分。
Description
技术领域
本公开涉及数据流加窗和触发。
发明内容
本公开的一个方面提供了一种用于对数据流进行加窗和触发的方法。该方法包括:在数据处理硬件处接收与流数据或者批量数据中的一个对应的数据;通过使用数据处理硬件来确定接收到的数据的用于计算的内容;通过使用数据处理硬件来确定数据的用于对数据进行切分的事件时间;以及通过使用数据处理硬件来确定输出接收到的数据的结果的处理时间。该方法还包括基于处理时间和事件时间来发射接收到的数据的结果的至少一部分。
本公开的实施方式可以包括以下可选特征中的一个或者多个。在一些实施方式中,该方法包括:通过使用数据处理硬件,基于事件时间,对接收到的数据窗口进行分组。该窗口可以包括由静态时间周期定义的固定窗口、由时间周期和滑动周期定义的滑动窗口、由超时间隔定义的会话窗口、或者由一对函数定义的用户定义的窗口中的一个。每个固定窗口可以被应用于在相关联的时间周期内的所有数据。每个滑动窗口可以被应用于在相关联的时间周期内的所有数据并且与开始时间相关联,由滑动周期将紧接着的窗口的开始时间与该开始时间分开。而且,每个会话窗口可以被应用于在小于相关联的超时间隔的时间跨度内出现的数据的子集。在一些实施例中,该方法包括:通过使用数据处理硬件来为接收到的数据的每个元素分配可合并窗口,每个元素包括相关联的输入时间戳,并且每个可合并窗口超过相关联的窗口的输入时间戳延伸预定义时间范围。该方法还可以包括:通过使用数据处理硬件来合并可合并窗口中重叠成单个合并窗口、属于相同密钥的两个或者更多个可合并窗口,并且通过使用数据处理硬件将每个元素的相关联的输出时间戳设置为大于或者等于在相关联的合并窗口或者相关联的可合并窗口中的最早时间的值。单个合并窗口可以包括大于预定义时间范围的相关联的时间范围。
当接收到的数据与流数据对应时,该方法可以包括:通过使用数据处理硬件将流数据分组成窗口,并且通过使用数据处理硬件设置对于流数据的元素的输入时间戳。当对于元素的输入时间戳先于水位线出现时,该方法可以包括:通过使用数据处理硬件来确定包括最新流数据的流数据;以及以下步骤中的一个步骤:丢弃最新流数据,或者通过创建复制窗口允许最新流数据在最新流数据的输出中。
在一些示例中,该方法包括:通过使用数据处理硬件将接收到的数据的第一子集分组成窗口,该窗口定义数据子集的子事件时间;通过使用数据处理硬件来聚合对于窗口的第一数据子集的第一结果;以及通过使用数据处理硬件来确定发射第一数据子集的第一聚合结果的触发时间。该触发时间可以包括以下中的至少一个:当水位线到达窗口的末端时;挂钟时间的每个阈值秒数;在接收到终止窗口的标点记录之后;每个阈值记录数;在任意的用户逻辑决定触发之后;或者在具体触发器的任意组合之后。
在确定发射第一数据子集的第一聚合结果的触发时间时,该方法可以包括:在聚合接收到的数据的后续子集的结果时,通过使用数据处理硬件抛弃对第一聚合结果的使用。在确定发射第一数据子集的第一聚合结果的触发时间时,该方法还可以包括:在持久状态下将第一聚合结果的副本存储在与数据处理硬件通信的存储器硬件内,并且通过数据处理硬件,利用第一聚合结果来细化后续子集的下一个聚合结果。在确定发射第一数据子集的第一聚合结果的触发时间时,该方法可以进一步包括:在持久状态下将第一聚合结果的副本存储在与数据处理硬件通信的存储器硬件内。在发射与相同的窗口相关联的后续子集的下一个聚合结果时,该方法可以包括:发射对第一聚合结果的撤销并且发射窗口的组合会话结果。
在一些实施方式中,该方法包括:在将第一数据子集分组成窗口之后,在数据处理硬件处接收最新数据点,该最新数据点与窗口有关,并且通过使用数据处理硬件抛弃最新数据点。该方法还可以包括:在将第一数据子集分组成窗口之后,在数据处理硬件处接收最新数据点,该最新数据点与窗口有关,并且通过使用数据处理硬件将最新数据点累加到窗口中以利用最新数据点来细化第一聚合结果。该方法可以进一步包括:在将第一数据子集分组成窗口之后,在数据处理硬件处接收最新数据点,该最新数据点与窗口有关;通过使用数据处理硬件来聚合第一数据子集和最新数据点的组合结果;以及发射该组合结果。
本公开的另一方面提供了一种用于对数据流进行加窗和触发的系统。该系统包括:数据处理硬件和与数据处理硬件通信的存储器硬件。该存储器硬件存储指令,该指令在数据处理硬件上被执行时使数据处理硬件执行操作。该操作包括:接收与流数据或者批量数据中的一个对应的数据;确定接收到的数据的用于计算的内容;确定数据的用于对数据进行切分的事件时间;确定输出接收到的数据的结果的处理时间;以及基于处理时间和事件时间来发射接收到的数据的结果的至少一部分。
该方面可以包括以下可选特征中的一个或者多个:在一些示例中,该操作进一步包括:基于事件时间将接收到的数据分组成窗口。该窗口包括由静态时间周期定义的固定窗口、由时间周期和滑动周期定义的滑动窗口、由超时间隔定义的会话窗口、或者由一对函数定义的用户定义的窗口中的一个。每个固定窗口可以被应用于在相关联的时间周期内的所有数据,每个滑动窗口可以被应用于在相关联的时间周期内的所有数据并且与开始时间相关联,由滑动周期将紧接着的窗口的开始时间与该开始时间分开,并且每个会话窗口可以被应用于在小于相关联的超时间隔的时间跨度内出现的数据的子集。
该操作可以进一步包括:为接收到的数据的每个元素分配可合并窗口,每个元素包括相关联的输入时间戳,并且每个可合并窗口超过相关联的窗口的输入时间戳延伸预定义时间范围。该操作还可以包括:合并可合并窗口中重叠成单个合并窗口、属于相同密钥的两个或者更多个可合并窗口,并且将每个元素的相关联的输出时间戳设置为大于或者等于在相关联的合并窗口或者相关联的可合并窗口中的最早时间的值。单个合并窗口可以包括大于预定义时间范围的相关联的时间范围。
当接收到的数据与流数据对应时,该操作可以进一步包括:通过使用数据处理硬件将流数据分组成窗口,并且通过使用数据处理硬件设置对于流数据的元素的输入时间戳。当对于元素的输入时间戳先于水位线出现时,该操作可以包括:通过使用数据处理硬件来确定流数据包括最新流数据、以及以下步骤中的一个步骤:丢弃最新流数据或者通过创建复制窗口来允许最新流数据在最新流数据的输出中。
在一些示例中,该操作进一步包括:将接收到的数据的第一子集分组成窗口,该窗口定义数据子集的子事件时间;聚合针对窗口的第一数据子集的第一结果;以及确定发射第一数据子集的第一聚合结果的触发时间。该触发时间可以包括以下中的至少一个:当水位线到达窗口的末端时;挂钟时间的每个阈值秒数;在接收到终止窗口的标点记录之后;每个阈值记录数;在任意的用户逻辑决定触发之后;或者在具体触发器的任意组合之后。
在确定发射第一数据子集的第一聚合结果的触发时间时,该操作可以包括:在聚合接收到的数据的后续子集的结果时,抛弃对第一聚合结果的使用。在确定发射第一数据子集的第一聚合结果的触发时间时,该操作还可以包括:在持久状态下将第一聚合结果的副本存储在与数据处理硬件通信的存储器硬件内,并且利用第一聚合结果来细化后续子集的下一个聚合结果。在确定发射第一数据子集的第一聚合结果的触发时间时,该操作可以进一步包括:在持久状态下将第一聚合结果的副本存储在与数据处理硬件通信的存储器硬件内。在与相同的窗口相关联的后续子集的下一个聚合结果发射时:该操作可以包括:发射对第一聚合结果的撤销并且发射窗口的组合会话结果。
在一些示例中,该操作包括:在将第一数据子集分组成窗口之后,接收最新数据点,该最新数据点与窗口有关,并且抛弃最新数据点。该操作还可以包括:在将第一数据子集分组成窗口之后,接收最新数据点,该最新数据点与窗口有关,并且将最新数据点累加到窗口中以利用最新数据点来细化第一聚合结果。该操作可以进一步包括:在将第一数据子集分组成窗口之后,接收最新数据点,该最新数据点与窗口有关;聚合第一数据子集和最新数据点的组合结果;以及发射该组合结果。
在下面的附图和说明中陈述所公开的一个或者多个实施方式的细节。其它方面、特征、和优点将通过说明书、附图和权利要求书而变得显而易见。
附图说明
图1A和1B是示例流计算系统的示意图。
图2是图1的流计算系统的示例加窗应用编程接口(API)的示意图。
图3是固定窗口、滑动窗口、和会话窗口的示例。
图4是窗口时域偏移的示例绘图。
图5是窗口合并操作的示例。
图6A是对数据点输入的窗口时域偏移的示例绘图。
图6B是示出了在单个全局窗口内的输出结果的示例绘图。
图6C是示出了处理时间区域内累加的输出结果的示例绘图。
图6D是示出了来自独立的处理时间区域的输出结果的示例绘图。
图6E是示出了来自独立的处理时间区域的输出结果的示例绘图。
图6F是示出了在水位线升高时分组到固定窗口内的数据点输入和从固定窗口发射的输出结果的示例绘图。
图6G是示出了在连续的微批量中分组到固定窗口内的数据点输入和从固定窗口发射的输出结果的示例绘图。
图6H是示出了更新固定窗口的输出结果的最新数据点的示例绘图。
图6I是示出了基于以处理时间为基础的触发器的输出结果的示例绘图。
图6J是示出了分组到会话窗口内的数据点输入和从组合会话窗口发射的组合输出结果的示例绘图。
图7是执行本文描述的任何系统或者方法的示例计算装置的示意图。
在每个附图中,类似的附图标记指示类似的元素。
具体实施方式
批量数据处理是在没有手动干预的情况下,即在没有人为干预的情况下,在计算机上执行程序(也称为作业)。经由脚本、命令行参数、控制文件、或者作业控制语言来对程序参数进行预定义。程序将数据文件的集合作为输入,然后在产生输出文件的集合之前对数据进行处理。术语“批处理”指的是将输入数据收集成批或者记录的集合,并且以各批为单元进行处理。输出也是重新用于计算的批量。
大规模批量数据处理在行业中是已知的。程序员编写描述某种计算的代码,然后在有限的数据集上运行该代码以产生结果。如果所探讨的计算恰好涉及按照时间进行聚合(例如,分组成固定窗口或者计算每用户会话),则程序员按照窗口大小的批量(对于简单的情况,比如固定窗口)对数据进行处理,或者程序员将加窗逻辑合并到您的计算逻辑(对于复杂的情况,比如用户会话)中。由于基于时间的聚合在分析用户行为模式时非常有用,所以基于时间的聚合实际上是相对常见的。
当程序员正在处理流数据时——与批处理相比,这是一个相对较新的领域,程序员拥有本质上无边界的数据集合,对于该数据集合该程序员想要执行相似计算。但是由于数据缺乏有限边界,所以程序员需要使用(1)在线近似算法(例如,近似Top N)或者(2)确定一种将数据流分成多片的方式。
在线近似算法方法对于一些应用而言可以非常有用,但是,由于结果是近似的,所以其不是批量计算的精确结果的完全替代。因此,程序员最终会并行地运行流系统和批处理系统(例如,Lambda架构):为了实现低延时,采用流处理,而为了得到精确的可重复结果,采用批处理。
将数据流分成有限的片使得有机会按照流处理方式计算精确结果。除了计算一些聚合之外,程序员还必须解决在何处对数据流进行切分以及在何时发射结果的问题。大多数流系统采用基于数据到达系统的时间来自动将数据流分成固定窗口的方法(例如,程序员请求5分钟的窗口,并且当接收到数据时,程序员将该数据缓冲五分钟,然后再对该数据进行处理)。该方法有两大缺点。与大多数批处理系统中的、准确反映事件所发生的时间的基于事件时间的窗口不同,第一个缺点是挂钟时间窗口只反映数据到达系统的时间。在健康的系统中,该时间可能是相当接近事件时间窗口的近似值,但是当数据由各不相同的过程的大集合(例如,分布式网络前端集合)生成时,不能保证并且程序员很有可能会多次发现:大片数据按照不同于实际事件时间定时的定时出现。因此,程序员的流系统成为必须通过批处理系统进行备份以提供精确结果的低延时近似值。第二个缺点是被应用于数据的加窗函数对于所有数据相同。因此,程序员没有办法为该数据的子集生成自定义窗口,该数据的子集例如为捕获特定用户的活动爆发的每用户会话。因此,程序员只能支持程序员在批处理时能够支持的用例的子集。
基于其有力的一致性保证和强大的API(应用编程接口),MillWheel(现在是WindMill,Dataflow流后端)作为用于构建低延时数据处理应用的框架,似乎是不具备前述限制的唯一流系统。MillWheel的API允许程序员基于事件时间按照任意方式对数据进行缓冲,从而在程序员认为有用的任何时候都可以发射结果,包括:与其它系统一样在挂钟时间的周期之后,但同样需要按照数据驱动的方式(例如,接收标点记录)或者在系统认为已经接收到截止给定事件时间(水位线/游标)之前的所有数据之后。程序员可以利用MillWheel来构建流数据处理系统,该流数据处理系统计算出精确的结果并且完全替代生成相同输出的批处理系统,但延时更低。
MillWheel API的较大缺点是其级别较低。MillWheel API提供了所有正确的构建块,但却未按照使程序员容易编写新计算或者构造现有库以构建新计算的方式来抽象化这些构建块。Flume是一种用于高效地采集、聚合、并且移动大量的日志数据的分布式的、可靠的并且可用的服务。Flume具有基于流式数据流的简单且灵活的架构。另外,Flume架构比MillWheel架构的级别更高,从而能够非常容易地链接计算构建块并且将该计算构建块构造成强大而可理解的事物。然而,因为批量Flume API不具备如何分割数据的无边界流以便进行处理的概念,所以批量Flume API并不完全适合流式范例。因此,需要分割数据的无边界流以便进行处理的API(和支持该API的底层架构)。
参照图1A和1B,在一些实施方式中,流计算系统100包括聚合API 200、加窗API300、和触发器API 400,其中,每个API将重点放在流计算处理的单独部分上。
聚合API 200将重点放在程序员正在计算的内容上,例如,总和或者前N个值的列表。加窗API 300将重点放在程序员(在事件时间内)选择对数据10的无边界流进行切分的位置(例如,固定窗口330或者会话350(图3))上。触发API 400将重点放在程序员(在处理时间内)选择在数据10的给定窗口内发射聚合结果20的时间。
聚合API 200在本质上是已经存在于Flume中的批量API。程序员定义在数据10进来时要执行什么计算,并且响应于其生成结果20。加窗API 300允许程序员定义(来自键入的数据10的)给定数据要落入哪个窗口。另外,当(例如,由用户)通过密钥将数据10分组在一起时,加窗API 300允许程序员合并窗口,这允许程序员建立动态的受数据驱动的窗口,比如会话。触发器API 400然后允许程序员定义何时发射窗口内的聚合结果30。示例可如下:当水位线已经到达窗口的末端处(MillWheel中的基于规范时间的聚合模型)时;挂钟时间的每N秒(例如,相较于结果20的完整性,更注重结果20的新鲜度的系统);在接收到终止窗口的标点记录之后;每隔阈值秒数;在任意的用户逻辑决定触发之后;或者具体触发器的任何任意组合(例如,最初是在水位线到达窗口的末端时,然后,在水位线后的最新数据20到达的任何时间每隔一分钟发射一次,在这种情况之后,使数据20得以更新或者改变)。
就表达性而言,流计算系统100提供了清楚的实施过程,这是因为程序员在实施这三个API 200、300、400中的一个API的函数时仅将重点放在手头的特定任务(聚合、加窗、或者触发)上,这是对诸如MillWheel的现有系统(和其它系统)的一种改进,在现有系统中,程序员必须兼顾这三个API,从而产生更难读取和维护的更复杂的代码。流计算系统100可以在计算装置700上执行的计算处理硬件710(图7)上执行。流计算系统100提供了可组合性,这是因为程序员可以混合和匹配来自这三个API 200、300、400的函数以获得精确类型的所需计算。当水位线到达窗口的末端时,可以将用于计算总和的聚合函数210与用于构建会话的加窗函数310和用于产生结果的触发器函数410一起使用。可以仅通过改变加窗函数310和触发器函数410,来使用相同的聚合函数210,以计算固定时间窗口内的总和,其中每个窗口包含10个记录。因此,流计算系统100(其按照批量模式工作)允许程序员构建复杂,但可理解的并且可维护的系统,该系统能精确地计算出程序员想要的结果20。因此,程序员可以通过使用流计算系统100来编写代码,并且允许系统100在流式模式下执行以获得低延时结果,或者在批量模式下执行以进行大规模回填或者进行一些一次性计算。因此,系统100提供多种益处,包括,但不限于:与所附的API和(非平凡)实施方式一起将流计算分解成内容(聚合API 200)、在事件时间内的位置(加窗API 300)、和时间(触发器API 400)这三个轴,并且将批语义和流式语义统一到一个公共机制下
加窗API 300:
参照图2,加窗API 300将流式数据10分组成有限窗口22(固定窗口330、会话350、和滑动窗口340(图3))以便进一步处理和聚合。加窗API 300还将流式数据10分组成由一对函数定义的用户定义的窗口。这对函数可以包括(1)将给定元素分配给窗口集合的assignWindows;以及(2)在分组时间可选地合并指定的窗口子集的mergeWindows。加窗将数据集10切分成有限块,以便作为组进行处理。当处理无边界的数据10时,对于一些操作,需要加窗(以便按照大多数的分组形式来描绘有限边界:聚合、外连接、有时间限制的操作等),而对于其它操作(过滤、映射、内连接等)则不需要加窗。尽管在许多情况下加窗仍然是在语义上有用的概念(例如,回填对先前计算得到的无边界的数据源的部分的大规模更新),但是对于有边界的数据,加窗在本质上是可选的。加窗实际上始终是基于时间的;而许多系统支持基于元组的加窗,其在元素依次具有递增的逻辑时间戳的逻辑时域中本质上是基于时间的加窗。可以将窗口对齐,即被应用于所探讨的时间窗口的所有数据,或者可以不将窗口对齐,即只被应用于给定时间窗口的数据的特定子集(例如,每密钥)。图3强调在处理无边界的数据时遇到的三种主要类型的窗口。
固定窗口330(有时称作滚动窗口)由静态窗口大小定义(例如,每小时窗口或者每日窗口)。通常将固定窗口对齐,即,每个窗口被应用于对应的时间周期内的所有数据10。为了在时间上均匀地散布窗口完成载荷,有时通过使对于每个密钥的窗口相移某一随机值,来使窗口不对齐。
滑动窗口320由窗口大小和滑动周期定义(例如,每分钟开始的每小时窗口)。周期可以小于该大小,这意味着窗口可以重叠。通常也将滑动窗口对齐;即使绘制了产生滑动运动感觉的图,但是所有五个窗口都可被应用于该图中的所有三个密钥,而不仅仅是窗口3。固定窗口实际上是大小等于周期的滑动窗口的特例。
会话330是捕获数据的子集内的一些活动周期的窗口,在这种情况下,按密钥进行捕获。通常,会话由超时间隔定义。将在小于超时的时间跨度内发生的任何事件一起分组为会话。会话是不对齐窗口。例如,窗口2只被应用于密钥1,窗口3只被应用于密钥2,并且窗口1和4只被应用于密钥3。
当对在时间上与事件有关的数据10进行处理时,要考虑两个固有的时域。所涉及的这两个域是事件时间和处理时间。事件时间是事件本身实际发生的时间,即,发生时(生成该事件的任何系统的)的系统时钟时间记录。处理时间是在流水线内的处理期间在任何给定点处观察到事件的时间,即,根据系统时钟的当前时间。注意,我们未对分布式系统内的时钟同步进行假设。
给定事件的事件时间在本质上不会发生变化,但是处理时间随着事件流经流水线对每个事件不断变化,并且时间会永远向前推进。当涉及以发生时间为背景稳健地分析事件时,这是一个重要的区别。
在处理期间,使用中的系统的现状(通信延时、调度算法、处理所耗的时间、流水线序列化等)产生了这两个域之间固有的并且动态改变的偏移量。诸如标点或者水位线的全局进度指标提供了一种将该偏移可视化的好方法。为了达成我们的目的,我们会考虑类似MillWheel的水位线的事物,作为已经通过流水线处理的事件时间的下限(通常启发式地建立)。完整性的概念通常与正确性不兼容,因此,水位线同样也是不可依赖的。然而,当系统认为很可能已经观察到截止事件时间中的给定点之前的所有数据时,水位线确实提供了一种有用的概念,并且从而发现不仅应用于将偏移可视化,而且还应用于监测整体系统健康和进度,以及围绕不需要完整准确性的进度做出决策,诸如,基本的垃圾收集策略。
在理想情况下,时域偏移将会始终为零,并且事件的处理将在事件发生时立即进行。然而,现实并不如此乐观并且通常会导致非零时域偏移。图4示出了示例时域偏移,其中,X轴表示“事件时间”,以及Y轴表示“处理时间”。在12:00左右开始,随着流水线延迟,实际水位线开始偏离理想水位线,在12:02左右的事件时间处,实际水位线回落至接近理想水位线,然后在12:03时,再次出现明显地滞后。该动态偏移变化在分布式数据处理系统中非常常见,并且在定义对于提供正确的可重复结果什么函数性是必要的方面发挥了巨大作用。
对系统的正式模型进行了解释,并且其语义一般足以包含标准批量、微批量、和流式模型、以及Lambda架构的混合流和批语义。针对代码示例,我们将使用Dataflow JavaSDK的简化变型,其本身是FlumeJava API的演进。
首先,我们可以考虑来自典型批量模型的基元。Dataflow SDK具有在流经系统ParDo和GroupByKey的(密钥、值)对上运行的两个核心变换。
ParDo用于通用并行处理。将待处理的每个输入元素(其本身可以是有限的类集)提供给用户定义的函数(在Dataflow中称作DoFn),该函数可以针对每个输入产生零个或者多个输出元素。例如,考虑到扩展输入密钥的所有前缀的操作,在该所有前缀中复制该值:
(fix,1),(fit,2)
↓ParDo(ExpandPrefixes)
(f,1),(fi,1),(fix,1),(f,2),(fi,2),(fit,2)
GroupByKey用于密钥-组(密钥、值)对。针对示例操作:
(f,1),(fi,1),(fix,1),(f,2),(fi,2),(fit,2)
↓GroupByKey
(f,[1,2]),(fi,[1,2]),(fix,[1]),(fit,[2])
ParDo操作基于元素在每个输入元素上运行,从而自然地转换为无边界的数据。另一方面,在将对于给定密钥的所有数据发送到下游以便减少数据之前,GroupByKey操作采集对于给定密钥的所有数据。如果输入源是无边界的,那么我们没有办法知道其何时才会结束。针对该问题的常见解决方案是对数据进行加窗。
支持分组的系统通常重新定义其GroupByKey操作,以在本质上作为GroupByKeyAnd-Window。此处,我们的主要贡献是支持不对齐窗口,对此存在两种关键见解。第一种关键见解是,较为简单的是从模型的角度将所有加窗策略视作不对齐,并且允许底层实施方式在使用的情况下应用与对齐情况相关的优化。第二种关键见解是可以将加窗分解成两个相关操作:
Set<Window>AssignWindows(T数据),其将元素分配至零个或者多个窗口。
Set<Window>MergeWindows(Set<Window>窗口),其在分组时间处合并窗口。随着数据到达并且被分组在一起,这使得受数据驱动的窗口能够随着时间而被构建。
针对任何给定的加窗策略,这两个操作是密切相关的;滑动窗口分配需要滑动窗口合并,会话窗口分配需要会话窗口合并等。
注意,为了本机地对支持事件时间加窗,而不是将对(密钥、值)传递通过系统,我们现在传递4元组(密钥、值、事件时间、窗口)。将元素以及事件时间时间戳(其也可以在流水线中的任何点处被修改)提供给系统,并且最初将元素分配至默认全局窗口,覆盖所有事件时间,从而提供与在标准批量模型中的默认匹配的语义。
从系统的角度而言,窗口分配在已经分配有元素的每个窗口中创建元素的新副本。例如,如下所示(为了简洁起见,按照HH:MM format格式给出时间戳),通过滑动宽度为两分钟并且周期为一分钟的窗口来考虑对数据集加窗。
(k,v1,12:00,[0,∞)),(k,v2,12:01,[0,∞))
↓AssignWindows(Sliding(2m,1m))
(k,v1,12:00,[11:59,12:01)),
(k,v1,12:00,[12:00,12:02)),
(k,v2,12:01,[12:00,12:02)),
(k,v2,12:01,[12:01,12:03))
在这种情况下,复制两个(密钥、值)对中的每一个以存在于重叠元素的时间戳的两个窗口中。由于窗口直接与其所属的元素相关联,所以在应用分组之前,窗口分配可以在流水线中的任何位置处发生。因为分组操作可能被埋在复合转换内部的下游的某个位置(例如,Sum.integersPerKey())处,所以这很重要。
窗口合并作为GroupByKeyAnd-Window操作的一部分出现,并且在图5的示例窗口合并操作的上下文中对该窗口合并进行了最佳的解释。图5针对四个示例数据点使用窗口会话500(还被称为“对会话进行加窗”),四个示例数据点中的三个示例数据点用于k1并且一个示例数据点用于k2,在通过会话对这些数据点加窗时,其具有30分钟的会话超时。最初由系统将所有数据点放置在默认全局窗口中。AssignWindows的会话实施方式将每个元素放到延伸超过其自身时间戳30分钟的单个窗口中;如果将后续事件视作相同的会话的一部分,则该窗口表示后续事件可以落入的时间范围。此后,GroupByKeyAndWindow操作可以开始,这实际上是五部分的复合操作。
DropTimestamps–丢弃元素时间戳,因为从现在起,只有窗口是相关的。GroupByKey–由密钥将(值、窗口)元组分组。MergeWindows–针对密钥合并当前缓存的窗口的集合。由加窗策略定义实际的合并逻辑。在这种情况下,如粗体所指示的,对于v1和v4的窗口重叠,因此,会话加窗策略将窗口合并到单个新的较大会话中。GroupAlsoByWindow–针对每个密钥,通过窗口对值进行分组。在先前步骤中合并之后,v1和v4现在处于相同窗口中,从而在该步骤中,v1和v4被分组在一起。ExpandToElements–利用新的每窗口时间戳将值的每密钥、每窗口分组扩展到(密钥、值、事件时间、窗口)元组中。在该示例中,将时间戳设置于窗口的末端,但是大于或者等于窗口中的最早事件的时间戳的任何时间戳相对于水位线正确性是有效的。
可以通过使用Cloud Dataflow SDK和以下各项来实现在实践中使用加窗来计算键控整数和的以下函数:
PCollection<KV<String,Integer>>input=IO.read(...);
PCollection<KV<String,Integer>>output=input
.apply(Sum.integersPerKey());
可以通过使用如图5中的具有30分钟超时的加窗会话来实现第二示例,在按照下面的示例发起求和之前使用单个window.into调用。
PCollection<KV<String,Integer>>input=IO.read(...);
PCollection<KV<String,Integer>>output=input
.apply(Window.into(Sessions.withGapDuration(Duration.standardMinutes(30))))
.apply(Sum.integersPerKey());
加窗API 300支持用于流式模式和批量模式的Cloud Dataflow。加窗API语义可以包括加窗的高级模型,诸如,但不限于,将元素分配到窗口集合中的Window.into、和将输入元素上的窗口视作辅助键的GroupByKey,因此加窗API语义通过(密钥、窗口)对进行分组。以下是加窗示例:
通知:
<Datum,Timestamp,Window set>
G是全局窗口,GBF是全局WindowingFn,[t1,t2)是表示时间间隔的Intervalbucket。
固定窗口:
{<KV(k1,a),0,G>,<KV(k1,b),5,G>,<KV(k1,c),15,G>,<KV(k2,d),7,G>}
通过GBF加窗
↓
Window.into(FixedWindows.of(10))
↓
{<KV(k1,a),0,{[0,10)}>,<KV(k1,b),5,{[0,10)}>,<KV(k1,c),15,{[10,20)}>,
<KV(k2,d),7,{[0,10)}>}
通过FixedWindows.of(10)加窗
↓
GroupByKeyAndWindows
↓
{<KV(k1,[a,b]),9,{[0,10)}>,<KV(k1,[c]),19,{[10,20)}>,<KV(k2,[d]),9,{[0,10)}>}
通过FixedWindows.of(10)加窗
滑动窗口:
{<KV(k1,a),10,G>,<KV(k1,b),15,G>,<KV(k1,c),25,G>,<KV(k2,d),17,G>}
通过GBF加窗↓
Window.into(SlidingWindows.of(20).every(10))
↓
{<KV(k1,a),10,{[0,20),[10,30)}>,<KV(k1,b),15,{[0,20),[10,30)}>,
<KV(k1,c),25,{[10,30),[20,40)}>,<KV(k2,d),17,{[0,20),[10,30)}>}
通过SlidingWindows.of(20).every(10)加窗
↓
GroupByKeyAndWindows
↓
{<KV(k1,[a,b]),19,{[0,20)}>,<KV(k1,[a,b,c]),29,{[10,30)}>,<KV(k1,[c]),39,{[20,40)}>,<KV(k2,[d]),19,{[0,20)}>,<KV(k2,[d]),29,{[10,30)}>}
通过SlidingWindows.of(20).every(10)加窗
会话:
{<KV(k1,a),0,G>,<KV(k1,b),5,G>,<KV(k1,c),15,G>,<KV(k2,d),7,G>}
通过GBF加窗
↓
Window.into(Sessions.withGapSize(10))
↓
{<KV(k1,a),0,{[0,10)}>,<KV(k1,b),5,{[5,15)}>,<KV(k1,c),15,{[15,25)}>,
<KV(k2,d),7,{[7,17)}>}
通过Sessions.withGapSize(10)加窗
↓
GroupByKeyAndWindows
↓
{<KV(k1,[a,b]),14,{[0,15)}>,<KV(k1,[c]),24,{[15,25)},<KV(k2,[d]),16,{[7,17)}>>}
通过Sessions.withGapSize(10)加窗
针对SomeUnspecifiedCrazyWindowFn的通用情况:
{<KV(k1,a),ta,G>,<KV(k1,b),tb,G>,<KV(k1,c),tc,G>,<KV(k1,d),td,G>,<KV(k2,e),te,G>}
通过GBF加窗
↓
Window.into(SomeUnspecifiedCrazyWindowFn)
↓
{<KV(k1,a),ta,{b1,b2}>,<KV(k1,b),tb,{b1,b3}>,<KV(k1,c),tc,{b4}>,<KV(k1,d),td,{}>,
<KV(k2,e),te,{b1,b2}>}
通过SomeUnspecifiedCrazyWindowFn加窗
↓
GroupByKeyAndWindows
(Assume b3and b4merge into b3-4)
↓
{<KV(k1,[a,b]),t(b1,[ta,tb]),{b1}>,<KV(k1,[a]),t(b2,[ta]),{b2}>,<KV(k1,[b,c]),t(b3-4,[tb,tc]),{b3-4}>,
<KV(k2,[e]),t(b1,[te]),{b1}>,<KV(k2,[e]),t(b2,[te]),{b2}>}
通过SomeUnspecifiedCrazyWindowFn加窗
GroupByKeyAndWindows的细节:
输入
{<KV(k,v1),t1,{b1}>,<KV(k,v2),t2,{b2}>,<KV(k,v3),t3,{b3,b4}>}
↓
擦除时间戳,并且通过密钥进行分组
k→{<v1,{b1}>,<v2,{b2}>,<v3,{b3,b4}>}
↓
扩展窗口集合
k→{<v1,b1>,<v2,b2>,<v3,b3>,<v3,b4>}
↓
合并窗口。在该示例中,映射是:
b1,b3→b5
b2→b6
b4→b7
k→{<v1,b5>,<v2,b6>,<v3,b5>,<v3,b7>}
↓
通过窗口进行分组
k→{b5→[v1,v3],b6→[v2],b7→[v3]}
↓
计算时间戳并且转换至元素。
{<KV(k,[v1,v3]),t(b5),{b5}>,<KV(k,[v2]),t(b6),{b6}>,<KV(k,[v3]),t(b7),{b7}>}
再次参照图2,加窗API 300包括加窗接口320。该加窗接口320包括时间戳设置器函数322和窗口访问器函数324。
时间戳设置器函数322在输出元素之前在步骤上下文中更新时间戳。时间戳设置器函数322的示例可以包括:
在批量模式和流式模式下,能够设置或者修改PCollection(其是作为计算的基本目标的元素的不可变分布式类集的表示)中的元素的时间戳是有用的。在批量模式下,任意地设置时间戳是安全的;然而,在流式模式下,设置输出元素上的时间戳可以产生将不会由剩余的流水线进行适当处理的最新数据(例如,(多个)最新数据点),相较于其对应的输入元素上的时间戳,输出元素上的时间戳过去的时间更长。
在流中存在对该规则的两个警告:第一个警告,如果DoFn可以提供对于其将时间戳向后移位的量的静态限制,程序员可以将水位线提高这个量并且仍然恰当地对数据进行处理;第二个警告,有时产生最新数据是期望的行为,并且可以利用触发器来切合实际地处理最新数据。因此,系统100在时间戳设置器函数322内提供两个提出的API,以处理在流中向后移位的时间戳。
选项1 322a:要求用户提供将要向后移位多少时间戳。
//返回输出时间戳可以小于其对应的输入时间戳的最大数量
long DoFn.lateDataHorizon()
选项2 322b:如果在流中调用outputWithTimestamp,则迫使用户设置OutputTimestampMode。
//在默认情况下,DoFn.getOutputTimestampMode返回UNBOUNDED_PAST模式,这在针对流式模式的DoFnContext.outputWithTimestamp中是不允许的。
窗口访问器函数324(例如,DoFn.ProcessContext.windows())是访问窗口的一种方式,但是实际上,只在GroupByKey之后访问窗口才有意义,并且在这种情况下,每个元素将仅处于单个窗口中。
加窗API 300使用触发器来处理最新数据。在没有触发器的情况下,加窗API 300使用两种可能的方法来处理最新数据。加窗API 300可以丢弃将不会被分组成正确窗口的最新数据,或者加窗API 300可以允许最新数据在GroupByKeyAndWindows的输出中创建复制窗口。加窗API 300可以选择其中一个选项或者使选项在流水线级别处或者窗转换上可配置(在本质上产生了非常差的触发近似/子集)。
对MergeWindows的需求:
在一些示例中,可能难以做出任意的窗口函数是确定性的。相反,系统100可以精确地量化窗口函数何时是确定性的。如果无论何时都准备发射窗口,则WindowingFn将会是确定性的,WindowingFn可能会合并的任何窗口必须已经是已知的,并且WindowingFn必须与所有窗口合并。
在一些实施方式中,系统100通过洗牌(shuffle)来提供批量支持。在一些示例中,对于遵循元素的逻辑时间顺序的相同工作器(worker),系统100处理对于给定密钥的所有KV。然后,工作器可以利用当前流代码,并且对数据进行处理,就好似这些数据来自于流。系统100执行以下项以通过洗牌来支持批量:1)ShuffleSink将时间戳和窗口编码成ShuffleEntry.value,并且使用时间戳作为密钥(排序键)。2)创建SortedShuffleSource以读取对于相同密钥的所有KV并且利用以下接口来返回结果:
以下是可以由系统100执行的示例性用户代码:
构建不对齐的事件时间窗口的能力是一种改进,但是还需要解决两个缺点。第一,系统100需要提供对基于元组的窗口和基于处理时间的窗口的支持,否则,加窗语义将相对于现有的其它系统而退化。第二,系统100必须知道要在何时发射窗口的结果20。由于包括多个数据点的数据10相对于事件时间是无序的,所以系统100需要一些其它信号来通知窗口何时结束。
在系统100建立针对窗口完整性问题的解决方案之后,下文解决了基于元组的窗口和基于处理时间的窗口的问题。针对窗口完整性,用于解决其的初始倾向可能是使用某种全局事件时间进度指标,诸如,水位线。然而,相对于正确性,水位线本身具有两大缺点。
水位线的第一个缺点是水位线有时过快,这意味着可能会存在在水位线之后到达的最新数据10。针对许多分布式数据源,导出完美的事件时间水位线是比较困难的,因此,如果在输出数据的结果20中期望达到100%正确,则仅仅依赖水位线是不可能实现的。
水位线的第二个缺点是其有时过慢。因为水位线是全局进度指标,所以可以通过单个缓慢的数据来对整个流水线抑制水位线。甚至对于在事件时间偏移方面变化较小的健康的流水线,根据输入源,偏移的基线水平仍然可以是几分钟或者更长。因此,例如,与可比较的Lambda架构流水线相比,使用水位线作为用于发射窗口结果20的唯一信号很可能会产生更高的整体结果的延时。
为此,系统100假定仅有水位线是不够的。在解决完整性问题方面的有用见解是Lambda架构有效地避开了这个问题:其不能通过以某种方式更快地提供正确的答复来解决完整性问题;一旦批量流水线运行,其就只能向流式流水线可以提供的结果的最佳的低延时估计提供最终的一致性和正确性的承诺。在批量作业运行时,批量作业的输出只有在输入数据10完成时才会是正确的;如果数据10随着时间而演进,在必须对数据10进行检测并且重新执行批量作业。从单个流水线起(无论执行引擎如何),系统100将需要对任何给定窗口提供多个答复(或者窗格(panes))的特征。该特征包括允许指定何时触发给定窗口的输出结果20的触发器或者触发时间。
触发器是响应于内部信号或者外部信号而刺激GroupByKeyAndWindow结果20的产生的机制。触发器是对窗口模型的补偿,因为其分别沿着不同的时间轴来影响系统行为。加窗确定事件时间数据10被分组在一起以便进行处理的位置。触发确定在处理时间中何时将分组的结果20作为窗格进行发射。诸如水位线触发器的特定触发器利用其提供的函数性中的事件时间,但是其在流水线内的效果仍然能够在处理时间轴中实现。
在一些实施方式中,系统100提供预定义触发器实施方式以便响应于数据10的到达(计数、字节、数据标点、模式匹配等),在处理时间中的多个点处,在完成估计(例如,当相较于处理输入数据10的每一最新片,更期望迅速处理输入数据10的最小百分比时,提供用于处理在批执行引擎和流执行引擎二者中的落后者的有用的语义的水位线,包括:百分位水位线)处进行触发。在一些示例中,系统100支持将触发器组合成逻辑组合(和、或等等)、循环、序列、和其它这种构造。另外,用户可以通过利用执行运行时间的底层基元(例如,水位线定时器、处理时间定时器、数据到达、组合支持)和任何其它相关外部信号(数据注入请求、外部进度指标、RPC完成回调等)来定义其自身的触发器。
除了在系统100发射结果20时进行控制之外,触发器API 400还提供了一种经由三种不同的细化模式来控制相同窗口的多个窗格如何彼此相关的方式:
第一细化模式是抛弃:在触发时,抛弃窗口内容,并且后续结果20与先前结果20不相关。在数据的下游消费者(位于流水线的内部或者外部)期望来自各种触发器启动的值能够独立的情况下(例如,当将这些值注入到生成已注入的值的总和的系统中时),该模式是有用的。在已缓冲的数据20的数量方面也是最高效的,尽管对于可以模式化为DataflowCombiner的关联并且交替的操作而言,效率增量通常会达到最低。对于视频会话用例而言,这还不够,这是由于要求数据10的下游消费者将局部会话连拼接在一起是不现实的。
第二细化模式是累加:在触发时,将窗口内容保持持久状态下的原样,并且后续结果20是对先前结果20的细化。当下游消费者在接收到相同窗口的多个结果20时期望利用新数据来重写旧数据时,这是有用的,并且对于用于Lambda架构系统中的模式是有效的,其中,流式流水线产生了低延时结果,然后在将来通过来自批流水线的结果20来重写该低延时结果。对于视频会话而言,如果系统100当前仅仅计算会话,然后立即将这些会话写入支持更新的一些输出源(例如,数据库或者密钥/值存储器),则这可能是足够的。
第三细化模式是累加&撤销:在触发时,除了累加语义之外,在持久状态下还存储了已发射的值的副本。当窗口在未来再次触发时,首先将发射对先前值的撤销,随后是作为标准数据的新值。简单的撤销处理的实施方式需要确定性操作,但可以利用附加复杂性和成本来支持非确定性;我们已经发现了需要非确定性的用例,诸如,概率建模。由于在将由单个窗口通过随后的触发器启动而生成的多个结果在下游进行分组时,这些结果可以在单独的密钥上结束,所以在具有多个串行GroupByKeyAnd-Window操作的流水线中撤销是必要的。在这种情况下,除非经由撤销通知了应该保留原始输出的效果的,否则第二分组操作将为这些密钥生成错误的结果20。同样可逆的Dataflow Combiner操作可以经由未组合的方法高效地支持撤销。对于视频会话,这种模式是理想的。如果系统100正在会话创建的下游执行依赖会话本身的特性的聚合,例如,通过检测不流行的ad(诸如,在大多数会话中,观看时间小于5秒的ad),作为随着时间而演进的输入,例如,作为恢复在线并且上传会话数据的大量的离线移动观看者,初始结果20可以是无效的。撤销为我们提供了一种在具有多个串行分组阶段的复杂流水线上适应于这些类型的变化的方式。下文讨论了触发系统的一些特定实施方式。
触发器API 400提供了表达在Dataflow/Streaming Flume内应该在何时(在处理时间内)发射聚合的结果20的结构化的、可组合的方式。触发器API 400连同聚合API 200和加窗API 300一起工作,这分别实现了对聚合的结果20是什么以及(在事件时间内)在何处执行聚合的表达。触发器API 400的目标是相对于标准MillWheel,克服现有StreamingFlume/Dataflow API中的大量缺点。这些缺点中的一些包括:
●最新数据—Streaming Flume用户无法管理最新数据(即,在水位线的后面到达的数据)。现有系统仅丢弃最新数据,即使在短期内这也是不现实的。
●推测性数据—一些MillWheel消费者通过使用百分位水位线或者其它基于数据的启发来手动地执行推测性聚合或者局部聚合,Streaming Flume当前不对此进行支持。
●挂钟时间聚合—许多MillWheel流水线不注重水位线,但仍想要提供某种周期性加窗聚合。挂钟时间定时器提供了一种提供定期更新的方式,该更新包含迄今为止已经接收到的任何数据,不论当前可能正在运行的其余流水线多快或多慢。
●数据驱动聚合—不需要水位线的另一种聚合分类是通过数据本身来驱动的聚合分类,例如,散列连接或者字节限制聚合。通过使用现有的Streaming Flume API(经由自定义WindowFns和/或State API)来支持这些模式中的大多数,但是可能期望将现有的Streaming Flume API与广义的聚合触发器API相结合,这是由于这将会为将数据驱动触发器与其它触发器组合创造可能性(例如,在挂钟时间延时之后超时的散列连接;当前您只能使用流时间延时)。
水位线:MillWheel提供水位线(或者游标)以作为推理流式流水线中的数据的完整性的方式。在默认情况下,水位线评估时间点,截止该时间点之前,已经接收到或者处理了给定流的所有数据。这仅在系统100认为其已经发现所有相关数据后允许执行时间边界聚合。
然而,在数据注入点处(即,在接收到数据时)建立水位线,并且从该数据注入点处传播水位线。对于许多数据源而言,不可能提供完全精确的水位线。例如,考虑到日志文件,日志注入器可以基于日志注入器在任何给定时刻正在扫描的日志文件集合来创建水位线,但是如果日志保护程序延迟了一段时间,则新日志文件能够在注入器已经将水位线升高之后到达。在这些最新日志文件中的数据现在是最新的。然后,下游计算将要负责决定如何处理最新数据。在一些情况下,可以将该下游计算包含到现有结果中。在其它情况下,最好只是丢弃最新数据。MillWheel未提供用于处理最新数据的结构化框架,只提供了检测最新数据的最小基础设施。Streaming Flume当前未提供与最新数据交互的方法;StreamingFlume仅丢弃最新数据。
百分位水位线:MillWheel还支持百分位水位线的概念,这可以给您提供估计时间的水位线,截止该时间之前,系统100已经对一些特定的数据子集(例如,95%)进行了处理。系统100可以使用百分位水位线,而不是标准水位线,来提供推测性结果。这可以用于更快地提供结果,这在一定程序上减少了信心。然而,给定计算当前只可以利用唯一一种类型的游标(100%或者单个特定信元的百分位)。因此,从配置角度而言,提供复杂的,分层的推测性结果的集合是费时费力的,并且目前不可能超过两个层次。
挂钟时间聚合:虽然水位线是在MillWheel中触发聚合的最常见的方式,但是存在其它类型的触发器更为实用的情况。在数据的时限性比任何特定的完整性概念更为重要的情况下,可以使用挂钟时间来提供迄今为止所聚合的数据的周期性更新。这确保程序员能够及时更新,即使是面临由于数据的较小部分明显落后于数据的其它部分而造成的水位线延迟。
数据驱动聚合:而且,存在非基于时间的聚合的整个类。示例是散列连接,由若干记录或者字节限定的聚合或者在数据本身的一些特征上触发的聚合(例如,具有特定值的数据的特定字段)。
复合聚合:在一些示例中,想要构成多种类型的聚合是相当常见的。通常,散列连接将具有超时。在这种示例中,可以使用当前系统100,具有流时间超时的StreamingFlume,而不是挂钟时间。在一些示例中,程序员想要在水位线达到100%时接收单个初始聚合,然后在最新数据到达时进行周期性(基于挂钟时间)更新。推测性数据在本质上是另一种类型的复合聚合(针对期望的百分位水位线值)。
在一些示例中,组合聚合的问题,无论是针对最新数据10、推测性数据、或者一些其它自定义组合,都会提出以下问题:当您的数据集的概念随着时间而变化时,您如何提供对聚合的结果的细化?
可以考虑几个选项来处理对流式流水线中的聚合的更新。选项1:提供多个版本的聚合和管理多个版本的聚合的方法。当提供多个版本时,存在系统100可以支持的两种模式。在第一种模式下,随后的聚合包含迄今为止能够发现的所有数据10。在这种情况下,新聚合20将会仅替代旧聚合20。在第二模式下,从最新聚合20起,随后的聚合20只包含新数据10。在这种情况下,如果需要和/或可行的话,必须将新聚合20与先前聚合20手动地组合。第一选项和第二选项包括具有利弊的清理服务,利处可以包括,但不限于:API半自动清理(不同版本的聚合仍然具有相同类型);用户曾经指定其聚合逻辑,系统注意按需多次应用该聚合逻辑;由于系统已经提供了多个版本的聚合(可通过时间戳区分),其中,以StreamingFlume进行加窗,因此,将版本扩展到新维度是相对自然的:(1A)在没有来自用户的额外工作的情况下,更新的聚合20即时可用;以及(1B)不需要针对一些最新数据范围来保持聚合状态。弊处包括(1A)必须保持聚合状态,直到不再允许最新数据为止。对于日志源而言,在绝佳化(goldenization)达到100%正确之前,将会花费两天时间。状态大小取决于所执行的聚合的类型。组合器:当利用combineValue来执行聚合时,只需要存储中间数据聚合(例如,用于平均计算的sum+count)。这产生整体数据存储大小:
O(PARTIAL_AGGREGATE_SIZE*NUM_WINDOWS_IN_HORIZON)。
全数据:非组合器聚合需要在时间范围之前存储建立好的整个输入数据。这产生整体数据存储大小:
O(INPUT_SIZE_OVER_HORIZON)。
(1A)先前聚合20必须不与任何其它下游累积聚合20组合。这导致了冗余的工作,并且当新聚合洗牌到与旧聚合不同的密钥时,还引入racy语义。(1B)用户必须进行额外的工作来将新聚合与旧聚合组合。
另一选项(选项2)提供了初始聚合,并且对原始随后数据10(即,“增量”)提供对初始聚合的访问。该选项包括利处,诸如,但不限于:无需保持聚合状态。弊处为,API更加复杂;聚合和增量可以具有不同的类型。您来自操作的输出现在是Pair<Aggregate,Delta>吗?或者您要求用户对其代码路径进行分叉(fork)吗?这会破坏原子性;用户必须为初始聚合指定过其聚合逻辑,然后再次为并入增量更新而第二次指定其聚合逻辑。许多种类型的聚合不经由增量来支持更新,因此,不适合此方案。
考虑到利弊列表,选项#1A和#1B是系统100可以针对触发执行的解决方案:
因此,为了解决上述的各种用例,系统100为窗口修改调用Window.into以允许用户指定指示何时发射聚合20的触发器以及随后聚合20与先前聚合20相关的方式:
windowBy(WindowFn,TriggerStrategy);
Dataflow:Window.into(WindowingStrategy,TriggerStrategy);
TriggerStrategy对象在本质上是命名值的元组:
1.触发器—指示将在何时发射聚合20,例如,首先在100%水位线百分位处,然后是最多两天内的每隔10个挂钟时间秒数的最新数据聚合20(若存在)。
2.累加模式—指示后续聚合20是否包括来自先前聚合20的数据10(即,当触发窗口时,是否清理窗口内容)。
3.增量模式—指示是否发射先前聚合的反数据,以允许下游聚合的增量更新。
API,高级别:系统100提供了高级方式来描述在GroupByKey操作内在加窗期间应该在何时产生聚合20,以及经由修改的windowBy/Window.into操作,多个版本的聚合20如何彼此有关以及是否会执行增量更新。
SF:windowBy(WindowFn,TriggerStrategy)
Dataflow:Window.into(WindowingStrategy,TriggerStrategy)
如上文提到的,TriggerStrategy是概略的元组<Trigger,AccumlationMode,IncrementalMode>。
触发器在本质上是类似于DoFn的类,其具有在加窗期间在特定点处由系统100调用的方法。这些方法将有关所探讨的窗口和值的各种参数作为输入,可以操纵每窗口和触发器的持久状态和时间,并且可以发射触发信号以指示应该何时在下游发射窗口的内容。以下对于用于实施触发器的API的更多细节将被包括在实施方式部分中。
与加窗API 400一样,自定义触发器实施方式相对较少。从终端用户的角度而言,更有趣的部分是我们提供的预构建触发器的库。
触发器库包含简单触发器和复合触发器(尽管在简单触发器与复合触发器之间的区别主要是语义)。示例简单触发器包括:
●WatermarkPercentile(浮点数百分位)—当给定水位线百分位到达窗口的末端时,发射聚合,其中,百分位的范围是(0.0,100.0]。在覆盖下,这些将经由水位线定时器来实现。注意,最新窗口按照定义将不会启动这种类型的触发器。AtPeriod(DateTime参考、长期、TimeUnit单元、TimeDomain域)--通过使用给定周期,在与给定参考时间(参考可以是任何有效的DateTime)对齐的下一个时间窗口的末端处发射窗口的聚合。当重复运行时,使得能够发射周期性聚合,例如,每隔周期秒。TimeDomain可以是STREAM_TIME或者WALL_TIME。在覆盖下,将经由水位线或者挂钟时间定时器来实施这些。AfterDelay(长延时、TimeUnit单元、TimeDomain域)--在发现窗口中的第一数据之后的一些时间量,例如在延时秒之后,发射聚合。TimeDomain可以是STREAM_TIME或者WALL_TIME。在覆盖下,这些将经由水位线或者挂钟时间定时器来实现。
●AfterBytes(长计数)--在已经发现字节的计数之后,发射聚合。
●AfterCount(长recordCount)--在已经发现记录的计数之后,发射聚合。
●自定义触发器—为每个记录调用用户提供的触发器接口的实施方式。
可以通过使用该API来实施上文的AfterByte和AfterCount触发器。Z3的推测性差异也是如此。这在本质上提供了与调用WindowSet.emit以提早发射窗口的自定义WindowFn.merge调用的语义相同的语义。
示例复合触发器包括:
●FirstOf(Trigger...triggers)–将最多允许启动所提供的触发器中的一个。
●SequenceOf(Trigger...triggers)–将允许按顺序启动指定的触发器。
●Repeat(Trigger trigger)–在启动之后,将重新设置指定的触发器并且将允许不断再次启动指定的触发器。
●RepeatUntil(Trigger trigger,Trigger until)–除了在the until Trigger启动时重复结束之外,与重复相同。
●RepeatCount(Trigger trigger,int count)–除了触发器启动计数次数之外,与重复相同。
考虑到这些基元,您可以表达若干有用的聚合模式。例如:
●发射90%和100%水位线百分位聚合,然后是准点地每隔挂钟时间小时的最新数据聚合(当其存在时),直到已经处理了两天的数据为止:
执行重复的散列连接,每个散列连接具有一小时挂钟时间超时。这很可能会与GlobalWindowFn/GlobalWindow一起使用,但是不必一定如此:
每天早上8点发射全局聚合(例如,在所有时间内发现的全局记录计数)。该用例是使用Streaming Flume定时器API的动机之一。考虑到加窗触发器,可以弃用定时器API(并且我们当前还没有针对Data Flow将其公开)。
AccumulationMode枚举可以具有四个可能的值:
●CLEAR_ALWAYS–不会累加在触发器调用内的值,从而忽略来自触发器实施方式的显式累加请求。
●CLEAR_BY_DEFAULT–除非触发器实施方式显式请求累加,否则进行清理。
●ACCUMULATE_BY_DEFAULT–除非触发器实施方式显式请求清理,否则进行累加。
●ACCUMULATE_ALWAYS–始终累加在触发器调用内的值,从而忽略来自触发器实施方式的显式清理请求。
IncrementalMode支持值ENABLED或者DISABLED。如果使能,则系统将支持经由反数据(例如,标记为用于对来自先前发射的聚合的效果求逆的数据)对在下游聚合中的先前聚合值的效果求逆。该特征足够复杂,该特征授权其自身的设计文档,并且不包括在任何初始的Dataflow或者Flume实施方式中。
AccumulationMode.ALWAYS和IncrementalMode=true的组合实际上是上文的选项1A。而AccumulationMode.NEVER和IncrementalMode=false的组合实际上是上文的选项1B(系统的默认模式)。
当最终由密钥进行分组时,GroupByKey的结果可以包括多个版本的任何给定聚合。可通过这些版本的产生时间值以及生成其的关联的触发器来区分这些版本(如下文低级别API部分中进一步描述的)。
在试图迫使用户明确考虑何时适合发射其聚合时,将弃用windowBy的单参数版本。尽管如此,将以这种方式来实现:提供仅在100%水位线处发射的原始语义,丢弃所有随后的最新数据,例如:
处理上下文API:标准ExecutionContext/ProcessingContext类可以获取提供低级别的每值指标的一些新方法,以解释多个版本的聚合。
●Integer ExecutionContext.getWatermarkPercentile()–为系统中的任何值提供水位线百分比。这将是[0,100]中的整数,或者如果在100%输出水位线后产生了该值(即该值为最新的),则其为空值。按照定义,水位线百分比将是水位线值>=产生时间处的给定值的事件时间的小块/范围的分数。对于内部MillWheel,将会经由预定义百分位水位线的集合来做出水位线百分比。对于云MillWheel,如果我们提供了水位线直方图,那么我们可以通过直方图推导出水位线百分比。
●long ExecutionContext.getProductionTime()–返回值的产生时间。可以用于按照时间顺序来区分多个版本的聚合。
●Trigger ExecutionContext.getTrigger()–提供生成该值的触发器(若存在)。针对非聚合值,返回空值。例如,检查该值将允许您确定数据是否为最新数据。
●boolean ExecutionContext.isAntiDatum()–如果数据是反聚合(或者有时来源于反聚合),则为真。用于不与具有和AccumulationMode.Cumulative一起运行的多个聚合阶段的流水线中的先前聚合组合。
当最终由密钥进行分组时,这会产生至少两个版本的每个窗口:一个适合于95%的数据,并且一个适合于100%的数据。如果任何最新数据达到,那么您还将获得对于每个最新数据的聚合的更新版本。
Flume触发器API的实施方式:经由Trigger<B extends Window,T>类的子类来实施简单触发器。该类由通过加窗API 400调用的三种抽象方法组成,每个方法接收提供可用于给定上下文中的所有操作的指定的上下文类。
●onDatum—在首先将数据并入窗口中之后立即对其进行调用。设置有窗口和(未并入的)值。可以经由Window.peekValue()访问窗口的完全聚合值,如果不使用AggrFn,则这可能会较为昂贵。可以读取/编写窗口的每标签状态。可以检查所有时域中的当前时间。可以设置/删除窗口的每标签定时器。可以触发或者清理窗口值。可以标记已完成Trigger。
●onMerge—在已经发生窗口合并之后立即对其进行调用。设置有源窗口和合并窗口。可以读取源窗口的每标签状态,并且编写合并窗口的每标签状态。可以检查所有时域中的当前时间。可以检查源窗口的每标签定时器并且设置合并窗口的每标签定时器。可以触发并且清理窗口值。可以标记已完成Trigger。在回调完成时(经由用于重新设置的调用)将删除源窗口的所有状态和未启动定时器。
●onTimer—当通过触发器启动而设置定时器时对其进行调用。设置有窗口和定时器标签以及域。可以读取/编写窗口的每标签状态。可以检查所有时域中的当前时间。可以设置/删除窗口的每标签定时器。可以触发并且清理窗口值。可以标记已完成Trigger。
注意,为了在执行兼容操作时允许根据多个不同的回调来编写和使用辅助方法,公共上下文方法(诸如,lookupState)被定义在其自身的接口中,例如:
interface LookupStateContext{
<V>V lookupState(String tag,Coder<V>coder);
}
注意,将计时器提升为第一类对象。这要求系统100在覆盖下在持久状态下追踪所有定时器,但是减轻了用户这样做的负担(在处理定时器时,这是持久状态的常见用法),并且允许系统100在垃圾收集期间自动为触发器清理所有定时器。
集成到现有加窗系统中是相对简单的,其中,两个主要的调用点是在将数据并入到窗口(对于onDatum)中之后,并且在已经由WindowingStrategy的合并功能(对于onMerge)对窗口进行合并之后。
更感兴趣的是如何支持复合触发器的创建,例如,FirstOf、SequenceOf等。将通过使用CompositeTrigger类来实施复合触发器,这提供了Trigger的函数性的超集(并且确实是其的实际超类)。CompositeTrigger中的每个上下文将支持一个或者两个附加功能:
●invokeChild–调用给定子触发器上的当前回调。可用于所有操作(onDatum、onMerge、onTimer、重新设置)。在覆盖下,追踪截止目前的子触发器的类群,从而通过使用该类群来为由任何给定的子触发器操纵的所有状态和定时器提供唯一的命名空间。还允许void invokeChild(Trigger trigger);
triggerHistory—返回已经在该回调的生命期期间调用ctx.trigger()方法的子触发器的序列,作为TriggerEvent对象(该对象捕获调用触发器以及是否请求清理)的列表。可用于其上下文类包括触发方法(onDatum、onMerge、onTimer)的所有操作。注意,由triggerHistory返回的触发器严格上讲在该特定触发器的直系后裔(例如,孙触发器将不会直接出现在该函数调用的结果中,尽管其可以导致子触发器出现)中。
TriggerHistory triggerHistory();
另外,CompositeTrigger提供了允许父辈挂接到子定时器回调中的第四回调,这是由于定时器的作用域虽是特定触发器,但可能对父辈有影响:
●onChildTimer—当由子触发器启动来设置定时器时对其进行调用。设置有窗口、子定时器、和定时器标签、即时、和域。可以读取/编写其自身的每标签状态和窗口的每标签状态。可以检查所有时域中的当前时间。可以检查/设置/删除其自身的窗口的每标签定时器。可以触发并且清理窗口值。可以标记已完成Trigger。可以调用子定时器。可以检查由子做出的任何触发器调用。
通过使用这些API,系统100能够提供MillWheel API的完整表达性,而通常不要求终端用户处理底层低级别API的复杂性。对于一组示例触发器实施过程,参见下文。
磁盘状态:触发器存储以下磁盘状态。
●用户标签/值对。
●用户定时器(在定时器系统中)
●用户标签/定时器对(在持久状态下)
●如果使能了增量模式,则窗口的最新发射值的快照。
●被标记为完成的触发器的碑石(tombstone)。
累加模式:
当决定是否要自动清理关于触发器调用的窗口值以及是否要服从来自触发器实施方式的清理调用时,系统100可以遵循针对当前TriggerStrategy而设置的累加模式的方向。
增量模式:在触发窗口的任何时候,将生成由窗口的先前值组成的反数据。
当在增量模式下合并窗口时,也要合并其最新发射值(若存在)。在下游,在反数据上的所有non-GroupByKey操作产生了更多的反数据(与时间戳传播类似)。当达到GroupByKey操作时,将反数据馈送到未组合方法中。然后未组合的结果是标准数据,而不是反数据;然而,如果该GBK的TriggerStrategy使能增量模式,则还将发射该窗口的先前值的反数据。系统100最初未以用于任何Dataflow/Flume产品的增量模式支持为目标;特征很可能应获得所有其自身的设计文档。
MillWheel:MillWheel可以经由注释支持额外的元数据(例如,与针对窗口的情况类似):
●将在触发器启动时添加触发器元数据。
●将在注入器处的原始数据处和触发时间处的聚合数据上注释水位线百分位。
●将反数据标记为在其被发射时的样子。
提供水位线百分位的细粒度评估将需要追踪全局水位线直方图,而不是单个最小水位线值。为WindMill计划水位线直方图。需要将水位线直方图添加至MillWheel。
在该API中的两个特征需要对多个定时器管理器的支持:
●任意的水位线百分位触发器。
●包含水位线和挂钟时间定时器的TriggerSets。
利用对多个定时器管理器的支持来构建WindMill,并且WindMill应该能够支持开箱即用的水位线+挂钟时间特征。对多个水位线百分比的支持不应该过于困难。MillWheel可能需要重构定时器管理器代码以支持特征。
附录A—示例触发器实施过程
//在所有序列被合并的最小索引处开始,
//合并并查找所有触发器,直到您获得不触发的索引值或或用尽索引值为止
//用于合并的invokeChild足够智能,并不试图触发已经完成的触发器(并且如果只存在一个未完成的子触发器则不调用合并)
图6A-6I示出了强调系统100支持的多个有用的输出模式的示例绘图600、600a-i。在整数总和流水线的上下文中图示了示例绘图600。
PCollection<KV<String,Integer>>output=input.apply(Sum.integersPerKey());
使用系统100从其接收包括10个数据点的数据10的输入源,每个数据点与较小的整数值相关联,并且在有边界的和无边界的数据源的上下文中由系统100对每个数据点进行分析。为了图示的简单性,在示例绘图600中系统100假设接收到的数据10的数据点适用于相同密钥;然而,在真实流水线中,由系统100执行的操作将针对多个密钥并行发生。图6A是示出了对接收到的数据10的数据点输入的窗口时域偏移的示例绘图600。X轴以事件时间(即,当事件实际发生时)绘制了数据10,而Y轴以处理时间(即,当流水线观察到其时)绘制了数据10。除非另外规定,否则所有绘图600、600a-i假设在流式引擎上执行。
许多绘图600还将取决于被包括在绘图600中的水位线。在这些场景中,绘图600示出了理想水位线和示例实际水位线。有斜率的直虚线表示理想水位线,即,如果不存在事件时间偏移并且所有事件在其发生时均由系统100进行了处理。考虑到分布式系统的不确定性,偏移是常见事件;如图6A的绘图600a所示,通过从理想水位线得出的实际水位线的曲折路径来对此进行例证。还要注意,通过具有出现在水位线后面的值9的单个“最新”数据(例如,数据点)来对该水位线的启发式性质进行例证。
如果系统100要通过使用所描述的总和流水线对在典型批处理系统中的接收到的数据10进行处理,则系统100将等待所有数据10到达,将数据10一起集合到一个束中(由于这些数据点全部适用于相同密钥),并且对其结果求和以达到总结果51。图6B的绘图600b示出了用暗矩形表示的该结果,其中,该区域覆盖包括在总和中的事件时间和处理时间的范围(当结果在处理时间内实现时,用矩形顶部来覆盖)。由于典型批处理是事件时间不可知的,所以将结果20包含在覆盖所有事件时间的单个全局窗口内。并且由于只有在接收到所有输出(例如,数据10)后才会计算出输出,所以结果20覆盖用于执行的所有处理时间。
注意,在绘图600b中包括水位线。尽管水位线通常不用于典型批处理,但是水位线在语义上将保持在开始时间处,直到已经对所有数据10进行了处理为止,然后达到无穷大。值得注意的重点是,通过利用按照这种方式进行的水位线来在流系统中运行数据,人们可以获取与典型批处理的语义相同的语义。
在一些实施方式中,系统将流水线转换为对无边界的数据源运行。在Dataflow中,默认触发语义要在水位线通过其时发射窗口。但是在使用具有无边界的输入源的全局窗口时,触发语义将不会在水位线通过时发射窗口,这是由于全局窗口覆盖所有的事件时间。同样,系统100需要由与默认触发器不同的事物触发或者由与全局窗口不同的事物进行加窗。否则,系统100将不会产生输出结果20。
在一些示例中,改变触发器允许触发器生成概念上相同的输出(在所有时间内的全局每密钥总和),但是具有周期性更新。在这些示例中,系统100应用在一分钟周期性处理时间边界上重复启动的Window.trigger操作。系统100可以指定累加模式,从而使得全局总和将会随着时间而细化(这假设系统100包括例如为数据库或密钥/值存储的输出接收点,系统100可以利用新结果将密钥的先前结果重新写入该输出接收点中)。参照图6C的绘图600c,系统100在每分钟处理时间后生成更新的全局总和。注意,半透明输出矩形(例如,窗口)如何重叠,这是由于累加窗格通过合并处理时间的重叠区域而构建在先前的结果上:
PCollection<KV<String,Integer>>output=input
.apply(Window.trigger(Repeat(AtPeriod(1,MINUTE)))
.accumulating())
.apply(Sum.integersPerKey());
相反,图6D的绘图600d示出了系统100,该系统100通过切换到丢弃模式而在每分钟后生成和的增量。注意,通过切换到丢弃模式,系统100有效地给出由许多流系统提供的处理时间加窗语义。输出窗格不再重叠,这是由于其结果包含来自独立的处理时间区域的数据。
PCollection<KV<String,Integer>>output=input
.apply(Window.trigger(Repeat(AtPeriod(1,MINUTE)))
.discarding())
.apply(Sum.integersPerKey());
提供处理时间加窗语义的另一种更强健的方式是简单地将到达时间指定为数据入口处的事件时间,然后使用对事件时间进行加窗。使用到达时间作为事件时间的较好副作用是系统对未到达的事件时间具有完美的认知,因此可以提供完美的(即,非启发式)水位线,而不带有最新数据。对于真实事件时间不必要或者不可用的用例,这是一种处理无边界的数据的有效的且成本效益高的方式。
在合并其他加窗选项之前,系统100可以考虑针对该流水线的触发器的又一个变化。在一些示例中,系统100可以通过在一定数量的数据到达之后简单地将触发器改变为启动,来对基于元组的窗口进行建模。参照图6E,绘图600e示出了来自独立的处理时间区域的五个输出结果。例如,每个输出结果包含两个相邻(按照处理时间)数据点输入的总和。更复杂的基于元组的加窗方案(例如,滑动基于元组的窗口)需要自定义加窗策略,但是以其它方式被支持。
PCollection<KV<String,Integer>>output=input
.apply(Window.trigger(Repeat(AtCount(2)))
.discarding())
.apply(Sum.integersPerKey());
用于支持无边界的源的其它示例包括从全局加窗切换出来。此处,系统100可以(例如,经由加窗API 300)将数据10加窗成固定的、两分钟累加窗口中:
PCollection<KV<String,Integer>>output=input
.apply(Window.into(FixedWindows.of(2,MINUTES)
.accumulating())
.apply(Sum.integersPerKey());
在未指定触发策略的情况下,系统100将使用默认触发器,这有效地是:
PCollection<KV<String,Integer>>output=input
.apply(Window.into(FixedWindows.of(2,MINUTES))
.trigger(Repeat(AtWatermark())))
.accumulating())
.apply(Sum.integersPerKey());
当水位线通过所述窗口的末端时,水位线触发器启动。如下文详述的,批量引擎和流式引擎实施水位线。触发器中的重复调用用于处理最新数据;如果任何数据在水位线之后到达,则其将实例化重复的水位线触发,由于已经通过水位线,所以这将会立即启动。
参照图6F-6H,绘图600f-600h分别在不同类型的运行时间引擎上特征化流水线为。在一些实施方式中,系统100首先观察该流水线在批处理引擎上的执行情况。在这些实施方式中,数据源必须是有边界的数据源,因此,与上文典型的批示例一样,系统100将等待批中的所有数据10到达。此后,如图6F的示例绘图600f所示,随着模拟水位线的升高,系统100然后将通过发射窗口来按照事件时间顺序对数据进行处理。
当利用一分钟微批量在该数据源内执行微批量引擎时,系统100将收集输入数据10达一分钟,对数据10进行处理,并且重复。每次,当前批量的水位线将从时间开始处开始并且升高到时间结束(技术上从批量的结束时间瞬间跳到时间结束,这是由于在该周期内不存在任何数据)处。系统100结束于每个微批量循环的新水位线,以及自上个循环起其内容已经改变的所有窗口的对应输出。如图6G的示例绘图600g所示,这提供了延时和最终正确性的非常好的组合。
当在流式引擎中执行流水线时,图6H的绘图600h示出了更新固定窗口的输出结果的最新数据点。虽然大多数窗口在水位线通过时发射其关联的数据点,但是系统100相对于水位线最新接收到值为9的数据(例如,数据点)。由于任何原因(移动输入源离线、网络分区等),系统100没有意识到值为9的数据尚未被注入,因此,已经观察到与相同窗口相关联的、值为5的数据(对于事件时间范围[12:00,12:02]),允许水位线越过事件时间内的最终将由值为9的数据占用的点。因此,一旦值为9的数据最后到达,其就会使第一窗口(对于事件时间范围[12:00,12:02])利用更新的总和进行重新触发。
该输出模式的好处在于,我们在每窗口大致有一个输出,在最新数据的情况下,该输出具有单个细化。但是,由于必须等待水位线升高,结果的整体延时显然比微批系统更差;这是水位线太慢的情况。
如果系统100经由对于我们的所有窗口的多个局部结果来期望更低的延时,则系统100可以添加一些附加的、基于处理时间的触发器来提供定期更新,直到实际通过水位线为止。参照图6I,绘图600i示出了基于以处理时间为基础的触发器的输出结果,以产生某种程度上比绘图600h的微批流水线的延时更好的延时,这是由于接收到的数据的数据点在其到达时就在窗口中累加,而不是按照小批量被处理。考虑到强大一致的微批量引擎和流式引擎,在这些引擎之间的选择(以及微批量大小的选择)确实只是延时与成本的关系的问题,这正是系统100可能基于以下模型实现的目标之一。
参照图6J,绘图600j示出了被分组到会话窗口内的接收到的数据10的数据点和从组合窗口会话发射的组合输出结果。此处,系统100可以通过更新至具有一分钟超时的会话加窗并且使能撤销,来满足视频会话要求(模数化作为聚合操作的总和的使用,出于图解一致性而被维持;切换到另一聚合将是不重要的)。这强调了通过将模型分解成四块(系统100正在计算什么、系统100在事件时间内正在进行计算的位置、在处理时间内系统100在何时发射计算结果、以及这些结果如何与后续细化相关)而提供的可组合性,并且还说明了恢复先前值的能力,否则可能与被提供为替代的值不相关。
在图6J的示例绘图600j中,系统100在第一个一分钟处理时间边界处输出值5和7的初始单例会话。在第二个分钟边界处,系统100输出根据值3、4、和3构建的、值为10的第三会话。当最后观察到值8时,其连接值为7和10的两个会话。当水位线通过该新组合会话的末端时,系统100发射对于值为7和10的会话的撤销,以及用于值为25的新会话的标准数据。类似地,当值为9的数据到达(最新)时,其将值为5的会话加入值为25的会话。重复的水位线触发器然后立即发射对于值为5和值为25的会话的撤销,然后是值为39的组合会话。对于值为3、8、和1的数据点,发生类似的执行,最终以对初始值为3的会话的撤销来结束,随后是值为12的组合会话。
FlumeJava可以实施系统100,将MillWheel用作流式模式的底层执行引擎;另外,在编写时主要完成Cloud Dataflow的外部重新实施方式。由于文献中的那些内部系统的先前特征,以及Cloud Dataflow是公开可用的,为了简洁起见,此处省去其本身的实施过程的细节。一个需要注意的有趣之处是,核心的加窗和触发代码非常通用,并且其重要部分在批实施过程和流式实施过程内共享;在未来的工作中值得对该系统本身进行更详细地分析。
对于来自现实世界经验的设计的重要因素如下。为了设计Dataflow Model,考虑到多年来采用FlumeJava和Mill-Wheel的现实世界经验。可以包含运行良好的配置,而带有不太理想的结果的配置激发了Dataflow Model设计的变化。
若干团队在MillWheel上运行日志连接流水线。在默认情况下,一个特别大的日志连接流水线在流式模式下在MillWheel上运行,但是具有用于大规模回填的单独的Flume-Java批量实施方式。更好的设置是将单个实施方式编写在可以在不进行修改的情况下在流式模式和批量模式二者下都运行的统一模型中。这成为统一批量引擎、微批量引擎、和流式引擎中的初步激励用例,并且在图6F至图6H的绘图600f—600h中对此进行了强调。
统一模型的另一激励来自采用Lambda架构的经验。尽管大多数数据处理用例都是由批量系统或者流式系统专门处理的,但是一个MillWheel消费者在一致性较差的模式下运行其流式流水线,而使用每夜运行MapReduce生成真相。其发现,消费者不再信任随时间一致性较差的结果,因此,在强大的一致性下重新实施其系统,从而其可以提供可靠的低延时结果。该经验进一步激励了在执行引擎中支持流体选择的期望。
系统100从一开始就需要支持会话;这在实际上是底层加窗模型在现有模型上的主要贡献。会话是极为重要的用例(并且在实际上是创建MillWheel的原因之一),并且被用于许多产品领域,包括:搜索、广告、分析、社交、和YouTube。在一段时间内将以别的方式不相交的用户活动的突发进行相关的任何产品都会通过计算会话来这样做。因此,在由系统100实施的Dataflow Model的设计中,对会话的支持变得极为重要。如图6J的绘图600j所示,在Dataflow Model中生成会话的系统100是不那么重要的。
采用构建在MillWheel上的计费流水线的两个团队经历了激励模型的部分的问题。当时的推荐做法是将水位线用作完成指标,用临时(ad hoc)逻辑处理最新数据或者元数据的变化。缺乏进行更新和撤销的原则性系统,对资源利用统计进行处理的团队最终让我们的平台构建自定义解决方案(完成的模型与我们同时开发的模型非常相似)。另一计费团队在由其输入中的落后者造成的水位线延迟方面出现了重大问题。这些缺点成为我们的设计中的主要激励,并且影响到将重点从目标完整性转换至随着时间的适用性。结果是双重的:触发器,其允许简明并且灵活地指定在何时实现结果,如通过在图6C-6J的绘图600c-600j中的相同的数据集合内的各种输出模式可能性证明的;以及通过累加(图6C和图6D)和撤销(图6J)的增量处理支持。
许多MillWheel流水线计算聚合统计(例如,延时平均值)。对于这些流水线而言,不需要100%的准确性,但是在合理的时间量内需要对其数据很大程度的全面理解。考虑到我们针对比如日志文件的结构化的输入源利用水位线实现了高水平的准确性,这些消费者发现水位线在触发单个高度准确的每窗口聚合方面非常有效。在图6H的绘图600h中强调了水位线触发器。若干滥用检测流水线在MillWheel上运行。滥用检测是迅速地处理大多数数据比迟缓地处理100%的数据更为有用的用例的另一示例。同样,其是MillWheel的百分位水位线的重要用户,并且是能够在模型中支持百分位水位线触发器的强大激励案例。
相关地,批处理作业的难点是在执行时间内创建长尾的落后者。虽然动态重新平衡可以帮助解决该问题,FlumeJava具有自定义特征,该自定义特征允许基于整体进度提前终止作业。批量模式的统一模型的其中一个益处是通过使用标准触发机制,可以自然地表达这种早期终止标准,而不是要求自定义特征。
另一流水线考虑在多个系统内构建用户活动树(本质上是会话树)。然后使用这些树来构建适应用户的兴趣的建议。流水线值得注意的地方是其使用处理时间定时器来驱动其输出。这是由于如下事实,对于其系统,一旦水位线通过会话的末端,对数据的局部观点进行定期更新比一直等到大部分完整观点准备就绪更有价值。这也意味着,由于少量的慢数据造成的水位线进度的延迟不会影响其余数据的输出的及时性。因此,该流水线促使包括在图6C和图6D的绘图600c和600d中分别示出的处理时间触发器。
当开发触发器时,其差异检测系统激励了受数据驱动的触发器。这些差异观察到查询流并且计算出是否存在尖峰的统计评估。当其认为发生尖峰时,其发射开始记录,并且当其认为尖峰已经停止时,其发射暂停。尽管技术可以针对异常检测驱动具有类似于Trill标点的周期性事物的不同输出,但是一确信发现异常就获得输出是理想的;使用标点在本质上将流系统转换成微批量,从而引入附加延时。虽然实际上对于若干用例而言,其并不是适合于该情况的理想用例,从而激励了对自定义受数据驱动的触发器的支持。这也是触发器组合的激励情况,因为在现实中,系统马上运行多个差异,根据明确定义的逻辑集合来多路复用其输出。用于图6E的绘图600e的AtCount触发器例证了受数据驱动的触发器;而图6E-6J的绘图600f-600j利用了复合触发器。
数据处理的未来是无边界的数据。尽管有边界的数据将会始终占据重要并且有用的位置,但是其在语义上被纳入无边界的对应部分。此外,跨现代业务的无边界的数据集的激增是惊人的。同时,处理数据的消费者越来越富有经验,这更加迫切地要求强大的构造,比如事件时间定时和不对齐窗口。目前存在的模型和系统充当构建未来的数据处理工具的良好基础,但是坚信,整体思维的转变对于使这些工具能够全面地解决无边界的数据的消费者的需要是必要的。
基于与现实世界、大规模、无边界的数据处理的多年经验,上述系统100朝这个方向迈出一大步。系统100支持现代数据消费者所需的不对齐的事件时间顺序窗口,同时提供灵活的触发和集成的累加和撤销,并且将该方法从找到数据的完整性重新集中到适应显示在现实世界数据集中的始终存在的变化。系统100将批量与微批量以及流这三者的关系抽象化,使得流水线构建者能够在这三者之间进行更流畅的选择,同时将其与系统特定的架构屏蔽,这些架构必然会爬入针对单个底层系统的模型中。系统100的整体灵活性允许流水线构建者适当地平衡正确性、延时、和成本的维度以适应其用例,考虑到存在的各种需求,这是至关重要的。最后,系统100通过将正在计算的结果的概念、在事件时间内的正在计算这些结果的位置、在处理时间内在何时实现这些结果、以及早期结果如何与后续细化相关分开,来阐明流水线实施方式。
软件应用(即,软件资源)可以指使计算装置执行任务的计算机软件。在一些示例中,可以将软件应用称为“应用”、“应用程序”、或者“程序”。示例应用包括:但不限于,系统诊断应用、系统管理应用、系统维护应用、文字处理应用、电子表格应用、消息应用、媒体流应用、社交网络应用、和游戏应用。
非暂时性存储器可以是用于在暂时或者永久基础上存储供计算装置使用的程序(例如,指令序列)或者数据(例如,程序状态信息)的物理装置。非暂时性存储器可以是易失性可寻址半导体存储器和/或非易失性可寻址半导体存储器。非易失性存储器的示例包括:但不限于,闪存和只读存储器(ROM)/可编程只读存储器(PROM)/可擦除可编程只读存储器(EPROM)/电可擦除可编程只读存储器(EEPROM)(例如,通常用于诸如引导程序的固件)。易失性存储器的示例包括:但不限于,随机存取存储器(RAM)、动态随机存取存储器(DRAM)、静态随机存取存储器(SRAM)、相变存储器(PCM)、以及光盘或者磁带。
图7是可以用于实施本文档描述的系统和方法的示例计算装置700的示意图。计算装置700旨在表示各种形式的数字计算机,诸如,膝上型计算机、台式计算机、工作站、个人数字助理、服务器、刀片式服务器、大型计算机、和其它合适的计算机。本文所示的部件、它们的连接和关系、以及它们的功能仅仅旨在作为示例,并且不旨在限制本文档中描述的和/或者要求保护的本发明的实施。
计算装置700包括:处理器710(例如,数据处理硬件)、存储器720、存储装置730、连接至存储器720和高速扩展端口750的高速接口/控制器740、和连接至低速总线770和存储装置730的低速接口/控制器760。通过使用不同的总线将每个部件710、720、730、740、750、和760互相连接,并且可以将上述每个部件安装在公共主板上、或者根据需要以其它的方式安装上述每个部件。处理器710可以对在计算装置700内执行的指令进行处理,指令包括存储在存储器720中或者存储装置730上以在外部输入/输出装置上显示图形用户界面(GUI)的图形信息的指令,外部输入/输出装置诸如为耦合至高速接口740的显示器780。在其它实施方式中,若需要,可以将多个处理器和/或多条总线与多个存储器和多种存储器一起使用。同样,可以连接多个计算装置700,每个装置提供部分必要的操作(例如,作为服务器阵列、一组刀片式服务器、或者多处理器系统)。数据存储硬件710(例如,处理器)可以执行流计算系统100。
存储器720(例如,存储器硬件)将信息非暂时性地存储在计算装置700内。存储器720可以是计算机可读介质、(多个)易失性存储器单元、或者(多个)非易失性存储器单元。非易失性存储器720可以是用于在暂时或者持久基础上存储供计算装置700使用的程序(例如,指令序列)或者数据(程序状态信息)的物理装置。非易失性存储器的示例包括:但不限于,闪存和只读存储器(ROM)/可编程只读存储器(PROM)/可擦除编程只读存储器(EPROM)/电可擦除编程只读存储器(EEPROM)(例如,通常用于诸如为引导程序的固件)。易失性存储器的示例包括:但不限于,随机存取存储器(RAM)、动态随机存取存储器(DRAM)、静态随机存取存储器(SRAM)、相变存储器(PCM)、以及光盘或者磁带。
存储装置730能够为计算装置700提供海量存储装置。在一些实施方式中,存储装置730是计算机可读介质。在各种不同的实施方式中,存储装置730可以是软盘装置、硬盘装置、光盘装置、或者磁带装置、闪存或者其它相似的固态存储器装置、或者装置阵列,包括:在存储区域网络或者其它配置中的装置。在附加实施方式中,计算机程序产品有形地体现为信息载体。计算机程序产品包含指令,该指令在被执行时执行一种或者多种方法,诸如,上文描述的方法。信息载体是计算机可读介质或者机器可读介质,诸如,存储器720、存储装置730、或者在处理器710上的存储器。
高速控制器740管理计算装置700的带宽密集型操作,而低速控制器760管理较低带宽的密集型操作。这种功能分配仅仅是示例性的。在一些实施方式中,高速控制器740耦合至存储器720、显示器780(例如,通过图形处理器或者加速器)耦合至高速扩展端口750,该高速扩展端口710可以接受各种扩展卡(未示出)。在一些实施方式中,低速控制器760耦合至存储装置730和低速扩展端口770。低速扩展端口770可以包括各种通信端口(例如,USB、蓝牙、以太网,和无线以太网),可以通过网络适配器耦合至一个或者多个输入/输出装置,诸如,键盘、指向装置、扫描器,或者诸如交换机或者路由器的联网装置。
如图所示,可以利用多种形式来实施计算装置700。例如,可以将计算装置700实施为标准服务器700a、或者多次实施在一组这种服务器700a中、或者实施为膝上型计算机700b、或者实施为机架式服务器系统700c的一部分。
此处描述的系统和技术的各种实施方式可以在数字电子电路系统和/或光学电路系统、集成电路系统、专用ASIC(专用集成电路)、计算机硬件、固件、软件、和/或它们的组合中实现。这些各种实施方式可以包括实施在一个或者多个计算机程序中,该一个或者多个计算机程序可在包括至少一个可编程处理器的可编程系统上执行和/或解释,该可编程处理器可以是专用或者通用的,可以从存储系统、至少一个输入装置、和至少一个输出装置接收数据和指令,并且将数据和指令传输至该存储系统、该至少一个输入装置、和该至少一个输出装置。
这些计算程序(也称作程序、软件、软件应用、或者代码)包括可编程处理器的机器指令,并且可以利用高级过程和/或面向对象的编程语言、和/或汇编/机器语言来实施这些计算程序。如本文使用的,术语“机器可读介质”和“计算机可读介质”指的是用于将机器指令和/或数据提供给可编程处理器的任何计算机程序产品、非暂时性计算机可读介质、设备、和/或装置(例如,磁盘、光盘、存储器、可编程逻辑装置(PLD)),包括,接收作为机器可读信号的机器指令的机器可读介质。术语“机器可读信号”指的是用于将机器指令和/或数据提供给可编程处理器的任何信号。
可以利用数字电子电路系统,或者利用计算机软件、固件或者硬件——包括在本说明书中所公开的结构及其结构等效物、或者它们中的一个或者多个的组合来实施本说明书中所描述的主题和功能操作的实施方式。而且,可以将本说明书中所描述的主题实施为一个或者多个计算机程序产品,即,编码在计算机可读介质上、由数据处理设备执行或者控制该数据处理设备的操作的计算机程序指令的一个或者多个模块。计算机可读介质可以是机器可读存储装置、机器可读存储基板、存储器装置、影响机器可读的传播信号的合成物质、或者它们中的一个或者多个的组合。术语“数据处理设备”、“计算装置”、和“计算处理器”囊括了用于处理数据的所有设备、装置、机器,该所有设备、装置、机器包括:例如,可编程处理器、计算机、或者多个处理器或者计算机。除了硬件之外,该设备还可以包括为探讨中的计算机程序创建执行环境的代码,例如,构成处理器固件、协议栈、数据库管理系统、操作系统、或者它们中的一个或者多个的组合的代码。传播信号是人工生成的信号,例如,机器生成的电气、光学或者电磁信号,生成该信号是为了对用于传输至合适的接收器设备的信息进行编码。
可以用任何形式的编程语言——包括编译语言或者解译语言,来编写计算机程序(也称为应用、程序、软件、软件应用、脚本或者代码),并且可以按照任何形式——包括作为独立式程序或者模块、部件、子例程、或者适合用于计算环境的其它单元,来部署计算机程序。计算机程序不一定需要与文件系统中的文件对应。可以将程序存储在保持其它程序或者数据(例如,存储在标记语言文档中的一个或者多个脚本)的文件的一部分中,或者存储在专用于所探讨中的程序的单个文件中,或者存储在多个协作文件(例如,存储一个或者多个模块、子程序、或者部分代码的文件)中。可以将计算机程序部署为在一个计算机上执行或者在位于一个站点处或者分布在多个站点中并且通过通信网络互相连接的多个计算机上执行。
可以通过一个或者多个可编程处理器来执行本说明书中所描述的过程和逻辑流程,该一个或者多个可编程处理器执行一个或者多个计算机程序以通过操作输入数据并且生成输出来进行功能。也可以通过专例如FPGA(现场可编程门阵列)或者ASIC(专用集成电路)的用逻辑电路系统来进行过程和逻辑流程,并且也可以将设备实施为该专用逻辑电路系统。
适合执行计算机程序的处理器包括:例如,通用微处理器、专用微处理器、以及任何种类的数字计算机的任何一个或者多个处理器。一般而言,处理器将接收来自只读存储器或者随机存取存储器或者两者的指令和数据。计算机的必要元件是:用于执行指令的处理器、和用于存储指令和数据的一个或者多个存储器装置。一般而言,计算机还将包括用于存储数据的一个或者多个海量存储装置,或者计算机可以操作地耦合以接收来自该一个或者多个海量存储装置的数据或者将数据传输至该一个或者多个海量存储装置或者进行两者,该海量存储装置例如为磁盘、磁光盘、或者光盘。然而,计算机无需具有这种装置。此外,计算机可以嵌入在另一装置中,例如,移动电话、个人数字助理(PDA)、移动音频播放器、全球定位系统(GPS)接收器,仅举几例。适合于存储计算机程序指令和数据的计算机可读介质包括所有形式的非易失性存储器、介质和存储器装置,包括:例如,例如为EPROM、EEPROM、和闪速存储器装置的半导体存储器装置、例如为内部硬盘或者可移动盘的磁盘、磁光盘、CD-ROM盘和DVD-ROM盘。处理器和存储器可以由专用逻辑电路系统补充或者可以并入该专用逻辑电路系统中。
为了提供与用户的交互,可以在计算机上实施本公开的一个或者多个方面,该计算机具有:用于向用户显示信息的显示装置,例如,CRT(阴极射线管)或者LCD(液晶显示器)监视器;或者触摸屏;以及可选地,键盘和指向装置,例如,鼠标或者轨迹球,用户可以通过该键盘和该指向装置来将输入提供给计算机。其它种类的装置可以用于提供与用户的交互;例如,提供给用户的反馈可以是任何形式的传感反馈,例如,视觉反馈、听觉反馈或者触觉反馈;并且可以用包括声输入、语音输入或者触觉输入的任何形式来接收来自用户的输入。另外,计算机可以通过将文档发送到用户所使用的装置并且接收来自该装置的文档,来与用于交互,例如,通过响应于从网络浏览器接收的请求来将网页发送至在用户的客户端装置上的网络浏览器。
可以将本公开的一个或者多个方面实施在包括例如作为数据服务器的后台部件的计算系统、或者包括例如为应用服务器的中间件部件的计算系统、或者包括前端部件的计算系统、或者包括一个或者多个这种后台部件、中间件部件或者前端部件的任何组合的计算系统中,前端部件例如为具有图形用户界面或者网络浏览器的客户端计算机,用户可以通过该图形用户界面或者该网络浏览器来与本说明书中所描述的主题的实施方式交互。可以通过例如为通信网络的任何形式或者介质的数字数据通信来将系统的部件相互连接。通信网络的示例包括:局域网(“LAN”)和广域网(“WAN”)、网际网(例如,互联网)、以及点对点网络(例如,ad hoc点对点网络)。
计算机系统可以包括客户端和服务器。客户端和服务器一般远离彼此并且通常通过通信网络进行交互。通过在相应的计算机上运行并且彼此具有客户端-服务器关系的计算机程序来产生客户端和服务器的关系。在一些实施方式中,服务器将数据(例如,HTML页面)传输至客户端装置(例如,为了向与客户端装置交互的用户显示数据并且接收来自该用户的用户输入)。可以在服务器处从客户端装置接收在客户端装置处生成的数据(例如,用户交互的结果)。
虽然本说明书包含了许多细节,但是不应该将这些细节视为对本公开或者可能被要求保护的内容的范围的限制,而是作为针对本公开的特定实施方式的特征的描述。在本说明书中在单独实施方式的背景下描述的某些特征还可以组合地实施在单个实施方式中。相反,在单个实施方式的背景中描述的各种特征也可以单独地或者按照任何合适的子组合实施在多个实施方式中。此外,虽然上文可能将特征描述为以某些组合来起作用并且最初甚至同样地对该特征进行了要求,但是在一些情况下可以从组合中删除来自所要求的组合的一个或者多个特征。并且所要求保护的组合可以指向子组合或者子组合的变化。
同样,虽然在附图中按照特定顺序示出了操作,但是不应该将其理解为需要按照所示的特定顺序或者按照相继的顺序来进行这种操作,或者需要进行所有图示的操作以实现期望的结果。在某些情况下,多任务处理和并行处理可以是有利的。此外,不应该将在上述实施例中的各种系统部件的分离理解为在所有实施例中需要这种分离,并且应该理解,所描述的程序部件和系统通常可以一起集成在单个软件产品中或者封装到多个软件产品中。
已经描述了若干实施方式。然而,要理解,可以在不脱离本公开的精神和范围的情况下做出各种修改。因此,其它实施方式在以下权利要求书的范围内。例如,在权利要求书中叙述的动作可以按照不同的顺序来进行并且仍然可以实现期望的结果。
Claims (24)
1.一种方法,所述方法包括:
在数据处理硬件(710)处接收与流数据(10)或者批量数据中的一个对应的数据(10);
通过使用所述数据处理硬件(710)来确定所接收到的数据(10)的内容以用于计算;
通过使用所述数据处理硬件(710)来确定所述数据(10)的事件时间以用于对所述数据(10)进行切分;
通过使用所述数据处理硬件(710)来确定输出所接收到的数据(10)的结果(20)的处理时间;以及
基于所述事件时间和所述处理时间来发射所接收到的数据(10)的结果(20)的至少一部分。
2.根据权利要求1所述的方法,所述方法进一步包括:
通过使用所述数据处理硬件(710),基于所述事件时间将所接收到的数据(10)分组成窗口(330、340、500),所述窗口(330、340、500)包括以下中的一个:
由静态时间周期定义的固定窗口(330),每个固定窗口(330)被应用于在所关联的时间周期内的所有所述数据(10);
由时间周期和滑动周期定义的滑动窗口(340),每个滑动窗口(340)被应用于在所关联的时间周期内的所有所述数据(10)并且与开始时间相关联,所述开始时间通过所述滑动周期与紧接着的窗口的开始时间分开;
由超时间隔定义的会话窗口(500),每个会话窗口(500)被应用于在小于所关联的超时间隔的时间跨度内出现的所述数据(10)的子集;或者
由一对函数定义的用户定义的窗口。
3.根据权利要求1或者2所述的方法,所述方法进一步包括:
通过使用所述数据处理硬件(710)来为所接收到的数据(10)的每个元素分配可合并窗口(330、340、500),每个元素包括相关联的输入时间戳,并且每个会话窗口(500)超过所关联的窗口(330、340、500)的所述输入时间戳延伸预定义时间范围。
通过使用所述数据处理硬件(710)来合并所述可合并窗口(330、340、500)中重叠成单个合并窗口(330、340、500)的、属于相同密钥的两个或者更多个可合并窗口;以及
通过使用所述数据处理硬件(710)将每个元素的相关联的输出时间戳设置为大于或者等于在所关联的合并窗口(330、340、500)或者所关联的可合并窗口(330、340、500)中的最早时间的值。
4.根据权利要求3所述的方法,其中,所述单个合并窗口(330、340、500)包括大于所述预定义时间范围的时间范围。
5.根据权利要求1至4中任一项所述的方法,所述方法进一步包括:当所接收到的数据(10)与流数据(10)对应时:
通过使用所述数据处理硬件(710)将所述流数据(10)分组成窗口(330、340、500);
通过使用所述数据处理硬件(710)设置针对所述流数据(10)的元素的输入时间戳;以及
当针对所述元素的所述输入时间戳先于水位线出现时,通过使用所述数据处理硬件(710)来确定所述流数据(10)包括最新流数据(10);以及
以下中的一个:
丢弃所述最新流数据(10);或者
通过创建复制窗口(330、340、500)来允许所述最新流数据(10)在所述最新流数据(10)的输出中。
6.根据权利要求1至5中任一项所述的方法,所述方法进一步包括:
通过使用所述数据处理硬件(710)将所接收到的数据(10)的第一数据子集分组成窗口(330、340、500),所述窗口(330、340、500)定义所述数据子集的子事件时间;
通过使用所述数据处理硬件(710)来聚合所述窗口(330、340、500)的所述第一数据子集的第一结果;以及
通过使用所述数据处理硬件(710)来确定发射所述第一数据子集的第一聚合结果的触发时间,所述触发时间包括以下中的至少一个:
当水位线到达所述窗口(330、340、500)的末端时;
挂钟时间的每个阈值秒数;
在接收到终止所述窗口(330、340、500)的标点记录之后;
每个阈值记录数;
在任意的用户逻辑决定触发之后;或者
在具体触发器的任意组合之后。
7.根据权利要求6所述的方法,所述方法进一步包括:当确定发射所述第一数据子集的所述第一聚合结果的所述触发时间时,在聚合所接收到的数据(10)的后续子集的结果时,通过使用所述数据处理硬件(710)抛弃对所述第一聚合结果的使用。
8.根据权利要求6或者7所述的方法,所述方法进一步包括:当确定发射所述第一数据子集的所述第一聚合结果的所述触发时间时:
在持久状态下将所述第一聚合结果的副本存储在与所述数字处理硬件(710)通信的存储器硬件(720)内;以及
通过所述数据处理硬件(710),利用所述第一聚合结果来细化后续子集的下一个聚合(20)结果。
9.根据权利要求6所述的方法,所述方法进一步包括:
当确定发射所述第一数据子集的所述第一聚合结果的所述触发时间时,在持久状态下将所述第一聚合结果的副本存储在与所述数据处理硬件(710)通信的存储器硬件(720)内;以及
当发射与相同的窗口(330、340、500)相关联的后续子集的下一个聚合结果时:
发射对所述第一聚合结果的撤销;以及
发射所述窗口(330、340、500)的组合会话结果。
10.根据权利要求6所述的方法,所述方法进一步包括:
在将所述第一数据子集分组成所述窗口(330、340、500)之后,在所述数据处理硬件(710)处接收最新数据点,所述最新数据点与所述窗口(330、340、500)有关;以及
通过使用所述数据处理硬件(710)抛弃所述最新数据点。
11.根据权利要求6所述的方法,所述方法进一步包括:
在将所述第一数据子集分组成所述窗口(330、340、500)之后,在所述数据处理硬件(710)处接收最新数据点,所述最新数据点与所述窗口(330、340、500)有关;以及
通过使用所述数据处理硬件(710)将所述最新数据点累加到所述窗口(330、340、500)中,以利用所述最新数据点来细化所述第一聚合结果。
12.根据权利要求6所述的方法,所述方法进一步包括:
在将所述第一数据子集分组成所述窗口(330、340、500)之后,在所述数据处理硬件(710)处接收最新数据点,所述最新数据点与所述窗口(330、340、500)有关;
通过使用所述数据处理硬件(710)来聚合所述第一数据子集和所述最新数据点的组合结果;以及
发射所述组合结果(20)。
13.一种系统,所述系统包括:
数据处理硬件(710);以及
与所述数据处理硬件(710)通信的存储器硬件(720),所述存储器硬件(720)存储指令,所述指令在所述数据处理硬件(710)上被执行时使所述数据处理硬件(710)执行操作,所述操作包括:
接收与流数据(10)或者批量数据中的一个对应的数据(10);
确定所接收到的数据(10)的内容以用于计算;
确定所述数据(10)的事件时间以用于对所述数据(10)进行切分;
确定输出所接收到的数据(10)的结果的处理时间;以及
基于所述处理时间和所述事件时间来发射所接收到的数据(10)的结果的至少一部分。
14.根据权利要求13所述的系统,其中,所述操作进一步包括:基于所述事件时间将所接收到的数据(10)分组成窗口(330、340、500),所述窗口(330、340、500)包括以下中的一个:
由静态时间周期定义的固定窗口(330),每个固定窗口(330)被应用于在所关联的时间周期内的所有所述数据(10);
由时间周期和滑动周期定义的滑动窗口(340),每个滑动窗口(340)被应用于在所关联的时间周期内的所有所述数据(10)并且与开始时间相关联,所述开始时间通过所述滑动周期与紧接着的窗口的开始时间分开;
由超时间隔定义的会话窗口(500),每个会话窗口(500)被应用于在小于所关联的超时间隔的时间跨度内出现的所述数据(10)的子集;或者
由一对函数定义的用户定义的窗口。
15.根据权利要求13或者14所述的系统,其中,所述操作进一步包括:
为所接收到的数据(10)的每个元素分配可合并窗口(330、340、500),每个元素包括相关联的输入时间戳,并且每个可合并窗口(330、340、500)超过所关联的窗口(330、340、500)的所述输入时间戳延伸预定义时间范围;
合并所述可合并窗口(330、340、500)中重叠成单个合并窗口(330、340、500)的、属于相同密钥的两个或者更多个可合并窗口;以及
将每个元素的相关联的输出时间戳设置为大于或者等于在所关联的合并窗口(330、340、500)或者所关联的可合并窗口(330、340、500)中的最早时间的值。
16.根据权利要求15所述的系统,其中,所述单个合并窗口(330、340、500)包括大于所述预定义时间范围的相关联的时间范围。
17.根据权利要求13至16中任一项所述的系统,其中,所述操作进一步包括:当所接收到的数据(10)与流数据(10)对应时:
将所述流数据(10)分组成窗口(330、340、500);
设置针对所述流数据(10)的元素的输入时间戳;以及
当针对所述元素的所述输入时间戳先于水位线出现时:
确定所述流数据(10)包括最新流数据(10);以及以下中的一个:
丢弃所述最新流数据(10);或者
通过创建复制窗口(330、340、500)来允许所述最新流数据(10)在所述最新流数据(10)的输出中。
18.根据权利要求13至17所述的系统,其中,所述操作进一步包括:
将所接收到的数据(10)的第一子集分组成窗口(330、340、500),所述窗口(330、340、500)定义所述数据子集的子事件时间;
聚合所述窗口(330、340、500)的所述第一数据子集的第一结果;以及
确定发射所述第一数据子集的第一聚合结果的触发时间,所述触发时间包括以下中的至少一个:
当水位线到达所述窗口(330、340、500)的末端时;
挂钟时间的每个阈值秒数;
在接收到终止所述窗口(330、340、500)的标点记录之后;
每个阈值记录数;
在任意的用户逻辑决定触发之后;或者
在具体触发器的任意组合之后。
19.根据权利要求18所述的系统,其中,所述操作进一步包括:当确定发射所述第一数据子集的所述第一聚合结果的所述触发时间时,在聚合所接收到的数据(10)的后续子集的结果时,抛弃对所述第一聚合结果的使用。
20.根据权利要求18所述的系统,其中,所述操作进一步包括:当确定发射所述第一数据子集的所述第一聚合结果的所述触发时间时:
在持久状态下将所述第一聚合结果的副本存储在与所述数字处理硬件(710)通信的存储器硬件(720)内;以及
利用所述第一聚合结果来细化后续子集的下一个聚合(20)结果。
21.根据权利要求18所述的系统,其中,所述操作进一步包括:
当确定发射所述第一数据子集的所述第一聚合结果的所述触发时间时,在持久状态下将所述第一聚合结果的副本存储在与所述数据处理硬件(710)通信的存储器硬件(720)内;以及
当发射与相同的窗口(330、340、500)相关联的后续子集的下一个聚合结果时:
发射对所述第一聚合结果的撤销;以及
发射所述窗口(330、340、500)的组合会话结果。
22.根据权利要求18所述的系统,其中,所述操作进一步包括:
在将所述第一数据子集分组成所述窗口(330、340、500)之后,接收最新数据点,所述最新数据点与所述窗口(330、340、500)有关;以及
抛弃所述最新数据点。
23.根据权利要求18所述的系统,其中,所述操作进一步包括:
在将所述第一数据子集分组成所述窗口(330、340、500)之后,接收最新数据点,所述最新数据点与所述窗口(330、340、500)有关;以及
将所述最新数据点累加到所述窗口(330、340、500)中,以利用所述最新数据点来细化所述第一聚合结果。
24.根据权利要求18所述的系统,其中,所述操作进一步包括:
在将所述第一数据子集分组成所述窗口(330、340、500)之后,接收最新数据点,所述最新数据点与所述窗口(330、340、500)有关;
聚合所述第一数据子集和所述最新数据点的组合结果(20);以及
发射所述组合结果(20)。
Applications Claiming Priority (5)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US201562201441P | 2015-08-05 | 2015-08-05 | |
US62/201,441 | 2015-08-05 | ||
US14/931,006 US10037187B2 (en) | 2014-11-03 | 2015-11-03 | Data flow windowing and triggering |
US14/931,006 | 2015-11-03 | ||
PCT/US2016/038131 WO2017023432A1 (en) | 2015-08-05 | 2016-06-17 | Data flow windowing and triggering |
Publications (2)
Publication Number | Publication Date |
---|---|
CN107209673A true CN107209673A (zh) | 2017-09-26 |
CN107209673B CN107209673B (zh) | 2020-11-06 |
Family
ID=57944030
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201680007851.6A Active CN107209673B (zh) | 2015-08-05 | 2016-06-17 | 数据流加窗和触发 |
Country Status (4)
Country | Link |
---|---|
EP (1) | EP3215963A1 (zh) |
CN (1) | CN107209673B (zh) |
DE (1) | DE202016007901U1 (zh) |
WO (1) | WO2017023432A1 (zh) |
Cited By (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108228356A (zh) * | 2017-12-29 | 2018-06-29 | 华中科技大学 | 一种流数据的分布式动态处理方法 |
CN109617648A (zh) * | 2018-10-29 | 2019-04-12 | 青岛民航凯亚系统集成有限公司 | 一种可变时间滑动窗口计算方法 |
CN109871248A (zh) * | 2018-12-29 | 2019-06-11 | 天津南大通用数据技术股份有限公司 | 一种可变间隔的去除重复流数据的会话窗口设计方法 |
CN110209685A (zh) * | 2019-06-12 | 2019-09-06 | 北京九章云极科技有限公司 | 一种数据实时处理方法及系统 |
CN110850825A (zh) * | 2019-11-13 | 2020-02-28 | 武汉恒力华振科技有限公司 | 基于事件时间的工业过程数据处理方法 |
CN111831383A (zh) * | 2020-07-20 | 2020-10-27 | 北京百度网讯科技有限公司 | 窗口拼接方法、装置、设备以及存储介质 |
CN111858368A (zh) * | 2020-07-27 | 2020-10-30 | 成都新潮传媒集团有限公司 | 数据处理方法、装置及存储介质 |
CN116974876A (zh) * | 2023-09-20 | 2023-10-31 | 云筑信息科技(成都)有限公司 | 一种基于实时流框架实现毫秒级监控告警的方法 |
WO2024031461A1 (zh) * | 2022-08-10 | 2024-02-15 | 华为技术有限公司 | 流数据处理方法及相关设备 |
Families Citing this family (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US10514952B2 (en) * | 2016-09-15 | 2019-12-24 | Oracle International Corporation | Processing timestamps and heartbeat events for automatic time progression |
US10909182B2 (en) * | 2018-03-26 | 2021-02-02 | Splunk Inc. | Journey instance generation based on one or more pivot identifiers and one or more step identifiers |
CN113127512B (zh) * | 2020-01-15 | 2023-09-29 | 百度在线网络技术(北京)有限公司 | 多数据流的数据拼接触发方法、装置、电子设备和介质 |
CN111478949B (zh) * | 2020-03-25 | 2022-05-24 | 中国建设银行股份有限公司 | 数据处理方法和装置 |
CN113742004B (zh) * | 2020-08-26 | 2024-04-12 | 北京沃东天骏信息技术有限公司 | 一种基于flink框架的数据处理方法和装置 |
JP2022151355A (ja) * | 2021-03-26 | 2022-10-07 | 富士通株式会社 | データ処理プログラム、データ処理方法及びデータ処理システム |
CN115080156B (zh) * | 2022-08-23 | 2022-11-11 | 卓望数码技术(深圳)有限公司 | 基于流批一体的大数据批量计算的优化计算方法及装置 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6934756B2 (en) * | 2000-11-01 | 2005-08-23 | International Business Machines Corporation | Conversational networking via transport, coding and control conversational protocols |
US7080386B2 (en) * | 2000-01-25 | 2006-07-18 | Texas Instruments Incorporated | Architecture with digital signal processor plug-ins for general purpose processor media frameworks |
US8160968B2 (en) * | 1999-05-19 | 2012-04-17 | Digimarc Corporation | Digital media methods |
CN102662642A (zh) * | 2012-04-20 | 2012-09-12 | 浪潮电子信息产业股份有限公司 | 一种基于嵌套滑动窗口和遗传算法的并行处理方法 |
-
2016
- 2016-06-17 EP EP16741415.0A patent/EP3215963A1/en not_active Withdrawn
- 2016-06-17 WO PCT/US2016/038131 patent/WO2017023432A1/en active Application Filing
- 2016-06-17 DE DE202016007901.9U patent/DE202016007901U1/de active Active
- 2016-06-17 CN CN201680007851.6A patent/CN107209673B/zh active Active
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US8160968B2 (en) * | 1999-05-19 | 2012-04-17 | Digimarc Corporation | Digital media methods |
US7080386B2 (en) * | 2000-01-25 | 2006-07-18 | Texas Instruments Incorporated | Architecture with digital signal processor plug-ins for general purpose processor media frameworks |
US6934756B2 (en) * | 2000-11-01 | 2005-08-23 | International Business Machines Corporation | Conversational networking via transport, coding and control conversational protocols |
CN102662642A (zh) * | 2012-04-20 | 2012-09-12 | 浪潮电子信息产业股份有限公司 | 一种基于嵌套滑动窗口和遗传算法的并行处理方法 |
Non-Patent Citations (2)
Title |
---|
MATEI ZAHARIA ETC.: ""Discretized Streams:An Efficient and Fault-Torelant Model for Stream Processing on Large Clusters"", 《HTTPS://WWW.USENIX.ORG/CONFERENCE/HOTCLOUD12》 * |
TYLER AKIDAU ETC.: ""MillWheel: Fault-Tolerant Stream Proceeding at Internet Scale"", 《PROCEEDINGS OF THE VLDB ENDOWMENT》 * |
Cited By (12)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108228356A (zh) * | 2017-12-29 | 2018-06-29 | 华中科技大学 | 一种流数据的分布式动态处理方法 |
CN108228356B (zh) * | 2017-12-29 | 2021-01-15 | 华中科技大学 | 一种流数据的分布式动态处理方法 |
CN109617648A (zh) * | 2018-10-29 | 2019-04-12 | 青岛民航凯亚系统集成有限公司 | 一种可变时间滑动窗口计算方法 |
CN109871248A (zh) * | 2018-12-29 | 2019-06-11 | 天津南大通用数据技术股份有限公司 | 一种可变间隔的去除重复流数据的会话窗口设计方法 |
CN110209685A (zh) * | 2019-06-12 | 2019-09-06 | 北京九章云极科技有限公司 | 一种数据实时处理方法及系统 |
CN110850825A (zh) * | 2019-11-13 | 2020-02-28 | 武汉恒力华振科技有限公司 | 基于事件时间的工业过程数据处理方法 |
CN110850825B (zh) * | 2019-11-13 | 2021-06-08 | 武汉恒力华振科技有限公司 | 基于事件时间的工业过程数据处理方法 |
CN111831383A (zh) * | 2020-07-20 | 2020-10-27 | 北京百度网讯科技有限公司 | 窗口拼接方法、装置、设备以及存储介质 |
CN111858368A (zh) * | 2020-07-27 | 2020-10-30 | 成都新潮传媒集团有限公司 | 数据处理方法、装置及存储介质 |
WO2024031461A1 (zh) * | 2022-08-10 | 2024-02-15 | 华为技术有限公司 | 流数据处理方法及相关设备 |
CN116974876A (zh) * | 2023-09-20 | 2023-10-31 | 云筑信息科技(成都)有限公司 | 一种基于实时流框架实现毫秒级监控告警的方法 |
CN116974876B (zh) * | 2023-09-20 | 2024-02-23 | 云筑信息科技(成都)有限公司 | 一种基于实时流框架实现毫秒级监控告警的方法 |
Also Published As
Publication number | Publication date |
---|---|
WO2017023432A1 (en) | 2017-02-09 |
DE202016007901U1 (de) | 2017-04-03 |
CN107209673B (zh) | 2020-11-06 |
EP3215963A1 (en) | 2017-09-13 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN107209673A (zh) | 数据流加窗和触发 | |
US10732928B1 (en) | Data flow windowing and triggering | |
CN101957832B (zh) | 对于事件流数据管理的统一的窗口支持 | |
CN104067257B (zh) | 自动化事件管理系统,管理事件方法及事件管理系统 | |
Bonner et al. | Concurrency and Communication in Transaction Logic. | |
CN106663010A (zh) | 执行基于图的程序规范 | |
Shoham | Why knowledge representation matters | |
Sonntag et al. | Model-as-you-go: an approach for an advanced infrastructure for scientific workflows | |
DE102020108374A1 (de) | Verfahren und vorrichtung zur laufzeitmehrfachplanung von software, die in einem heterogenen system ausgeführt wird | |
US20160117087A1 (en) | Job creation and reuse | |
US10990359B2 (en) | Use and advancements of assistive technology in automation for the visually-impaired workforce | |
CN106096145B (zh) | 一种基于状态空间的复杂系统图形化建模与分析系统 | |
Tolosana‐Calasanz et al. | Autonomic streaming pipeline for scientific workflows | |
AU2022202376A1 (en) | Correlated incremental loading of multiple data sets for an interactive data prep application | |
de Lara et al. | Domain-specific discrete event modelling and simulation using graph transformation | |
US20170090917A1 (en) | Context-specific view of a hierarchical data structure | |
Letia et al. | Unified enhanced time Petri net models for development of the reactive applications | |
Daniels et al. | RxJS in Action | |
Erb et al. | A conceptual model for event-sourced graph computing | |
Filip | Designing and building modern information systems; A series of decisions to be made | |
CN106055714A (zh) | 一种从ria页面中抓取云计算数据的方法 | |
Banti et al. | An accessible verification environment for UML models of services | |
Vargas-Solar et al. | Big continuous data: dealing with velocity by composing event streams | |
JP2023504637A (ja) | Etlパイプライン処理のためのシステム及び方法 | |
Cano et al. | Session-based concurrency, reactively |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
CB02 | Change of applicant information | ||
CB02 | Change of applicant information |
Address after: American California Applicant after: Google limited liability company Address before: American California Applicant before: Google Inc. |
|
GR01 | Patent grant | ||
GR01 | Patent grant |