为啥 RDD 不适合流式任务?

Posted

技术标签:

【中文标题】为啥 RDD 不适合流式任务?【英文标题】:Why aren't RDDs suitable for streaming tasks?为什么 RDD 不适合流式任务? 【发布时间】:2016-03-06 02:25:07 【问题描述】:

我广泛使用 Spark,Spark 的核心是 RDD,如 RDD 论文中所示,在流式应用程序方面存在局限性。这是 RDD 论文的准确引用。

如简介中所述,RDD 最适合 对于应用相同操作的批处理应用程序 数据集的所有元素。在这些情况下,RDD 可以 清楚地记住每个转换是一个步骤中的一个步骤 沿袭图,可以恢复丢失的分区而无需 记录大量数据。 RDD 会更少 适用于使异步细粒度的应用程序 更新共享状态,例如存储系统 对于网络应用程序或增量网络爬虫

我不太明白为什么 RDD 不能有效地管理状态。 Spark Streaming 如何克服这些限制?

【问题讨论】:

你可能会在***.com/questions/28082581/… 中得到这个查询的间接答案(为什么 flink 比 Spark 更适合流式传输)。查看该问题中引用的文章和 ppts。 【参考方案1】:

我不太明白为什么 RDD 不能有效地管理状态。

这不是真正的能力,而是更多的成本。我们有完善的机制来处理Write-ahead logging 的细粒度更改,但管理日志的成本很高。这些必须写入持久存储,定期合并,并且在发生故障时需要昂贵的重放。

相比之下,RDD 是非常轻量级的解决方案。它只是一个小的本地数据结构,只需要记住它的沿袭(祖先和应用的转换)。

这是否意味着不可能在 Spark 之上创建至少部分有状态的系统。看看Caffe-on-Spark architecture。

Spark Streaming 如何克服这些限制?

它没有,或者更准确地说,它在外部独立于 RDD 抽象处理这个问题。它包括使用具有源特定保证的输入和输出操作以及用于处理接收数据的容错存储。

【讨论】:

【参考方案2】:

在the paper的其他地方有解释:

现有的集群内存存储抽象,例如分布式共享内存 [24]、键值存储 [25]、数据库和 Piccolo [27],提供了基于对可变状态的细粒度更新的接口(例如,表格中的单元格)。使用此接口,提供容错的唯一方法是跨机器复制数据或跨机器记录更新。这两种方法对于数据密集型工作负载来说都是昂贵的,因为它们需要通过集群网络复制大量数据,而集群网络的带宽远低于 RAM,并且它们会产生大量的存储开销。

与这些系统相比,RDD 提供了一个基于粗粒度转换(例如映射、过滤和连接)的接口,这些转换将相同的操作应用于许多数据项。这允许他们通过记录用于构建数据集(其沿袭)而不是实际数据的转换来有效地提供容错。1 如果 RDD 的分区丢失,RDD 有足够的信息来说明它是如何从其他 RDD 派生的重新计算那个分区。因此,可以很快恢复丢失的数据,而无需进行昂贵的复制。

正如我所解释的那样,处理流式应用程序需要系统对单个单元进行大量写入,将数据推送到网络、I/O 和其他成本高昂的事情上。 RDD 旨在通过主要支持可组合的功能类型操作来避免所有这些事情。

这与我大约 9 个月前在 edx 上进行基于 Spark 的 MOOC 时的回忆一致(遗憾的是当时还没有触及它)——我记得,Spark 甚至懒得计算结果直到用户真正需要一些输出之前,RDDs 上的地图,这样可以节省大量的计算。

【讨论】:

以上是关于为啥 RDD 不适合流式任务?的主要内容,如果未能解决你的问题,请参考以下文章

流式计算助力实时数据处理spark-streaming入门实战

为啥 MicroBatchReader 必须是可序列化的?任务不可序列化错误

RDD和SparkSQL综合应用

将rdd转换为数据框时,pyspark对mapPartitions使用一项任务

RDD的缓存,依赖,spark提交任务流程

Spark任务流程笔记