Hadoop服务库与事件库的使用及其工作流程

 

Hadoop服务库:

YARN采用了基于服务的对象管理模型,主要特点有:

  • 被服务化的对象分4个状态:NOTINITED,INITED,STARTED,STOPED
  • 任何服务状态变化都可以触发另外一些动作
  • 可通过组合方式对任意服务进行组合,统一管理

具体类请参见 org.apache.hadoop.service包下.核心接口是Service,抽象实现是AbstractService

    YARN中,ResourceManager和NodeManager属于组合服务,内部包含多个单一和组合服务.以实现对内部多种服务的统一管理.

 

Hadoop事件库:

YARN采用事件驱动并发模型, 把各种逻辑抽象成事件,进入事件队列,然后由中央异步调度器负责传递给相应的事件调度器处理,或者调度器之间再传递,直至完成任务.

具体参见org.apache.hadoop.yarn.event.主要类和接口是:Event, AsyncDispatcher,EventHandler

 

 

按照惯例, 先给出一个Demo,然后顺着Demo研究代码实现.

示例我是直接抄<hadoop技术内幕>:

例子涉及如下几个模块:

  1. Task

  2. TaskType

  3. Job

  4. JobType

  5. Dispatcher

package
com.demo1;

 

import org.apache.hadoop.conf.Configuration;

import
org.apache.hadoop.service.CompositeService;

import
org.apache.hadoop.service.Service;

import
org.apache.hadoop.yarn.event.AsyncDispatcher;

import
org.apache.hadoop.yarn.event.Dispatcher;

import
org.apache.hadoop.yarn.event.EventHandler;

 

/**

* Created by yang on 2014/8/25.

*/

public
class
SimpleService
extends
CompositeService {

 

private
Dispatcher
dispatcher;

private String jobID;

private
int
taskNum;

private String[] taskIDs;

 

public SimpleService(String name, String jobID, int
taskNum) {

super(name);

this.jobID = jobID;

this.taskNum = taskNum;

this.taskIDs = new String[taskNum];

 

for (int
i = 0; i < taskNum; i++) {

taskIDs[i] = new String(jobID + "_task_" + i);

}

}

 

public
Dispatcher getDispatcher() {

return
dispatcher;

}

 

public
void serviceInit(Configuration conf) throws Exception {

dispatcher = new
AsyncDispatcher();

dispatcher.register(JobEventType.class, new JobEventDIspatcher());

dispatcher.register(TaskEventType.class, new TaskEventDIspatcher());

addService((Service)dispatcher);

super.serviceInit(conf);

}

 

private
class JobEventDIspatcher implements
EventHandler<JobEvent> {

 

@Override

public
void handle(JobEvent
jobEvent) {

if (jobEvent.getType() == JobEventType.JOB_KILL) {

System.out.println("JOB KILL EVENT");

for (int
i = 0; i < taskNum; i++) {

dispatcher.getEventHandler().handle(new
TaskEvent(taskIDs[i], TaskEventType.T_KILL));

}

} else
if (jobEvent.getType() == JobEventType.JOB_INIT) {

System.out.println("JOB INIT EVENT");

for (int
i = 0; i < taskNum; i++) {

dispatcher.getEventHandler().handle(new
TaskEvent(taskIDs[i], TaskEventType.T_SCHEDULE));

}

}

}

}

 

private
class TaskEventDIspatcher implements
EventHandler<TaskEvent> {

 

@Override

public
void handle(TaskEvent
taskEvent) {

if (taskEvent.getType() == TaskEventType.T_KILL) {

System.out.println("TASK KILL EVENT" + taskEvent.getTaskID());

} else
if (taskEvent.getType() == TaskEventType.T_SCHEDULE) {

System.out.println("TASK INIT EVENT" + taskEvent.getTaskID());

}

}

}

}

 

  1. 测试程序

package
com.demo1;

 

import org.apache.hadoop.conf.Configuration;

import
org.apache.hadoop.yarn.conf.YarnConfiguration;

 

/**

* Created by yang on 2014/8/25.

*/

