我想了解一些关于火花流执行的内部结构。
如果我有一个流X,并且在我的程序中,我将流X发送到功能A和功能B:
在函数A中,我在X-> Y-> Z上做了一些变换/滤波操作等来创建流Z.现在我在Z上执行forEach操作并将输出打印到文件
然后在功能B中,我减少流X - > X2(表示每个RDD的最小值),并将输出打印到文件
是否并行执行每个RDD的两个功能?它是如何工作的?
由于
--- Spark社区的评论----
我正在添加来自spark社区的评论 -
如果在驱动程序中的两个线程中执行collect步骤(foreach in 1,可能在2中减少),则它们将并行执行。无论哪个提交给Spark首先被执行 - 如果你需要确保执行顺序,你可以使用信号量,但我会认为排序不重要。
答案 0 :(得分:0)
是。 它类似于spark的执行模型,它使用DAG和惰性评估,除了流在每批新数据上重复运行DAG。 在您的情况下,由于完成每个操作所需的DAG(或更大的DAG的子DAG,如果有人喜欢这种方式调用)(您拥有的2个 foreach 中的每一个)都没有公共链接一直到源,它们完全并行运行。整个流应用程序在应用程序提交给资源管理器时分配给每个执行程序分配X执行程序(JVM)和Y核心(线程)。任何时候,给定X * Y任务中的任务(即线程)将执行这些DAG的一个的一部分或全部。请注意,应用程序的任何2个给定线程,无论是在同一执行程序中还是其他程序,都可以执行同一应用程序的不同动作同时进行。
答案 1 :(得分:0)
@ Eswara的回答似乎是正确的,但它不适用于您的用例,因为您的单独转换DAG(X->Y->Z
和X->X2
)有一个共同的DStream祖先X
。这意味着当运行操作以触发每个流时,转换X->Y
和转换X->X2
不能同时发生。将会发生的是RDD X
的分区将以非并行方式分别为每个转换计算或从内存加载(如果已缓存)。
理想情况下,转换X->Y
将会解决然后转换Y->Z
和X->X2
并行完成,因为它们之间没有共享状态。我相信Spark的流水线架构会为此进行优化。您可以通过持久化DStream X->X2
来确保X
上的更快计算,以便可以从内存加载而不是重新计算或从磁盘加载。有关持久性的更多信息,请参阅here。
有趣的是,如果您可以提供复制存储级别*_2
(例如MEMORY_ONLY_2
或MEMORY_AND_DISK_2
),以便能够在同一源上同时运行转换。我认为这些存储级别目前仅为useful against lost partitions,因为将处理重复分区以代替丢失的分区。