当前位置: 首页 > 知识库问答 >
问题:

什么时候使用Scala Futures?

松雅昶
2023-03-14

我是一名spark Scala程序员。我有一份spark工作,其中包含完成整个工作的子任务。我想使用ToFutures并行完成子任务。一旦完成整个工作,我必须返回整个工作响应。

关于scala Futures,我听说一旦主线程执行并停止,其余线程将被终止,并且您将得到空响应。

我必须使用等待。结果以收集结果。但是所有的博客都告诉你应该避免等待。结果是,这是一个糟糕的做法。

正在使用等待。在我的案例中,结果是否正确。?

def computeParallel(): Future[String] = {
  val f1 = Future {  "ss" }
  val f2 = Future { "sss" }
  val f3 = Future { "ssss" }

  for {
    r1 <- f1
    r2 <- f2
    r3 <- f3
  } yield (r1 + r2 + r3)
} 

computeParallel().map(result => ???)



根据我的理解,我们必须在Web服务中使用Futures,其中有一个进程始终在运行,不会退出。但在我的情况下,一旦逻辑执行(scala程序)完成,它就会退出。

我可以使用期货来解决我的问题吗?

提前感谢

共有1个答案

裴韬
2023-03-14

除非在特殊情况下,否则在Spark中使用期货可能是不可取的,并且简单地并行化计算不是其中之一(为阻塞I/O提供非阻塞包装器(例如向外部服务发出请求)很可能是唯一的特殊情况)。

请注意,Future不保证并行性(它们是否并行执行以及如何并行执行取决于它们运行的ExecutionContext),只是异步。此外,如果您在Spark转换中产生执行计算的未来(即在执行器上,而不是驱动程序上),很可能不会有任何性能改进,因为Spark倾向于很好地保持执行器上的内核忙碌,所有产生这些未来所做的就是与Spark争夺内核。

一般来说,在组合Spark RDD/DStreams/Dataframes、参与者和期货等并行抽象时要非常小心:有很多潜在的雷区,这些组合可能会违反各种组件中的保证和/或约定。

还值得注意的是,Spark对中间值的可串行化有要求,并且期货通常不可串行化,因此Spark阶段不会产生未来;这意味着您基本上别无选择,只能等待在某个阶段生成的期货。

如果您仍然想在Spark阶段生成期货(例如将它们发布到Web服务),最好使用Future.sequence将期货折叠成一个,然后等待(注意,我还没有测试这个想法:我假设有一个隐式的CanBuildFrom[Iterator[Future[String]], String, Future[String]]可用):

def postString(s: String): Future[Unit] = ???

def postStringRDD(rdd: RDD[String]): RDD[String] = {
  rdd.mapPartitions { strings =>
    // since this is only get used for combining the futures in the Await, it's probably OK to use the implicit global execution context here
    implicit val ectx = ???
    Await.result(strings.map(postString))
  }
  rdd  // Pass through the original RDD
}
 类似资料:
  • 问题内容: 奇怪的是: 似乎或多或少被定义为。通过这种方式很容易产生错误: 一些fname意外地以else块结尾。修复很简单,我们应该改用它,但是从表面上看,这似乎是一种不错的pythonic方式,并且比“正确”的方式更具可读性。 由于字符串是不可变的,所以为什么字符串错误是什么技术细节?什么时候进行身份检查更好,什么时候进行平等检查更好? 问题答案: 据我所知,检查对象身份是否相等。由于没有强制

  • 问题内容: 我有一个将客户发送到另一个站点来处理付款的应用程序。客户之外的另一个站点在我们的服务器上调用一个页面,让我们知道付款的状态。被调用页面会检查付款应用程序提供的参数,并检查我们是否知道该交易。然后,它更新数据库以反映状态。这一切都无需与客户进行任何互动即可完成。 我个人选择将此功能实现为JSP,因为将文件拖放到文件系统中比编译和打包文件然后将条目添加到配置文件中要容易得多。 考虑到页面的

  • 问题内容: 我怎么能说: 为什么函数调用中不需要括号,而最后一行呢? 问题答案: 是一个功能 调用该函数并产生该函数返回的任何值。 setTimeout的目的是在一段时间后运行代码。你需要的功能只是传递给它(这样的setTimeout可以自称在适当的时候函数),因为如果你将它传递给setTimeout的前调用的函数(用括号),将执行 现在 而不是1秒后,。

  • 一般来说,当发现 CPU 的占用率和实际业务应该出现的占用率不相符,或者对 Nginx worker 的资源使用率(CPU,内存,磁盘 IO )出现怀疑的情况下,都可以使用火焰图进行抓取。另外,对 CPU 占用率低、吐吞量低的情况也可以使用火焰图的方式排查程序中是否有阻塞调用导致整个架构的吞吐量低下。 常用的火焰图有三种: lj-lua-stacks.sxx 用于绘制 Lua 代码的火焰图 sam

  • 问题内容: 我习惯于进行Java编程,在编程时,您无需真正考虑指针。但是,此刻我正在用C ++编写程序。在创建具有其他类成员的类时,何时应该使用指针,何时不应该使用指针?例如,什么时候我想这样做: 与此相反: 问题答案: 首先避免指针。 在以下情况下使用它们: 您想使用Pimpl习惯用法或抽象工厂。 该实例实际上是由程序的其他部分管理的,而该类仅需要能够访问它。 您想推迟对象的构建(即,您想 在

  • 本文向大家介绍什么时候用delegate,什么时候用Notification?相关面试题,主要包含被问及什么时候用delegate,什么时候用Notification?时的应答技巧和注意事项,需要的朋友参考一下 答:delegate针对one-to-one关系,并且reciever可以返回值 给sender,notification 可以针对one-to-one/many/none,recieve

  • 问题内容: 何时使用和何时使用运算符? Java提供了两个选项来检查分配兼容性。什么时候使用? 问题答案: 我认为官方文档为您提供了答案(尽管以一种非常具体的方式): 此方法与Java语言instanceof运算符动态等效。 我认为这主要是指在运行时处理类型反射的代码中使用。特别是,我想说它的存在是为了处理您可能不事先知道要检查其成员资格的类的类型的情况(尽管这些情况可能很少)。 例如,您可以使用

  • 问题内容: 我知道他们两个都禁用了Nagle的算法。 我什么时候应该/不应该使用它们中的每一个? 问题答案: 首先,不是所有人都禁用Nagle的算法。 Nagle的算法用于减少有线中更多的小型网络数据包。该算法是:如果数据小于限制(通常是MSS),请等待直到收到先前发送的数据包的ACK,同时累积用户的数据。然后发送累积的数据。 这将对telnet等应用程序有所帮​​助。但是,在发送流数据时,等待A