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窗口中。
然而,实际上,大多数系统仍然有完整性问题需要处理(如果由于网络分区,你的一些事件在发送到日志的途中被延迟了,该怎么办?如果你的事件是全局收集的,并且必须在处理之前转移到一个公共位置,该怎么办?如果你的事件来自移动设备怎么办?),这意味着可能需要某种方式(例如,延迟处理,直到你确定所有事件都已收集,或在数据延迟到达时重新处理给定窗口的整个批次)。
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.
相关文章:
Streaming System是第一章翻译
GIthub链接,欢迎志同道合的小伙伴一起翻译 Chapter 1.Streaming101 如今,流数据处理在大数据中是非常重要的,其主要原因是: 企业渴望对他们的数据有更及时的了解,而转换到流处理是实现更低延迟的一个好方法…...
abap MODIFY常用语法解析
MODIFY 是既可以操作数据又可以操作内表的一个语法, 实现的逻辑都一样. 如果你内表或数据库中存在该行数据会对该行数据进行更新. 如果不存在,就会插入数据. , 1.如果it_tab是带有标题行的内表,是可以忽略FROM wa_tab工作区的 MODIFY it_tab .2.把工作区wa_tab中的数据更新…...
[媒体分流直播]媒体直播和传统直播的区别,以及媒体直播的特点
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 直播毋庸置疑已经融入到了我们生活的方方面面,小到才艺,游戏,大到政策的发布,许多企业和机构也越来越重视直播,那么一场活动怎…...
打地鼠游戏-第14届蓝桥杯STEMA测评Scratch真题精选
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第102讲。 蓝桥杯选拔赛现已更名为STEMA,即STEM 能力测试,是蓝桥杯大赛组委会与美国普林斯顿多…...
链表经典刷题--快慢指针与双指针
本篇总结链表解题思路----快慢指针,其实也就是双指针,这个快慢并不单纯指“快慢”,它更多的可以表示,速度快慢,距离长度,时间大小等等,用法很有趣也很独特,理解它的思想,…...
【Java集合框架】篇四:Set接口
1. Set及主要实现类特点 Set:无序、不可重复(去重)、存储value HashSet:底层使用HashMap,即使用 数组单项链表红黑树 结构进行存储。(jkd8中) LinkedHashSet:是HashSet的子类&…...
Python 数据库连接 + 创建库表+ 插入【内含代码实例】
人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB.在TESTDB数据库中您已经创建了表 EMPLOYEEEMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。连…...
DSS 部署环境需求清单
文章目录 DSS系统需求项目地址计算资源计算基准:计算引擎程序硬件需求表 :DSS计算及存储资源需求计算资源计算基准:计算程序硬件需求表:DSS系统需求 项目地址 https://github.com/WeBankFinTech/DataSphereStudio 计算资源计算基准: 1.日活用户10万。 2.单用户单日总…...
Python的面向对象,详细讲解Python之用处等基本常识
目录 Python 面向对象 面向对象技术简介 创建类 实例 实例 self代表类的实例,而非类 实例 创建实例对象 访问属性 实例 Python内置类属性 实例 python对象销毁(垃圾回收) 实例 实例 类的继承 实例 方法重写 实例 基础重载方法 运算符重载 实例…...
如何使用固态继电器为恒温器供电
恒温器有两种电源:电池和 24VAC。恒温器需要电池才能不间断地运行。电池消耗的能量尽可能低非常重要,但即使您最大限度地减少消耗,这仍然不是一个用户友好的选择,因为电池会不时需要更换。要降低更换频率,可以使用 24V…...
【LeetCode】剑指 Offer(14)
目录 题目:剑指 Offer 32 - I. 从上到下打印二叉树 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:剑指 Offer 32…...
Rman单实例迁移到单实例
关于同平台同版本数据库之间的迁移操作的实验 ---Source DB[rootoracle-db-19cs ~]# cat /etc/redhat-release CentOS Stream release 8 [rootoracle-db-19cs ~]# --- Target DB[rootoracle-db-19ct ~]# cat /etc/redhat-release CentOS Stream release 8 [rootoracle-db-19ct…...
毕业设计 基于stm32舞台彩灯控制器设计app控制系统
基于stm32舞台彩灯控制器设计app控制1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STM32F103C8T6核心系统电路设计2.2 WS2812RGB彩灯电路设计3、部分代码展示3.1 控制WS2812显示颜色3.2 设置RGB灯的颜色,角度,亮度实物图1、项目简介 选题指导…...
【MyBatis】篇一.
文章目录1、MyBatis概述2、环境搭建1、MyBatis概述 认识: JavaEE开发的一个套件SSM,即: MyBatis是一个持久层的框架,是对JDBC的一个封装,是一个半自动的ORM框架。 ORM即实体类对象和数据库中的数据的一个映射关系&am…...
【JavaScript速成之路】JavaScript流程控制
📃个人主页:「小杨」的csdn博客 🔥系列专栏:【JavaScript速成之路】 🐳希望大家多多支持🥰一起进步呀! 文章目录前言1,流程控制2,分支结构2.1,if语句2.2&…...
18、基准测试,sysbench
基准测试,sysbench 1. sysbench1.1 用途1.2 安装1.3 版本1.4 查看帮助1.5 测试过程阶段2 CPU 性能测试2.1 测试原理2.2 查看帮助2.3 测试3. 内存性能测试3.1 查看帮助信息3.2 测试过程4.磁盘性能基准测试4.1 查看帮助4.2 生成文件(prepare)4.3 测试文件io(run)4.4 结果分析4.5…...
3D,点云拼接2
文章目录 点云配准方法自动配准技术PCL实现的配准算法两两配准1.关键点提取2.特征描述符3. 对应关系估计4. 对应关系去除5. 变换矩阵估算在上篇文章中对于拼接的概念、拼接精度的评价做了详细的介绍。本文是对拼接(配准)的进一步介绍,涉及更多原理层面的东西。 主要围绕以下三…...
jmeter学习笔记一(http基础知识)
HTTP请求:客户端同通过发送http请求向服务器请求资源的访问。http请求由三部分组成:请求行、请求头、请求正文 请求行包括:请求方法 URI 协议/版本 请求头:Content-type、Cookie、Authorization、User-Agent、Accept、Acc…...
【Java】CompletableFuture 并发顺序调度
前言 Java CompletableFuture 提供了一种异步编程的方式,可以在一个线程中执行长时间的任务,而不会堵塞主线程。 和Future相比,CompletableFuture不仅实现了Future接口,也实现了 CompletionStage接口。Future接口不用多说&#…...
职场人必备的6款实用办公app,每一款都是心头爱
打工人不容易啊,不提高工作效率怕是要被淘汰了。今天给大家分享6款职场人必备的实用办公APP,免费效率神器让工作事半功倍。这些APP每一款都是我的心头爱,肯定会让人大开眼界的,超级实用,直接往下看吧。1、向日葵远程控…...
小丑改造计划之复习一
1.函数重载 根据参数个数 参数顺序 参数类型 的不同 可以在同一个域存在多个同名函数 但是不可以根据返回值 缺省参数的不同去重载函数 2.指针和引用的区别 第一点 指针是内存地址,会开辟内存空间,而引用和它所引用的变量共享同一块内存 第二点 引用必须…...
final修饰符使用中遇到的一些问题
文章目录final修饰符1. final不能用来修饰构造方法2. final修饰变量的一些注意问题2.1 final修饰成员变量2.2 final修饰引用类型2.2.1 演示代码中lombok链式编程介绍final修饰符 final具有“不可改变”的含义,它可以修饰非抽象类、非抽象成员方法和变量。 用final…...
好记又实用的获取电脑型号方法
个人常用的方法 方法二最好记又好用。 方法一 dxdiag命令 按下键盘WINR调出运行在输入框输入dxdiag命令后,按下回车;进入DirectX诊断工具,便可查看系统型号等信息。 这里就会显示系统型号。 方法二 设备和打印机 控制面板-查看方式-小图…...
@Transactional配置详解
一:事务注解Transactional,属性propagation的7个配置 PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。,默认配置,也是常用的选择。 PROPAGATION_SUPPORTS -- 支持当前事务&#…...
性能测试面试题汇总
稳定性测试的怎么挑选的接口? 1、频繁使用的接口:选择那些被频繁使用的接口,因为这些接口可能会面临更大的负载和并发访问,从而可能导致性能问题。 2、核心功能接口:选择那些实现系统核心功能的接口,因为这…...
vue权限控制和动态路由
思路 登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到localStore中,保证刷新页面后能记住用户登录状态)…...
利用正则表达式删掉代码中的所有注释-pycharm为例
首先删除注释 打开您想要删除注释的Python文件。 使用快捷键 Ctrl Shift R 打开 "Replace in Files"(在文件中替换)对话框。 在 "Find"(查找)框中输入以下正则表达式,以查找所有行中的注释内容…...
【java基础】内部类、局部内部类、匿名内部类、静态内部类
内部类 内部类就是定义在另一个类中的类。我们使用内部类的原因主要有以下两点 内部类可以对同一个包中的其他类隐藏内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据 public class A {class B {} }我们使用内部类可以访问外部类的所有属性&…...
react renderProps学习记录
react renderProps学习记录1.引入2.改一下呢3.再改一下呢4.总结一下如何向组件内部动态传入带内容的结构(标签)?children propsrender props1.引入 上代码: import React, { Component } from react import ./index.css export default class Parent extends Com…...
关于tf.gather函数batch_dims参数用法的理解
关于tf.gather函数batch_dims参数用法的理解0 前言1. 不考虑batch_dims2. 批处理(考虑batch_dims)2.1 batch_dims12.2 batch_dims02.3 batch_dims>22.4 batch_dims再降为12.5 再将axis降为12.6 batch_dims<02.7 batch_dims总结3. 补充4. 参数和返回值5. 其他相关论述6. 附…...
怎么提高网站的权重/友链申请
IDEA整合GitLab,并进行分支使用一:IDEA安装GitLab插件二:检出项目三:将总分支代码更新到自己的分支中总结步骤3.1介绍3.2 切换总分支,更新代码3.3 将最新代码合并到自己的分支中3.4 push当前master分支的代码到自己的远…...
免费文字logo生成器/厦门关键词优化平台
题目链接 状压DP 本来如果考虑所有情况应该开hh[n][2^10][2^10]表示i行在i-1的状态为j,i-2的状态为k的最大个数 但是由于每行中的人互相限制所以在m10时只有60种情况 空间就可以满足,时间也可以满足了 1 #include<algorithm>2 #include<iostrea…...
可信的昆明网站建设/东莞市优速网络科技有限公司
pyltp的简介 语言技术平台(LTP)经过哈工大社会计算与信息检索研究中心 11 年的持续研发和推广, 是国内外最具影响力的中文处理基础平台。它提供的功能包括中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注等。 pyltp 是 LTP 的 Python 封装࿰…...
湖南移动网站建设/市场调研分析报告
路径的分类:相对路径、绝对路径 绝对路径:所谓绝对路径就是文件在磁盘上的绝对位置,从盘符或协议开始写的一种路径,格式:<img src"C:\Users\SSNH\Desktop\day2\pic.jpg">,注意火狐浏览器要…...
网站设计制作全网优惠/免费顶级域名申请网站
通过对TCP/IP协议的学习,本人写了一个可以实现对PCAP文件中的IPV4下的TCP流提取,以及提取指定的TCP流,鉴于为了学习,没有采用第三方包解析pcap,而是对bytes流进行解析,其核心思想为:若想要提取T…...
独立做网站/海外短视频软件
一、IPC (Inter-Process Communication): --中文翻译是线程间的通信 消息队列共享内存(效率最高)信号灯集二、客户端命令: ipcs:--用来查看system V的IPC机制标识符的命令-q,显示当前系统中 消息队列 的…...