模仿NameNode和DataNode之间通信

供自己查看。。。。。。。。。。。。。。。。。。。。。。。
//这是NameNode节点

package scala

import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.{Config, ConfigFactory}

import scala.collection.mutable
import scala.concurrent.duration._

/**
  * Created by Administrator on 2017/10/18.
  */
class Master(var masterHostName:String,var masterPort:Int) extends  Actor{

  private var id2workerInfo = new mutable.HashMap[String,WorkerInfo]()


  private var workerInfos = mutable.HashSet[WorkerInfo]()

  override def preStart(): Unit = {
    //启动定时扫描
    import context.dispatcher
    context.system.scheduler.schedule(0 millis ,15000 millis,self,CheckTimeOut)

  }

  override def receive: Receive = {
    case RegisterWorker(workerID,cpu,memory) =>{
      val workerInfo = new WorkerInfo(workerID,cpu,memory)


      id2workerInfo(workerID)=workerInfo
    //  id2workerInfo.put(workerID,workerInfo)
    //  id2workerInfo+=(workerID -> workerInfo)
      workerInfos += workerInfo

      sender() ! RegisteredWorker(s"${masterHostName}:${masterPort}")

    }

    case Heartbeat(workerID) => {
      val currentTime = System.currentTimeMillis()
      var workerInfo=id2workerInfo(workerID)
      //更新上一次的心跳时间
      workerInfo.lastHeartBeatTime=currentTime
      id2workerInfo(workerID)=workerInfo
      workerInfos +=workerInfo
    }
    case CheckTimeOut =>{
     val currentTime= System.currentTimeMillis()
      //true 代表这个数据我们要
      //false 代表这个数据我们不要
      val deadNode = workerInfos.filter( workerInfo => currentTime - workerInfo.lastHeartBeatTime > 15000 )
      deadNode.foreach( w =>{
        id2workerInfo -= w.workerId
        workerInfos -= w
      })



      println("当前我们注册上来的worker的个数:"+workerInfos.size)
    }
  }
}

object Master{
  val MASTER_ACTORSYSTEM="MasterActorSystem"
  val MASTER_NAME="master"

  def main(args: Array[String]): Unit = {
    val hostname=args(0)
    val port=args(1).toInt
    val str=
      s"""
        |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
        |akka.remote.netty.tcp.hostname =${hostname}
        |akka.remote.netty.tcp.port=${port}
      """.stripMargin
    val conf: Config = ConfigFactory.parseString(str)
    val actorSystem = ActorSystem(MASTER_ACTORSYSTEM,conf)
    actorSystem.actorOf(Props(new Master(hostname,port)),MASTER_NAME)
  }
}

//这是DataNode节点

package scala

import java.util.UUID

import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

import scala.concurrent.duration._

/**
  * Created by Administrator on 2017/10/18.
  */
class Worker(var masterHostname:String,var masterPort:Int ,var cpu:Int,var memory:Int) extends  Actor{
    var masterRef:ActorSelection =_
//  val name:String=_  //""
//  val age:Int=_ // 0
  var workerID:String=_
  override def preStart(): Unit = {
     //masterRef 的引用
     masterRef= context.actorSelection(s"akka.tcp://${Master.MASTER_ACTORSYSTEM}@${masterHostname}:${masterPort}/user/${Master.MASTER_NAME}")
    //val workerID:String,val cpu:Int,val memeory:Int
    workerID = UUID.randomUUID().toString
    masterRef ! RegisterWorker(workerID,cpu,memory)

  }

  override def receive: Receive = {
    case RegisteredWorker(masterURL) =>{
      /**
        * 这个地方稍微说一下:
        * 理论上来讲,我们worker注册,应该会有两个结果:
        * 1) 注册成功
        * 2)注册失败
        *
        * 接下来我们需要定时的去发送 心跳信息
        * 每隔十秒就发送一次心跳
        */
      /**
        *   initialDelay: FiniteDuration, 你的这个事多久以后开始干!!   0
            interval:     FiniteDuration,  你的这个事每隔多长时间干一次  10
            receiver:     ActorRef,   你的这个事是发送给谁的? master
            message:      Any   你到底干的是什么事?  心跳
        */
      import context.dispatcher
      context.system.scheduler.schedule(0 millis ,10000 millis,self,SendHeartBeat)

    }

    case SendHeartBeat =>{
      /**
        *
        * 好处就是这个里面可以做好多在发送心跳之前需要做的准备工作
        *、、、、、、、、、、、、、、
        * 、、、、、、、、、、、、、、
        */

       sender()
      //可以给Master发送心跳信息
      masterRef ! Heartbeat(workerID)
    }
  }
}

