我想运行一个 Spark 作业,其中每个 RDD 负责通过网络连接发送某些流量。每个 RDD 的返回值不是很重要,但我也许可以要求他们返回发送的消息数。重要的部分是网络流量,这基本上是在每个 RDD 上运行函数的副作用。
在 Spark 中执行上述任务是个好主意吗?
我正在尝试模拟来自多个来源的网络流量,以测试接收端的数据收集基础设施。我可以改为手动设置多台机器来运行发送器,但我认为如果我可以利用 Spark 现有的分布式框架会很好。
然而,Spark 似乎是为程序“计算”然后“返回”某些东西而设计的,而不是为程序运行以产生副作用。我不确定这是否是一个好主意,并希望得到其他人的意见。
需要明确的是,我正在考虑以下内容
IDs = sc.parallelize(range(0, n))
def f(x):
for i in range(0,100):
message = make_message(x, i)
SEND_OVER_NETWORK(message)
return (x, 100)
IDsOne = IDs.map(f)
counts = IDsOne.reduceByKey(add)
for (ID, count) in counts.collect():
print ("%i ran %i times" % (ID, count))
Run Code Online (Sandbox Code Playgroud)
一般来说,这是没有意义的:
Spark并发的粒度较低,以分区为主要并发单位。在这个级别上,处理变得同步。在完成当前分区之前,您无法移至下一个分区。
假设您的情况有一个 Slow SEND_OVER_NETWORK。如果您map在整个分区上使用几乎所有的块处理。您可以使用 进入较低级别mapPartitions,进行SEND_OVER_NETWORK异步,并仅在处理整个分区时返回。它更好,但仍然不是最理想的。
您可以增加分区数量,但这意味着更高的簿记开销,因此最终您可能会使情况变得更糟而不是更好。
Spark API 主要是为无副作用操作而设计的。它使得表达不适合该模型的操作变得困难。
可以说更重要的是 Spark 仅保证每个操作至少执行一次(如果 rdd 从未实现,则忽略零次)。例如,如果应用程序需要一次性语义,那么事情就会变得棘手,尤其是当您考虑第 2 点时。
可以跟踪 Spark 主逻辑之外的每个分区的本地状态,但如果您做到了这一点,则表明 Spark 不是正确的工具。
| 归档时间: |
|
| 查看次数: |
897 次 |
| 最近记录: |