Streaming System 第一章翻译

GIthub链接,欢迎志同道合的小伙伴一起翻译

Chapter 1.Streaming101

如今,流数据处理在大数据中是非常重要的,其主要原因是:

  • 企业渴望对他们的数据有更及时的了解,而转换到流处理是实现更低延迟的一个好方法;
  • 现代商业的海量、无界的数据集日益增加,通过使用专为此类无限的数据量设计的系统,可以更容易地处理数据;
  • 数据到达时的处理工作负载在一段时间内更均匀地分布,从而产生更一致和可预测的资源消耗。(个人理解:数据到达时立刻处理,资源消耗较少)

尽管商业驱动使得对流的兴趣激增,但与它们的同类批量系统相比,streaming system长期以来仍然相对不成熟。直到最近,这股潮流才决定性地转向了另一个方向。一小部分原因可能是因为我的“Streaming101”和“Streaming102”博客文章中提供了大量的激励(这本书的前几章显然是基于这些博文)。但在现实中,也有很多行业对streaming system的成熟感兴趣,有很多聪明和活跃的人喜欢构建它们。

首先,我将介绍一些重要的背景信息,这些信息将有助于构建我想讨论的其他主题。主要分为以下三个具体的部分:

Terminology

  • 精确地定义术语。对于一些在当前使用中有过多解释的术语,当我说它们的时候,我会试着明确我的意思。
    Capabilities
  • 我谈到了streaming system的缺点。我还提出了我认为数据处理系统构建者需要采用的思想框架,以满足未来的数据处理需要。

Time domains

  • 我将介绍与数据处理相关的两个主要时间领域,展示它们之间的关系。

Terminology: What Is Streaming?

在进一步讨论之前,我想先澄清一件事:什么是流?流这个术语今天被用来表示各种不同的东西,这可能会导致人们对流的真正含义或streaming system的实际能力的误解。因此,我更倾向于对这个术语进行更精确的定义。

问题的关键在于,许多本来应该被描述为什么的东西(unbounded data processing, approximate results, etc. 无界数据处理,近似结果,等等),现在却被通俗地描述为它们在历史上是如何被完成的(例如,通过流执行引擎)。术语的精确性的缺乏使流的真正含义变得模糊,并且在某些情况下,它使streaming system本身被误解,因为它们的能力被限制于在历史上被描述为“流”的特性上,例如流处理的结果是近似的或推测的(approximate or speculative results)。

考虑到设计良好的streaming system对比现有的批处理系统(batch engine,)一样能够产生正确、一致、可重复的结果,我倾向于将术语“流”分离为一个非常具体的含义:

Streaming system

  • 一种数据处理引擎,在设计时考虑了无限的数据集。
    如果我想谈论低延迟(low-latency)、近似(approximate)或推测(speculative results)的结果,我使用这些特定的词,而不是不精确地称它们为“流”(“streaming)。

在讨论可能遇到的不同类型的数据时,精确的术语也很有用。从我的角度来看,有两个重要的(且正交的)维度定义了给定数据集的形状:cardinality and constitution(基数和构成)。

一个数据集的cardinality决定了它的大小,cardinality最显著的方面是给定的数据集是有限的还是无限的(finite or infinite)。下面是我喜欢用的两个术语来描述数据集中的coarse cardinality:

Bounded data

  • A type of dataset that is finite in size.

Unbounded data

  • A type of dataset that is infinite in size (at least theoretically).

cardinality很重要,因为无限数据集的无界特性给使用它们的数据处理框架带来了额外的负担。下一节将详细介绍这一点。
另一方面,数据集的constitution决定了它的物理表现。因此,constitution定义了与数据交互的方式。在第六章之前,我们不会深入研究constitution,但让你们简单了解一下,有两个重要的constitution:

Table

  • A holistic view of a dataset at a specific point in time. SQL systems have traditionally dealt in tables. (数据集在特定时间点的整体视图。SQL系统传统上是处理表的。)

Stream

  • An element-by-element view of the evolution of a dataset over time. The MapReduce lineage of data processing systems have traditionally dealt in streams. (数据集随时间变化的逐元素视图。数据处理系统的MapReduce沿袭传统上是在流中处理的。)

在第6、8和9章中,我们深入研究了流和表之间的关系,在第8章中,我们还了解了将它们联系在一起的time-varying relations的统一的基本概念(underlying concept)。但在那之前,我们主要在流中处理,因为constitution pipeline developers(开发人员)直接与当今大多数数据处理系统(包括批处理和流处理)进行交互。它也是最自然地体现流处理特有挑战的构造。

