scala akka wordcount程序

来源:互联网 发布:达内大数据课程怎么样 编辑:程序博客网 时间:2024/06/02 19:41

Message.scala:

package com.hupu.dace.messagessealed 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])

MasterActor:

package com.hupu.dace.actorsimport 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 _ =>  }}


MapActor:

package com.hupu.dace.actorsimport java.util.StringTokenizerimport 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)  }}

ReduceActor:

package com.hupu.dace.actorsimport 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)  }}

AggregateActor:

package com.hupu.dace.actorsimport akka.actor.Actorimport 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)  }}


HelloAkka程序入口:

package com.hupu.daceimport akka.actor.{ActorSystem, Props}import com.hupu.dace.actors.MasterActorimport 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()  }}


ReduceActor做本地聚合类似HADOOP wordcount的combiner,然后全部发送给AggregateActor做全局聚合获得最终结果。

0 0
原创粉丝点击