public
class
Test {

public
static
void main(String[] args) throws Exception {

String jobID="job_1";

SimpleService
ss = new
SimpleService("test",jobID,5);

YarnConfiguration
config = new
YarnConfiguration(new Configuration());

 

ss.serviceInit(config);

ss.init(config);

ss.start();

 

ss.getDispatcher().getEventHandler().handle(new
JobEvent(jobID,JobEventType.JOB_KILL));

ss.getDispatcher().getEventHandler().handle(new
JobEvent(jobID,JobEventType.JOB_KILL));

}

}

 

 

不出意外的话,运行结果应该类似:

14/08/25 16:02:20 INFO event.AsyncDispatcher: Registering class com.yws.demo1.JobEventType for class com.yws.demo1.SimpleService$JobEventDIspatcher

14/08/25 16:02:42 INFO event.AsyncDispatcher: Registering class com.yws.demo1.TaskEventType for class com.yws.demo1.SimpleService$TaskEventDIspatcher

14/08/25 16:02:54 INFO event.AsyncDispatcher: Registering class com.yws.demo1.JobEventType for class com.yws.demo1.SimpleService$JobEventDIspatcher

14/08/25 16:03:03 INFO event.AsyncDispatcher: Registering class com.yws.demo1.TaskEventType for class com.yws.demo1.SimpleService$TaskEventDIspatcher

JOB KILL EVENT

JOB KILL EVENT

TASK KILL EVENTjob_1_task_0

TASK KILL EVENTjob_1_task_1

TASK KILL EVENTjob_1_task_2

TASK KILL EVENTjob_1_task_3

TASK KILL EVENTjob_1_task_4

TASK KILL EVENTjob_1_task_0

TASK KILL EVENTjob_1_task_1

TASK KILL EVENTjob_1_task_2

TASK KILL EVENTjob_1_task_3

TASK KILL EVENTjob_1_task_4

 

 

我们开始分析:

所谓的Task,Job,其实是按业务逻辑划分的, 他们都继承AbstractEvent类.

SimpleService是一个组合服务,里面放了EventHandler和Dispatcher

 

从Test开始,看看Service是如何创建的

构造函数比较简单,就是将一个job拆分成taskNum个Task

ss.serviceInit(config);做了什么呢:

创建一个中央事件调度器: AsyncDispatcher(具体实现我们在后文分析)

并把Job和Task的Event及2者对应的EventHandler注册到调度器中.

这里就是初始化和启动服务了.最后2行就是模拟2个事件的JOB_KILL事件.

 

我们进到ss.getDispatcher().getEventHandler(),发现他其实是创建一个GenericEventHandler

 

这个handler干什么是呢?

就是把

塞到BlockingQueue<Event> eventQueue; 中.

不知道你发现没有, 这个方法仅仅是一个入队操作啊. 那具体调用JobEventDIspatcher.handler是在什么地方呢?

这时联想到之前不是有个中央调度器嘛, AsyncDispatcher, Line 80行, 他创建了一个线程,并不断的从之前说的EventQueue中不断的取Event,然后执行,这里的执行也就是调用了具体的handler了

就这样一个基于事件驱动的程序这么完成了.

 

按照hadoop 早起版本中, 业务逻辑之间是通过函数调用方式实现的,也就是串行的. 现在基于事件驱动后,大大提高了并发性.很值得我们学习.

 

来张全家福:

 

HandlerThread就是前文说的那个隐藏线程. EventHandler会产生一些新的Event,然后又重新进入队列.循环.