On the Greatly Exaggerated Limitations of Streaming (论流被过分夸大的局限性)

在这一点上,让我们接下来讨论一下streaming system能做什么和不能做什么,重点是能做什么。在这一章中,我想要阐述的最重要的事情之一就是一个设计良好的streaming system可以有多强大。streaming system在历史上一直服务于需要低延迟、结果不需要十分准确或可接受推测性结果的市场,streaming system通常与更强大的批处理系统一起提供最终正确的结果;换句话说,就是Lambda Architecture.。

对于那些还不熟悉Lambda体系结构的人来说,其基本思想是在运行批处理系统的同时运行streaming system,两者执行本质上相同的计算。streaming system提供低延迟、不准确的结果(可能是因为使用了近似算法,也可能是因为streaming system本身不提供正确性),一段时间后,批处理系统将继续运行,并提供正确的输出。这个想法最初是由Twitter的Nathan Marz (Storm的创造者)提出的,最终非常成功,因为这在当时是一个非常棒的想法;流引擎在正确性方面有点令人失望,而批处理引擎inherently unwieldy(比较笨重),所以Lambda提供了一种双赢的方式。不幸的是,维护Lambda系统很麻烦:需要构建、提供和维护两个独立的pipeline,然后还需要以某种方式在最后合并两个pipeline的结果。

我认为设计良好的streaming system实际上提供了严格的批处理功能的超集(superset)。

批处理和流处理的效率差异

批处理和流处理之间的效率差很大程度上是由于批处理系统中增加的bundling和更高效的shuffle传输的结果。
批处理系统是当今效率极高的系统,没有理由不能整合到为无限数据设计的系统中,为用户提供在高延迟、高效率的“批处理”和低延迟、低效率的“流”处理之间的灵活选择。这就是我们在谷歌上使用云数据流所做的,我们在相同的统一模型下提供了批处理和流运行器。在我们的案例中,我们使用独立的运行器,因为我们碰巧有两个独立设计的系统,它们针对特定的用例进行了优化。从长远来看,从工程学的角度来看,我希望看到我们将两者合并成一个系统,在保持选择合适效率水平的灵活性的同时,将两者最好的部分结合在一起。

streaming system能够击败批系统最重要的只有两件事:

Correctness(正确性)

  • 这能让streaming system和批系统一样。正确性的核心是一致的存储。streaming system需要一种随着时间checkpointing persistent state的方法,而且它必须设计得足够好,以在机器故障时保持一致。

对于exactly-once processing的处理,需要很强的一致性,这是正确性的要求,这是任何有机会达到或超过批处理系统能力的系统的要求。除非你真的不关心结果,否则我恳请你不要使用任何不提供强一致性状态的streaming system。批处理系统不要求你提前验证它们是否有能力给出正确答案;不要把你的时间浪费在无法满足相同标准的流系统上。

Tools for reasoning about time (用来推理时间的工具)

  • 这可以让你超越批系统。好的时间推理工具对于处理event-time skew的无界、无序数据是必不可少的。越来越多的现代数据集显示出无界无序的特征,而现有的批处理系统(以及许多streaming system)缺乏必要的工具来应对它们带来的困难(尽管这一点现在正在迅速改变,甚至在我写这篇文章的时候)。我们将用本书的大部分篇幅来解释和关注这一点的各个方面。

首先,我们对时间域这个重要概念有一个基本的理解,然后我们将更深入地了解我所说的无边界、无顺序的变化event time偏移 (unbounded, unordered data of varying event-time skew)是什么意思。然后,我们将在本章的其余部分讨论使用批处理和流处理系统进行有界和无界数据处理的常用方法。

Event Time Versus processing time

Event time

  • 这是事件实际发生的时间。

processing time

  • 这是在系统中观察到事件的时间。(到达流处理系统的时间)

在理想情况下,event time和processing time总是相等的,事件一发生就立即被处理。然而,现实情况并非如此,event time和processing time之间的偏差不仅是非零的,而且经常是底层输入源、执行引擎和硬件特征(underlying input sources, execution engine, and hardware)的一个高度可变的函数。影响skew程度的因素包括:

  • 共享资源限制,如网络拥塞、网络分区或非专用环境中的共享CPU
  • 软件引起的问题有分布式系统逻辑、竞争等
  • 数据本身的特征,如key distribution, variance in throughput, or variance in disorder(例如,一架飞机上的乘客在整个飞行过程中使用了离线的手机后,直到关闭飞行模式,数据才开始上传)。