object Worker{
  val WORKER_ACTORSYSTEM="WorkerActorSystem"
  val WORKER_NAME="worker"

  def main(args: Array[String]): Unit = {
    //实际上下面的这些东西应该是通过解析配置文件得到的
    val hostname=args(0)
    val masterHostname=args(1)
    val masterPort=args(2).toInt
    val cpu=args(3).toInt
    val memory=args(4).toInt
    val port=args(5).toInt
    val str=
      s"""
        |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
        |akka.remote.netty.tcp.hostname = ${hostname}
        |akka.remote.netty.tcp.port=${port}
      """.stripMargin
    val conf = ConfigFactory.parseString(str)
    val actorSystem = ActorSystem(WORKER_ACTORSYSTEM,conf)
    actorSystem.actorOf(Props(new Worker(masterHostname,masterPort,cpu,memory)),WORKER_NAME)
  }
}

//这是发送信息所用的样例类

package scala

/**
  * Created by Administrator on 2017/10/19.
  */
//要发送消息的类型:
//worker -> master   worker向Master注册消息
case class RegisterWorker(val workerID:String,val cpu:Int,val memeory:Int) extends  Serializable
//master -> worker  worker注册完成消息
case class RegisteredWorker(val masterURL:String) extends Serializable
//worker -> master 发送心跳信息
case class Heartbeat(val workerID:String) extends Serializable

case object SendHeartBeat
case object CheckTimeOut

//用于封装worker

package scala

/**
  * Created by Administrator on 2017/10/19.
  */
/**
  * 用于封装worker的信息
  */
class WorkerInfo(var workerId:String,var cpu:Int,var memory:Int){
  var lastHeartBeatTime:Long=_
}
1.启动全分布模式Hadoop集群,守护进程包括NameNodeDataNode、SecondaryNameNode、ResourceManager、NodeManagerJobHistoryServer。 在Hadoop集群主节点上搭建MapReduce开发环境Eclipse。 查看Hadoop自带的MR-App单词计数源代码WordCount.java,在Eclipse项目MapReduceExample下建立新包com.mapreduce,模仿内置的WordCount示例,自己编写一个WordCount程序,最后打包成JAR形式并在Hadoop集群上运行该MR-App,查看运行结果。 分别在自编MapReduce程序WordCount运行过程中运行结束后查看MapReduce Web界面。 2. 有如下股票买卖文件,计算股票的资本损益,统计买卖的每个股票收益。(提示:将每个股票的名称作为key值,当操作为Buy时,value记为负的价格,当操作为Sell时,value记为正的价格,以这个keyvalue作为map阶段输出,reduce阶段的输入)。实验要求如下: (1)编写MapReduce代码 (2)编译并打包项目 (3)使用hadoop jar命令运行程序 (4)到控制台查看输出文件结果。 文件内容: Leetcode Buy 1000 Corona Buy 10 Leetcode Sell 9000 Handbags Buy 30000 Corona Sell 1010 Corona Buy 1000 Corona Sell 500 Corona Buy 1000 Handbags Sell 7000 Corona Sell 10000 输出结果是: Corona 9500 Handbags -23000 Leetcode 8000 3. 编程实现文件合并去重操作 对于两个输入文件,即文件A文件B,请编写MapReduce程序,对两个文件进行合并,并剔除其中重复的内容,得到一个新的输出文件C。下面是输入文件输出文件的一个样例供参考。 输入文件A的样例如下: 20170101 x 20170102 y 20170103 x 20170104 y 20170105 z 20170106 x 输入文件B的样例如下: 20170101 y 20170102 y 20170103 x 20170104 z 20170105 y 根据输入文件AB合并得到的输出文件C的样例如下: 20170101 x 20170101 y 20170102 y 20170103 x 20170104 y 20170104 z 20170105 y 20170105 z 三、实验过程与结论 记录每一步操作,要求贴出实验结果的截图。 给出我具体的操作示例,详细以及验证
最新发布
04-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值