Hadoop服务库与事件库的使用及其工作流程的更多相关文章

  1. Hadoop2源码分析-YARN 的服务库和事件库

    1.概述 在<Hadoop2源码分析-YARN RPC 示例介绍>一文当中,给大家介绍了YARN 的 RPC 机制,以及相关代码的演示,今天我们继续去学习 YARN 的服务库和事件库,分享 ...

  2. 【深入浅出 Yarn 架构与实现】2-3 Yarn 基础库 - 服务库与事件库

    一个庞大的分布式系统,各个组件间是如何协调工作的?组件是如何解耦的?线程运行如何更高效,减少阻塞带来的低效问题?本节将对 Yarn 的服务库和事件库进行介绍,看看 Yarn 是如何解决这些问题的. 一 ...

  3. Yarn的服务库和事件库使用方法

    事件类型定义: package org.apache.hadoop.event; public enum JobEventType { JOB_KILL, JOB_INIT, JOB_START } ...

  4. 服务容错保护断路器Hystrix之二:Hystrix工作流程解析

    一.总运行流程 当你发出请求后,hystrix是这么运行的 红圈 :Hystrix 命令执行失败,执行回退逻辑.也就是大家经常在文章中看到的“服务降级”. 绿圈 :四种情况会触发失败回退逻辑( fal ...

  5. Yarn的服务库和事件库

    对于生命周期较长的对象,YARN采用了基于服务对象管理模型对其进行管理. 该模型有一下特点: 每个被服务化的对象都分为4个状态 任何服务状态变化都可以触发另外一些动作 可以通过组合方式对任意服务进行组 ...

  6. 【深入浅出 Yarn 架构与实现】2-2 Yarn 基础库 - 底层通信库 RPC

    RPC(Remote Procedure Call) 是 Hadoop 服务通信的关键库,支撑上层分布式环境下复杂的进程间(Inter-Process Communication, IPC)通信逻辑, ...

  7. 利用epoll写一个"迷你"的网络事件库

    epoll是linux下高性能的IO复用技术,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取 ...

  8. libevent库介绍--事件和数据缓冲

    首先在学习libevent库的使用前,我们还要从基本的了解开始,已经熟悉了epoll以及reactor,然后从event_base学习,依次学习事件event.数据缓冲Bufferevent和数据封装 ...

  9. ktouch移动端事件库

    最近闲来无事,写了个移动端的事件库,代码贴在下面,大家勿拍. /** @version 1.0.0 @author gangli @deprecated 移动端触摸事件库 */ (function ( ...

随机推荐

  1. linux系统,服务器与服务器拷贝文件

    服务器与服务器拷贝文件命令 scp -P (服务器端口)-r 拷贝文件名称列表    远程服务器用户@远程服务器ip :(文件放置目录) 1.将本地home目录下的apache-tomcat-8.0. ...

  2. select2插件设置选中值并显示的问题

    在select2中,要想设置指定值为选中状态并显示: $("#select2_Id").val("XXXXX").select2() 或者 var obj= $ ...

  3. 22. Generate Parentheses产生所有匹配括号的方案

    [抄题]: Given n pairs of parentheses, write a function to generate all combinations of well-formed par ...

  4. 48-Python 安装pyautogui失败解决办法

    转载自:https://www.cnblogs.com/SH170706/p/9809830.html Python 安装pyautogui 在Python中使用PyAutoGui模拟键盘和鼠标操作 ...

  5. mysql sql_mode=only_full_group_by错误解析

    实测,解决问题; 1.错误提示: 2.检查参数设置: 3.mysql的配置文件my.cnf里面可以修改, 但是,改完以后,你检查所有的参数设置都是对的,就是运行不了.怎么办?怎么办? 4.如果还是不行 ...

  6. python 安装第三方包时 read timed out

    记录下安装python第三方包超时报错,解决方法:(以安装numpy为例) pip install numpy 报错:raise ReadTimeoutError(self._pool, None, ...

  7. Linux 第四天

    1.文件搜索命令 1)locate 在文件资料库中查找文件(需要文件资料库中有,新建的文件查不到,需要手动更新,updatedb.查不到/tmp目录下的文件) 语法:locate 文件名 常用选项: ...

  8. springboot 使用maven 打包 报 (请使用 -source 7 或更高版本以启用 diamond 运算符) 错误解决办法

    在使用springboot maven 打包时 报如下错误 (请使用 -source 7 或更高版本以启用 diamond 运算符) pom.xml编译插件 配置如下: <plugin> ...

  9. 《Pro git》

    可以通过阅读 CODING 工程师参与翻译的 <Pro Git> 进一步掌握 Git 版本控制系统. https://git-scm.com/book/zh/v2

  10. 关于SQL\SQL Server的三值逻辑

    在SQL刚入门的时候,我们筛选为某列值为NULL的行,一般会采用如下的方式: SELECT * FROM Table AS T WHERE T.Col=NULL 而实际上此种写法无法得到想要的结果.此 ...