因此,如果你在任何现实世界的系统中绘制event time和processing time的进度,你通常会得到类似图1-1中的红线的结果。
[图片]

图1-1中,斜率为1的黑色虚线表示理想状态,此时processing time与event time完全相等;红线代表现实。在这个例子中,系统在processing time开始时有一点滞后,在processing time中间更接近理想状态,然后在processing time结束时又有一点滞后。乍一看,在这张图中有两种类型的skew,每一种都位于不同的时间域:

processing time

  • 理想和红线之间的垂直距离是processing time域的滞后。这个距离告诉你在给定时间内事件发生和事件被处理之间观察到的延迟(在processing time中)有多少。这也许是两种偏差中比较自然和直观的一种。

Event time

  • 理想状态与红线之间的水平距离是该时刻pipeline中event time偏移量。它告诉你当前pipeline距离理想(event time)还有多远。

实际上,在任何给定的时间点上,processing time滞后和event-time skew(processing-time lag and event-time skew)是相同的;它们只是看待同一件事的两种方式。关于lag/skew的重要结论是:因为event time和processing time之间的整体映射不是静态的(即,lag/skew可以随时间任意变化),这意味着如果你关心它们的event time(即事件实际发生的时间),你不能只在pipeline观察到它们的上下文中分析数据。不幸的是,许多为无限数据设计的系统在历史上就是这样操作的。为了处理无界数据集的无限本质,这些系统通常提供一些对输入数据进行窗口化的概念。我们稍后将更深入地讨论窗口,但它本质上意味着沿着时间边界将数据集分割成有限的块。如果你关心正确性,并对在event time上下文中分析数据感兴趣,那么你不能像许多系统那样使用processing time(即processing time窗口)来定义这些时间边界;由于processing time和event time之间没有一致的相关性,一些event time数据将会在错误的processing time窗口中结束(由于分布式系统的固有滞后,许多类型的输入源的在线/离线性质,等等),将正确性排除在窗外。

不幸的是,如果按event time来划分,情况也并不乐观。在数据无界的情况下,无序和变量skew会导致event time窗口的完整性问题:在processing time和event time之间缺乏可预测的映射,你如何确定何时已经观察到给定event time X的所有数据?对于许多现实世界的数据源,你根本不能。但是,目前使用的绝大多数数据处理系统都依赖于某些完整性概念,这使得它们在应用于无界数据集时处于严重的劣势。

与其试图将无穷无尽的数据整理成有限批的信息,不如设计一些工具,让我们能够生活在由这些复杂数据集带来的不确定性世界中。新数据将会到来,旧数据可能会被收回或更新,我们构建的任何系统都应该能够自己处理这些事实,完整性的概念是针对特定和适当的用例的方便优化,而不是满足所有用例的语义需要。

Data Processing Patterns

至此,我们已经有了足够的背景知识,可以开始研究当今有界和无界数据处理的常见使用模式的核心类型了。我们着眼于这两种类型的处理,并将其与我们所关心的两种主要类型的引擎(批处理和流处理,在这里,我将微批处理与流处理混为一谈,因为这两者之间的区别在这个级别上并不重要)。

Bounded Data

处理有界数据在概念上是非常简单的,并且可能对每个人都很熟悉。在图1-2中,我们从一个充满熵的数据集开始。我们通过一些数据处理引擎(通常是批处理,尽管精心设计的流引擎也可以很好地工作)运行它,比如MapReduce,在右侧最终得到一个具有更大内在价值的新结构化数据集。
[图片]

现在让我们看看处理无界数据的各种方法,首先是传统批处理引擎使用的方法,然后是为无界数据设计的系统可以采用的方法,如大多数流或微批处理引擎。

Unbounded Data: Batch

批处理引擎,虽然没有明确地设计为无界数据,但从批处理系统的第一个构想开始,就被用于处理无界数据集。这种方法围绕着将无界数据分割成适合于批处理的有界数据集集合。

Fixed windows

使用批处理引擎重复运行处理无界数据集的最常见方法是将输入数据划分为固定大小的窗口,然后将每个窗口作为单独的、有界的数据源(有时也称为翻滚窗口)处理,如图1-3所示。特别是对于像日志这样的输入源,事件可以被写入目录和文件层次结构中,这些目录和文件层次结构的名称编码了它们对应的窗口,这类事情乍一看非常简单,因为你实际上已经执行了基于时间的shuffle,以便提前将数据放入适当的event time窗口中。

