Message.scala:
package com.hupu.dace.messages sealed case class Result() sealed case class WordCount(word: String, count: Int) sealed case class MapData(data: List[WordCount]) sealed case class ReduceData(data: List[WordCount])
package com.hupu.dace.actors import akka.actor.{Actor, Props} import com.hupu.dace.messages.Result /** * Created by xiaojun on 2015/10/12. */ class MasterActor extends Actor { val aggregateActor = context.actorOf(Props[AggregateActor], name = "agg") val reduceActor = context.actorOf(Props(classOf[ReduceActor], aggregateActor), name = "reduce") val mapActor = context.actorOf(Props(classOf[MapActor], reduceActor), name = "map") override def receive: Receive = { case msg: String => mapActor ! msg case Result() => aggregateActor ! Result() case _ => } }
package com.hupu.dace.actors import java.util.StringTokenizer import akka.actor.{Actor, ActorRef} import com.hupu.dace.messages.{MapData, WordCount} import scala.collection.mutable.ArrayBuffer /** * Created by xiaojun on 2015/10/12. */ class MapActor(reduceActor: ActorRef) extends Actor { override def receive: Receive = { case msg: String => val mapData = getMapData(msg) reduceActor ! mapData case msg => unhandled(msg) } private def getMapData(msg: String): MapData = { val list = ArrayBuffer[WordCount]() val tokenizer: StringTokenizer = new StringTokenizer(msg) while (tokenizer.hasMoreTokens) { val word: String = tokenizer.nextToken.toLowerCase list += WordCount(word, 1) } MapData(list.toList) } }
package com.hupu.dace.actors import akka.actor.{Actor, ActorRef} import com.hupu.dace.messages.{MapData, ReduceData, WordCount} /** * Created by xiaojun on 2015/10/12. */ class ReduceActor(aggregateActor: ActorRef) extends Actor { override def receive: Receive = { case MapData(data) => val list = data.groupBy(_.word).map { case (word, list) => WordCount(word, list.foldLeft(0)((count, wc) => count + wc.count)) }.toList aggregateActor ! ReduceData(list) case msg => unhandled(msg) } }
package com.hupu.dace.actors import akka.actor.Actor import com.hupu.dace.messages.{Result, ReduceData} import scala.collection.mutable /** * Created by xiaojun on 2015/10/12. */ class AggregateActor extends Actor { val finalData = mutable.HashMap[String, Int]() override def receive: Receive = { case ReduceData(data) => data.foreach(wc => { finalData.put(wc.word, finalData.getOrElse(wc.word, 0) + wc.count) }) case Result() => println(finalData) case msg => unhandled(msg) } }
package com.hupu.dace import akka.actor.{ActorSystem, Props} import com.hupu.dace.actors.MasterActor import com.hupu.dace.messages.Result /** * Created by xiaojun on 2015/10/10. */ object HelloAkka { def main(args: Array[String]) { val _system = ActorSystem("HelloAkka") val master = _system.actorOf(Props[MasterActor],"master") master ! "hello world hadoop" master ! "hello hadoop" master ! " hello spark world" Thread.sleep(1000) master ! Result() Thread.sleep(1000) _system.shutdown() } }