Akka实现WordCount(Scala):

架构图:

项目结构:

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.citi.sky</groupId>
<artifactId>AkkaPJ</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>AkkaPJ</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.6</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-compiler</artifactId>
<version>2.11.6</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-reflect</artifactId>
<version>2.11.6</version>
</dependency> <dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId>
<version>2.3.3</version> </dependency> <dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-testkit_2.11</artifactId>
<version>2.3.6</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.11</artifactId>
<version>3.0.4</version>
<scope>test</scope>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.15.2</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </project>

消息:

case class MapData (dataList: List[WordCount])

case class ReduceData (reduceDataList: Map[String, Int])

case class Result()

case class WordCount (key: String, count: Int)

Actors:

MasterActor

import akka.actor.Actor
import akka.actor.Props
import com.citi.dw.messages.Result class MasterActor extends Actor { private val aggregateActor = context.actorOf(Props(classOf[AggregateActor]), "aggregateActor")
private val reduceActor = context.actorOf(Props(classOf[ReduceActor], aggregateActor), "reduceActor")
private val mapActor = context.actorOf(Props(classOf[MapActor], reduceActor), "mapActor") def receive: Actor.Receive = {
case msg: String => {
mapActor ! msg
}
case msg: Result => {
aggregateActor.forward(msg)
}
// case msg: Map[String, Int] =>
case _ => println("MasterActor receive wrong message.")
}
}

MapActor:

import akka.actor.Actor
import com.citi.dw.messages.MapData
import com.citi.dw.messages.WordCount
import scala.collection.mutable.ListBuffer
import akka.actor.ActorRef class MapActor(val reduceActor: ActorRef) extends Actor {
def receive: Actor.Receive = {
case msg: String => {
val mapData = evaluateExpression(msg)
reduceActor ! mapData
}
case _ => println("MapActor receive wrong message.")
} private[this] def evaluateExpression(line: String): MapData = {
val dataList = ListBuffer[WordCount]()
line.split(" ").map(word => dataList += WordCount(word, 1)) // val wordArr = line.split(" ")
// for(word <- wordArr) {
// dataList += WordCount(word, 1)
// }
// println(dataList)
MapData(dataList.toList)
} }

ReduceActor:

import akka.actor.Actor
import com.citi.dw.messages.MapData
import com.citi.dw.messages.ReduceData
import com.citi.dw.messages.WordCount
import scala.collection.mutable.HashMap
import akka.actor.ActorRef class ReduceActor(val aggregateActor: ActorRef) extends Actor { def receive: Actor.Receive = {
case msg: MapData => {
val reduceData = reduce(msg.dataList)
aggregateActor ! reduceData
}
case _ => println("ReduceActor receive wrong message.")
} private[this] def reduce(dataList: List[WordCount]): ReduceData = {
val reduceMap = HashMap[String, Int]() for (wc <- dataList) {
wc match {
case WordCount(key, count) if reduceMap.contains(key) => {
val localSumCount = reduceMap.get(key).get + count
reduceMap += ((key, localSumCount))
// println(reduceMap)
}
case WordCount(key, count) => {
reduceMap += ((key, 1))
// println(reduceMap)
}
} } ReduceData(reduceMap.toMap)
} }

AggregateActor:

import akka.actor.Actor
import com.citi.dw.messages.ReduceData
import scala.collection.mutable.HashMap
import com.citi.dw.messages.Result
import akka.actor.ActorRef class AggregateActor extends Actor { private[this] var finalReduceMap = HashMap[String, Int]() def receive: Actor.Receive = {
case msg: ReduceData => {
aggregateAndReduce(msg.reduceDataList)
}
case msg: Result => {
// println(f"Result: ${finalReduceMap}")
// sender().tell(finalReduceMap.toMap, ActorRef.noSender)
sender ! finalReduceMap.toMap
}
case _ => println("AggregateActor receive wrong message.")
} private[this] def aggregateAndReduce(reduceList: Map[String, Int]) = {
// println(s"final: ${finalReduceMap}")
for (key <- reduceList.keys) {
if (finalReduceMap.contains(key)) { val count = finalReduceMap.get(key).get + reduceList.get(key).get
finalReduceMap += ((key, count))
} else {
finalReduceMap += ((key, reduceList.get(key).get))
}
} } }

主程序:

import akka.actor.ActorSystem
import akka.actor.Props
import com.citi.dw.actors.MasterActor
import com.citi.dw.messages.Result
import akka.pattern.ask
import scala.concurrent.duration._
import akka.util.Timeout
import scala.util._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await object AkkaWordCount extends App { implicit val timeout = Timeout(5 seconds)
val system = ActorSystem("WordCountAkka")
val master = system.actorOf(Props(classOf[MasterActor]), "master") master ! "Hi! Hi!"
master ! ("My name is Sky. I am so so so happy to be here ")
master ! ("Today, I am going to introduce word count for Akka ")
master ! ("I hope hope It is helpful to you ")
master ! ("Thank you ") Thread.sleep(1000) val future = master ? Result()
// future.onComplete({
// case Success(x: String) => println(x)
// case Failure(t) => println(t)
// case msg => println("unknown message! " + msg)
// }) val result = Await.result(future, timeout.duration).asInstanceOf[Map[String, Int]]
result.map(m => println(m._1, m._2)) system.shutdown() }

