Akka 使用系列之四: Future

这篇文章介绍 Akka 的同步机制,以及 Spark 和 Akka 的恩怨情仇。

1 Akka 中的 Future

Akka 中的 Actor 发送和接收消息默认都是异步的。为了说明异步性,我们实行下面的数学老师和历史老师的 Actor:

class MathTeacherActor extends Actor with ActorLogging {
  def receive = {
    case "1+1等于多少?"           => {
      Thread.sleep(1)
      sender ! "1+1等于2"
    }
  }
}

class HistoryTeacherActor extends Actor with ActorLogging {
  def receive = {
    case "历史上规模最大的众筹行动是什么?" => {
      Thread.sleep(1)
      sender ! "历史上规模最大的众筹行动是 +1s"
    }
  }
}

如果我们在询问历史老师之后访问答案(如下面代码所示),我们发现并不能获取正确答案。原因就在于 Akka 是异步非阻塞的。

val res = historyteacher ? "历史上规模最大的众筹行动是什么?"
println(res)

实质上, historyteacher ? “历史上规模最大的众筹行动是什么?” 返回的根本不是答案,而是一个 Future。在Akka中, 一个Future是用来获取某个并发操作的结果的数据结构。有了 Future,我们可以以同步(阻塞)或异步(非阻塞)的方式访问结果。下面是简单地以同步(阻塞)方式访问结果的示例。

class StudentActor(mathteacher:ActorRef,historyteacher:ActorRef) 
extends Actor with ActorLogging{

  def receive = {
    case res:String => {
        val future1 = historyteacher ? "历史上规模最大的众筹行动是什么?"
        val future2 = mathteacher ? "1+1等于多少?"

        val res1    = Await.result(future1,10 second)
        val res2    = Await.result(future2,10 second)

        println(res1)
        println(res2)

    }
  }
}

2 Akka 和 Spark

Spark 一开始使用 Akka 作为内部通信部件。在 Spark 1.3 年代,为了解决大块数据(如Shuffle)的传输问题,Spark引入了Netty通信框架。到了 Spark 1.6, Spark 可以配置使用 Akka 或者 Netty 了,这意味着 Netty 可以完全替代 Akka 了。再到 Spark 2, Spark 已经完全抛弃 Akka 了,全部使用 Netty 了。Sad。

为什么 Spark 无情地有步骤有预谋地抛弃 Akka 呢?Spark 官方倒是给了一个说法:https://issues.apache.org/jira/browse/SPARK-5293

A lot of Spark user applications are using (or want to use) Akka. Akka as a whole can contribute great architectural simplicity and uniformity. However, because Spark depends on Akka, it is not possible for users to rely on different versions, and we have received many requests in the past asking for help about this specific issue. For example, Spark Streaming might be used as the receiver of Akka messages – but our dependency on Akka requires the upstream Akka actors to also use the identical version of Akka. Since our usage of Akka is limited (mainly for RPC and single-threaded event loop), we can replace it with alternative RPC implementations and a common event loop in Spark.

大意就是很多 Spark 用户在使用 Spark 之后,就必须使用 Spark 依赖的那个版本的 Akka。Spark 主要用了 Akka 的 RPC 和 单线程 event-loop,因此 Spark 没有必要依赖完全的 Akka。最终 Spark 用 netty 实现下简易版本的 Akka。真爱啊。

3 总结

到这里,Akka 使用系列就结束了。这个系列简单地过了一下 Akka 的基础知识,介绍其梗概。如果需要深入了解,还需要详细阅读官方文档。完整代码已经上传至 Github

最近在 GitHub 上开发了一个 Side Project – RoomAI。这个 Side Project 目标是提供一些非完整信息游戏环境,让算法人员开发非完整信息游戏 AI, 目前已经支持德州和梭哈。欢迎大家使用和反馈。我后续会基于这个项目写一些文章介绍非完整信息游戏的算法。

Akka 系列系列文章

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张高兴的博客

张高兴的 Windows 10 IoT 开发笔记:FM 电台模块 KT0803L

3446
来自专栏叁金大数据

EmguCV学习——视频与图片互转

其实视频转图片在上篇文章中已经有些眉目了,其实就是按帧读取视频,然后把帧保存就ok。然后自己再加个进度条美化一下。。。这代码简单易懂,还是直接上代码吧。

751
来自专栏光变

Maven运行sonar出错

Maven运行sonar报错 Unable to determine structure of project. Probably you use Maven ...

702
来自专栏腾讯数据中心

敬请收藏:数据中心常用标识的中英文对照

中国的数据中心在不断走向国际化,同时数据中心内的关键标识也逐渐采取了中英文双语标识。 今天,我们整理出腾讯数据中心内部使用的中英文标识对照。敬请收藏以备后续参考...

3164
来自专栏吴小龙同學

Android 进程间通信

什么鬼!单例居然失效了,一个地方设置值,另个地方居然取不到,这怎么可能?没道理啊!排查半天,发现这两就不在一个进程里,才恍然大悟…… 什么是进程 按照操作...

2394
来自专栏IT笔记

SpringBoot开发案例之整合mail队列进阶篇

前情提要 上一篇文章,我们为了解决实际场景中遇到的问题,使得其更像一个安全高效的邮件服务平台,我们引入了LinkedBlockingQueue队列对邮件发送进行...

2755
来自专栏哈雷彗星撞地球

RunLoop总结:RunLoop的应用场景(四)App卡顿监测

今天要介绍的RunLoop使用场景很有意思,在做长期项目,需要跟踪解决用户问题非常有用。 使用RunLoop 监测主线程的卡顿,并将卡顿时的线程堆栈信息保存下...

682
来自专栏安富莱嵌入式技术分享

【二代示波器教程】第12章 示波器设计—DAC信号发生器的实现

本章节为大家讲解二代示波器中信号发生器的实现。这个功能还是比较实用的,方便为二代示波器提供测试信号。实现了正弦波,方波和三角波的频率,幅度以及占空比设置。

612
来自专栏跟着阿笨一起玩NET

LINQ to XML 从逗号分隔值 (CSV) 文件生成 XML 文件

参考:http://msdn.microsoft.com/zh-cn/library/bb387090.aspx

441
来自专栏HansBug's Lab

1615: [Usaco2008 Mar]The Loathesome Hay Baler麻烦的干草打包机

1615: [Usaco2008 Mar]The Loathesome Hay Baler麻烦的干草打包机 Time Limit: 5 Sec  Memory ...

32211

扫码关注云+社区