然而,实际上,大多数系统仍然有完整性问题需要处理(如果由于网络分区,你的一些事件在发送到日志的途中被延迟了,该怎么办?如果你的事件是全局收集的,并且必须在处理之前转移到一个公共位置,该怎么办?如果你的事件来自移动设备怎么办?),这意味着可能需要某种方式(例如,延迟处理,直到你确定所有事件都已收集,或在数据延迟到达时重新处理给定窗口的整个批次)。
![[图片]](https://img-blog.csdnimg.cn/982009572c004968a5f6fe6d01b00560.png

Sessions(会话)

当你尝试使用批处理引擎将无界数据处理成更复杂的窗口策略(如sessions)时,这种方法会breaks down。sessions通常定义为活动的周期(例如,对于特定用户),由一段不活动间隙终止。当使用典型的批处理引擎计算sessions时,你通常会得到跨批处理的sessions,如图1-4中的红色标记所示。我们可以通过增加批处理的大小来减少分割的数量,但以增加延迟为代价。另一种选择是添加额外的逻辑来拼接以前运行的sessions,但以进一步复杂为代价。
[图片]

不管怎样,使用经典的批处理引擎来计算sessions都不太理想。一种更好的方式是以流的方式构建sessions,我们将在后面讨论。

Unbounded Data: Streaming

与大多数基于批处理的无界数据处理方法的临时性质相反,streaming system是为无界数据构建的。正如我们前面谈到的,对于许多现实世界的分布式输入源,你不仅要处理无界数据,还需要处理以下数据:

  • event time是高度无序的,这意味着如果你想在事件发生的上下文中分析数据,要做基于时间的排序。
  • 变化的event-time skew,这意味着你不能假设你总是能看到给定event time X的大部分数据在某个常数的时间Y内。

在处理具有这些特征的数据时,可以采用几种方法。我通常将这些方法分为四组:时间无关的、近似的、按processing time和按event time进行窗口操作(time-agnostic, approximation, windowing by processing time, and windowing by event time)。

Time-agnostic

时间无关处理用于时间基本上无关的情况;也就是说,所有相关的逻辑都是数据驱动的。因为这些用例的所有内容都是由更多数据的到来所决定的,所以除了基本的数据交付外,流引擎实际上不需要支持任何特殊的东西。因此,基本上所有现有的streaming system都支持开箱即用的与时间无关的用例(当然,如果你关心正确性的话,可以在一致性方面对系统到系统的差异进行模量保证)。批处理系统也非常适合于对无界数据源进行时间无关的处理,它将无界数据源简单地切分成任意的有界数据集序列,并独立地处理这些数据集。(如公司年报)

Filtering

一种非常基本的与时间无关的处理形式是过滤,如图1-5所示。假设你正在处理web流量日志,并希望过滤掉所有不是来自特定域的流量。你将在每个记录到达时查看它,看看它是否属于感兴趣的领域,如果不属于则删除它。因为这类事情在任何时候都只依赖于单个元素,所以数据源是无界的、无序的和变化的event time偏移的事实是无关的。
[图片]

Inner joins

另一个与时间无关的例子是内部连接,如图1-6所示。当连接两个无界数据源时,如果你只关心来自两个数据源的元素到达时的连接结果,那么逻辑中不存在时间元素。在看到一个源的值时,你可以简单地将它缓冲为持久化状态;只有当来自另一个源的第二个值到达后,你才需要发出所连接的记录。(实际上,你可能希望为未发出的部分连接使用某种垃圾收集策略,这种策略可能是基于时间的。但是对于有很少或没有未完成连接的用例,这样的事情可能不是问题。)
[图片]

某种类型的外部连接会引入我们讨论过的数据完整性问题:在看到连接的一端后,如何知道另一端是否会到达?说实话,你不需要,所以你需要引入一些超时的概念,它引入了一个时间元素。时间元素本质上是一种窗口形式,我们稍后会更详细地讨论它。

Approximation algorithms

第二类主要的方法是近似算法,例如近似Top-N,流k-means,等等。它们接受无限制的输入源,并提供输出数据,如果你仔细看,就会发现这些数据或多或少是你希望得到的,如图1-7所示。近似算法的优点在于,设计上,它们的开销很低,而且专为无界数据设计。缺点是它们的数量有限,算法本身通常很复杂(这使得我们很难想出新的算法),而且它们的近似性质限制了它们的实用性。
[图片]

值得注意的是,这些算法通常在设计中确实有一些时间元素(例如,某种内置衰减)。由于它们在元素到达时进行处理,所以时间元素通常基于processing time。这对于在近似上提供某种可证明的误差范围的算法来说尤为重要。如果这些错误边界是基于数据的顺序,那么当你为算法提供带有不同event-time skew的无序数据时,它们基本上毫无意义。这是需要记住的。近似算法本身是一个迷人的主题,但由于它们本质上是时间无关处理的另一个例子(对算法本身的时间特性进行模化),它们使用起来非常简单,因此不值得进一步关注。

Windowing

其余两种用于无界数据处理的方法都是窗口的变体。在深入研究它们之间的区别之前,我应该明确地说明我所说的“窗口”是什么意思,因为我们在前一节中只是简单地谈到了它。窗口只是获取数据源(无界的或有界的)的概念,并沿着时间边界将其分割成有限块进行处理。图1-8显示了三种不同的窗口模式。
[图片]

让我们仔细看看这些策略:
Fixed windows (aka tumbling windows)

  • 我们之前讨论过固定窗户。固定的窗口切片时间与固定大小的时间长度片段。通常(如图1-9所示),固定窗口的段在整个数据集上统一应用,这是aligned windows的一个例子。在某些情况下,需要对数据的不同子集(例如,每个键)的窗口进行相移,以便在一段时间内更均匀地扩展窗口完成负载,这是一个unaligned windows的例子,因为它们在数据之间变化。

Sliding windows (aka hopping windows)

  • 一种一般化的固定窗口,滑动窗口由固定长度和固定周期定义。如果窗口长度大于周期,则窗口重叠。如果周期等于长度,则有固定窗口。如果窗口长度小于周期,每一个采样窗口它只会观察一段时间内数据的子集。与固定窗口一样,滑动窗口通常是对齐的,尽管在某些用例中,它们可以作为性能优化而不对齐。请注意,图1-8中的滑动窗口是为了给人一种滑动运动的感觉而绘制的;实际上,所有5个窗口都适用于整个数据集。

Sessions(会话)

  • 动态窗口的一个例子是,sessions是由一系列事件组成的,这些事件由超过某个超时的不活动间隙终止。sessions通常用于分析用户的行为,通过将一系列时间上相关的事件组合在一起(例如,一次观看的一系列视频)。sessions之所以有趣,是因为它们的长度不能预先定义;它们依赖于所涉及的实际数据。它们也是不对齐窗口的典型例子,因为sessions实际上在不同的数据子集(例如,不同的用户)之间从不相同。
Windowing by processing time

当按processing time划分窗口时,系统本质上是将传入的数据缓冲到窗口中,直到经过一定的processing time。例如,在5分钟固定窗口的情况下,系统将缓冲数据5分钟的processing time,之后它将把这5分钟内观察到的所有数据作为一个窗口,并将它们发送到下游进行处理。
[图片]
processing time窗口有几个很好的特性:

  • 实现非常简单,因为你无需担心在一定时间内打乱数据。你只需要在它们到达时进行缓冲,然后在窗口关闭时将它们发送到下游。
  • 判断窗口完整性是很简单的。因为系统对窗口的所有输入是否已被看到有充分的了解,它可以对给定的窗口是否完整做出完美的决定。这意味着,当按processing time划分窗口时,不需要以任何方式处理“延迟”数据。
  • 如果你希望在观察到源文件时推断出有关源文件的信息,那么processing time窗口正是你所需要的。许多监控场景都属于这一类。想象一下,跟踪每秒发送到全球范围的web服务的请求数。计算这些请求的速率以检测中断是processing time窗口的完美使用。

抛开优点不谈,processing time窗口有一个非常大的缺点:如果有问题的数据与event time相关,那么如果processing time窗口要反映这些事件实际发生的时间,那么这些数据必须按照event time顺序到达。不幸的是,按照event time顺序的数据在真实世界并不常见。

举个简单的例子,假设任何一个移动应用程序收集使用统计数据以供以后处理。对于一个给定的移动设备在任何时间内离线的情况(短暂的连接中断,飞行时的飞行模式,等等),在这段时间内记录的数据将不会被上传,直到设备重新上线。这意味着数据可能带有分钟、小时、天、周或更多的event time偏移。当按processing time划分窗口时,基本上不可能从这样的数据集中得出任何有用的推论。

另一个例子是,当整个系统处于健康状态时,许多分布式输入源似乎提供了event time顺序(或非常接近于event time顺序)的数据。不幸的是,在正常情况下,输入源的event-time skew较低并不意味着它将始终保持这种状态。考虑一个处理在多个大陆收集的数据的全球服务。如果带宽受限的跨大陆线路上的网络问题(令人遗憾的是,这种问题非常普遍)进一步降低了带宽和/或增加了延迟,那么输入数据的一部分可能突然开始以比以前更大的偏移方式到达。如果你按processing time对这些数据进行窗口化,那么你的窗口将不再代表其中实际发生的数据;相反,它们表示事件到达处理pipeline时的时间窗口,处理pipeline是旧数据和当前数据的任意组合。在这两种情况下,我们真正想要的是,以一种对事件到达顺序健壮的方式,通过event time来显示数据。我们真正想要的是event time窗口。

Windowing by event time

event time窗口是在需要观察有限块中的数据源时使用的窗口,这些数据块反映了这些事件实际发生的时间。这是开窗的黄金标准。
图1-10展示了一个将无界源划分为一个小时固定窗口的例子。
[图片]
图1-10中的黑色箭头显示了两个特别有趣的数据。每个数据到达的processing time窗口与每个数据位所属的event time窗口不匹配。因此,如果这些数据被窗口化到一个关心event time的用例的processing time窗口中,那么计算的结果将是不正确的。event time正确性是使用event time窗口的一个好处。

event time窗口在无界数据源上的另一个好处是,你可以创建动态大小的窗口,比如sessions,而不会在固定窗口上生成sessions时观察到的任意分割(正如我们在“无界数据:流”的sessions示例中看到的那样),如图1-11所示。
[图片]

event time窗口有两个明显的缺点,因为窗口通常必须比窗口本身的实际长度(processing time)更长的事实:
Buffering

  • 由于窗口生存期延长,需要更多的数据缓冲。幸运的是,在大多数数据处理系统所依赖的资源类型中,持久性存储通常是最便宜的(其他的主要是CPU、网络带宽和RAM)。因此,在使用任何设计良好的数据处理系统(具有强一致性的持久状态和良好的内存缓存层)时,这个问题通常比你想象的要小得多。此外,许多有用的聚合不需要缓冲整个输入集(例如,求和或平均),而是可以增量地执行,使用一个小得多的中间聚合存储在持久状态。

Completeness

  • 假设我们经常没有好的方法来知道我们什么时候看到了给定窗口的所有数据,那么我们如何知道窗口的结果什么时候准备好实现呢?事实上,我们根本不知道。对于许多类型的输入,系统可以通过MillWheel、Cloud Dataflow和Flink(我们将在第3章和第4章详细讨论)中的watermark等方法,给出一个合理准确的启启式窗口完成估计。但对于绝对正确性至关重要的情况(再次考虑一下账单),唯一的选择是为pipeline builder提供一种方式,来表示他们希望窗口的结果具体化,以及这些结果应该如何随着时间的推移而细化。

Summary

在深入研究Beam模型方法之前,让我们简要回顾一下到目前为止我们所学到的内容。在本章中,我们做了以下工作:

  • 澄清了术语,将重点放在“流”的定义上,即指用无边界数据构建的系统,同时使用更描述性的术语,如近似/推测结果,用于通常归类在“流”伞下的不同概念。此外,我们强调了大规模数据集的两个重要维度:cardinality(即有界与无界)和编码(即表与流),后者将占据本书后半部分的大部分内容。
  • 评估了设计良好的批处理和流处理系统的相对能力,假设流处理实际上是批处理的一个严格的超集,并且像Lambda体系结构,流处理不如批处理这样的概念,注定会随着流处理系统的成熟而退役。
  • 提出了streaming system追赶并最终超越批处理所必需的两个高级概念,分别是correctness和tools for reasoning about time。
  • 建立了event time和processing time之间的重要差异,描述了这些差异在分析数据时所带来的困难,并提出了一种方法的转变,从完整性的概念转向简单地适应数据随时间的变化。
  • 通过批处理引擎和流引擎,我们查看了目前常用的处理有界数据和无界数据的主要数据处理方法,粗略地将无界数据处理方法分为:time-agnostic, approximation, windowing by processing time, and windowing by event time.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值