RDD管道每行一个外部进程

时间:2018-02-24 11:40:29

标签: scala apache-spark

我目前在独立模式下使用apache spark作为工作流系统。我的上下文是我有一个csv文件,其中每一行描述了我的模拟的一个实例的参数。

我的输入数据如下:

id,socket,type,platform,workload
00001,28001,fcfs,platform.xml,workload1.json
00002,28002,fcfs,platform.xml,workload2.json

所以我会打电话给我的模拟器

simulator --tcp-port 28001 -arg1 fcfs -arg2 platform.xml -arg3 workload.json
// Simple user-defined function to call
// sc.addFile to all file of the local folder
addFolderToContext(sc, input_folder) 
// Loading the csv from my file system
val inputsRDD = spark.read.format("csv")
   .schema(schema) 
   .option("header", "true")
   .load(input_folder + "/inputs.csv")

// Some preprocessing filtering
val simulationsFCFS = inputsRDD.filter($"type" === "fcfs")
   .collect()
   .map(r => new String(r.mkString("",",","")))
   .take(2) // Only two for testing

sc.parallelize(simulationsFCFS)
    .map(r => r)
    // Since each line is a simulation, 
    // I want to have one forked process per line 
    // .repartition(simulationsFCFS.size) // I try this, but it does not work.
    .pipe(Seq(scriptFcfs),
     Map(),
     null,
     null,
     false,
     1024, 
     Codec.defaultCharsetCodec.name) 
    .collect()

我已经能够使用RDD.pipe函数来调用我的外部 程序。但就目前而言,我被迫拥有一个循环的包装脚本 通过/ dev / stdin并为每一行调用我的包装器。这是因为管道函数将所有行从一个分区应用到我的程序的同一个子进程,而不是每个“行”。

然而,我可以实现良好的并行性,这是我的要求之一(能够并行化我的模拟),我对特定实例没有太多控制权。我想要的是在我的输入csv的每一行调用我的外部进程。好处是能够跟踪失败的模拟,因为它们将成为标准的火花任务。有人可以帮我实现吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

如果您想继续使用spark.pipe功能,为什么不在需要时为特定输入行分叉/执行单个进程。我假设您不需要为每个RDD记录单独处理,但仅针对某些记录。如果你确实需要每条记录,那么只需执行mapPartition()并在每条记录中启动自己的可执行文件。另一种笨拙的方法是继续使用RDD.pipe但重新分区,以便每个分区只有1条记录。