运行结果:

(for,1)
(name,1)
(count,1)
(is,2)
(am,2)
(My,1)
(going,1)
(so,3)
(introduce,1)
(Sky.,1)
(I,3)
(to,3)
(Hi!,2)
(you,2)
(here,1)
(happy,1)
(Thank,1)
(hope,2)
(Today,,1)
(helpful,1)
(Akka,1)
(It,1)
(be,1)
(word,1)

 

Akka实现WordCount(Scala)的更多相关文章

  1. Akka(一) - akka的wordcount

    1. 启动类 object Application extends App{ val _system = ActorSystem("HelloAkka") //构建akka容器 v ...

  2. Spark:用Scala和Java实现WordCount

    http://www.cnblogs.com/byrhuangqiang/p/4017725.html 为了在IDEA中编写scala,今天安装配置学习了IDEA集成开发环境.IDEA确实很优秀,学会 ...

  3. 编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本]

    编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本] 1. 开发环境 Jdk 1.7.0_72 Maven 3.2.1 Scala 2.10.6 Spark 1.6 ...

  4. Scala IDE for Eclipse的下载、安装和WordCount的初步使用(本地模式和集群模式)

    包括: Scala IDE for Eclipse的下载  Scala IDE for Eclipse的安装 本地模式或集群模式 我们知道,对于开发而言,IDE是有很多个选择的版本.如我们大部分人经常 ...

  5. IDEA15 下运行Scala遇到问题以及解决办法

    为了让Scala运行起来还是很麻烦,为了大家方便,还是记录下来: 1.首先我下载的是IDEA的社区版本,版本号为15. 2.下载安装scala插件: 2.1 进入设置菜单. 2.2 点击安装JetBr ...

  6. 在IDEA中编写Spark的WordCount程序

    1:spark shell仅在测试和验证我们的程序时使用的较多,在生产环境中,通常会在IDE中编制程序,然后打成jar包,然后提交到集群,最常用的是创建一个Maven项目,利用Maven来管理jar包 ...

  7. Win7上Spark WordCount运行过程及异常

    WordCount.Scala代码如下: package com.husor.Spark /** * Created by huxiu on 2014/11/26. */ import org.apa ...

  8. Akka初步介绍

    Akka可能很多人都没有用过,也不知道是什么,但如果说起Scala或Spark就有很多人都听说过或使用过 ,这里简单说下三者的关系Akka是使用Scala开发的,Spark中使用了Akka作为其消息的 ...

  9. IntelliJ IDEA的下载、安装和WordCount的初步使用(本地模式和集群模式)

    包括: IntelliJ IDEA的下载  IntelliJ IDEA的安装 IntelliJ IDEA中的scala插件安装 用SBT方式来创建工程 或 选择Scala方式来创建工程 本地模式或集群 ...

随机推荐

  1. P2774 方格取数问题 网络最大流 割

    P2774 方格取数问题:https://www.luogu.org/problemnew/show/P2774 题意: 给定一个矩阵,取出不相邻的数字,使得数字的和最大. 思路: 可以把方格分成两个 ...

  2. Treap + 无旋转Treap 学习笔记

    普通的Treap模板 今天自己实现成功 /* * @Author: chenkexing * @Date: 2019-08-02 20:30:39 * @Last Modified by: chenk ...

  3. 数论 线性同余方程的应用 poj2891

    Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 17321 ...

  4. JSP标签介绍

    JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. jsp的常用标签有以下三个 <j ...

  5. [1]尝试用Unity3d制作一个王者荣耀(持续更新)->AssetBundle管理器

    如果已经看过本章节:目录传送门:这是目录鸭~ 1.AssetBundleManager: 首先我们创建一个文件夹,叫AssetBundleManager,再创建Csharp(即C#)脚本,名为Asse ...

  6. 【深入浅出-JVM】(76):classloader

    方法 public Class<?> loadClass(String name) throws ClassNotFoundException 通过类名发挥这个类的Class实例 prot ...

  7. java.lang.UnsupportedClassVersionError:JDK版本不一致报错

    交代一下背景:公司运行的一个上线项目,打了个补丁发给客户后,反馈说运行不了.把源码拿回来场景重现.贴上报错信息: 08-15 14:13:29 ERROR doPost(jcm.framework.r ...

  8. 创建多线程之threading.Thread的使用

    1.threading模块 threading模块是众多多线程管理模块的其一,它能确保重要的子线程退出后进程才退出. multiprocess模块的完全模仿了threading模块的接口,二者在使用层 ...

  9. 并发编程之线程创建到销毁、常用API

    在前面一篇介绍了线程的生命周期[并发编程之多线程概念],在本篇将正式介绍如何创建.中断线程,以及线程是如何销毁的.最后,我们会讲解一些常见的线程API. 线程创建 Java 5 以前,实现线程有两种方 ...

  10. 正则表达式(RegExp)

    前言:先来了解一下基础知识.再细说正则表达式~ 转义字符  ----   \ 转义字符会将与之相邻的字符转换含义. 例如说,希望在一个字符串中输出 “ 号,那么就可以使用在双引号前加入 \ ,这样就能 ...