Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何在ApacheSpark作业中执行阻塞IO?_Scala_Parallel Processing_Apache Spark - Fatal编程技术网

Scala 如何在ApacheSpark作业中执行阻塞IO?

Scala 如何在ApacheSpark作业中执行阻塞IO?,scala,parallel-processing,apache-spark,Scala,Parallel Processing,Apache Spark,当我遍历RDD时,如果我需要通过调用外部(阻塞)服务来计算数据集中的值,该怎么办?你认为这是如何实现的 val值:Future[RDD[Double]]=未来序列任务 我试图创建一个未来列表,但由于RDD id不可遍历,Future.sequence不适合 我只是想知道,如果有人有这样的问题,你是如何解决的? 我试图实现的是在单个工作节点上实现并行性,这样我就可以每秒调用该外部服务3000次 可能还有另一种更适合spark的解决方案,比如在单个主机上有多个工作节点 很有意思的是,你如何应对这样的

当我遍历RDD时,如果我需要通过调用外部(阻塞)服务来计算数据集中的值,该怎么办?你认为这是如何实现的

val值:
Future[RDD[Double]]=未来序列任务

我试图创建一个未来列表,但由于RDD id不可遍历,Future.sequence不适合

我只是想知道,如果有人有这样的问题,你是如何解决的? 我试图实现的是在单个工作节点上实现并行性,这样我就可以每秒调用该外部服务3000次

可能还有另一种更适合spark的解决方案,比如在单个主机上有多个工作节点


很有意思的是,你如何应对这样的挑战?谢谢。

< P>根据您的答案,阻塞调用是比较RDD中的每个单独的项的输入,我强烈考虑重写java/Scala中的比较,以便它可以作为SCAPK进程的一部分运行。如果比较是一个“纯”函数(没有副作用,仅取决于其输入),那么它应该可以直接重新实现,并且由于不必进行远程调用而降低了spark进程的复杂性并提高了稳定性,这可能是值得的

您的远程服务似乎不太可能每秒处理3000个呼叫,因此最好使用本地进程内版本

如果由于某种原因这是绝对不可能的,那么您可以创建一个RDD转换,将您的数据转换为未来的RDD,使用伪代码:

val callRemote(data:Data):Future[Double] = ...

val inputData:RDD[Data] = ...

val transformed:RDD[Future[Double]] = inputData.map(callRemote)
然后从那里继续,计算你未来的[双重]目标

如果您知道远程进程可以处理多少并行性,那么最好放弃未来模式,接受它是一个瓶颈资源

val remoteParallelism:Int = 100 // some constant

val callRemoteBlocking(data:Data):Double = ...

val inputData:RDD[Data] = ...

val transformed:RDD[Double] = inputData.
  coalesce(remoteParallelism).
  map(callRemoteBlocking)
您的工作可能需要相当长的时间,但它不应该淹没您的远程服务,并可怕地死亡


最后一个选择是,如果输入是合理可预测的,结果范围是一致的,并且限制在合理数量的输出(数百万左右),您可以使用远程服务将它们作为一个数据集进行预计算,并使用连接在spark工作时间找到它们。

以下是我自己问题的答案:

val buckets = sc.textFile(logFile, 100)
val tasks: RDD[Future[Object]] = buckets map { item =>
  future {
    // call native code
  }
}

val values = tasks.mapPartitions[Object] { f: Iterator[Future[Object]] =>
  val searchFuture: Future[Iterator[Object]] = Future sequence f
  Await result (searchFuture, JOB_TIMEOUT)
}
这里的想法是,我们得到分区集合,其中每个分区都被发送给特定的工作者,并且是最小的工作。该工作的每一部分都包含数据,可以通过调用本机代码并发送该数据来处理这些数据


“values”集合包含从本机代码返回的数据,这些数据在整个集群中完成。

您需要计算哪种类型的值?是否可以脱机计算并将其连接到数据集?或者远程代码可以作为jar拉入并在进程中计算?该值是通过比较提供的输入和RDD中的每个项来计算的。所以我遍历RDD并比较每个元素。Comarison是一个阻塞调用,因为它隐藏在本机组件中。这就是为什么我想知道,如果你有这个挑战,你会怎么做?非常感谢你的帮助。我们现在面临同样的问题。你有关于如何使用任务的例子吗?谢谢,spark会自动为您的未来提供一个隐式的ExecutionContext吗?要开发@advait问题,了解spark在这种情况下是如何管理并发的将非常有趣