03-类加载器

类加载器

    

    类加载定义:通过一个类的全限定名来获取描述此类的二进制流来获取所需要的类的动作
        
    类从被加载到虚拟机内存中开始,到卸载出内存生命周期分为以下7个阶段
        加载(Loading) -> 【验证(Verification) -> 准备(Preparation) -> 解析(Resolution)】 -> 初始化(Initialization) -> 使用(Using) -> 卸载(Unloading)
        验证、准备和解析统称为连接(Linking)
    
    主动引用(会触发类初始化的引用):
        1.遇到new,getstatic,putstatic或invokestatic这4条指令时,若类没有初始化会被触发初始化(new对象时、读取或者设置类静态非常量字段时、调用类静态方法)
        2.反射调用类时
        3.初始化类,其父类还未被初始化时触发父类初始化
        4.虚拟机启动时,用户需要指定一个要执行的主类(包含main方法的那个类),虚拟机会先初始化这个类

    被动引用(不会触发类初始化的引用):
        1.通过子类引用父类的静态字段
        2.通过定义数组来引用类
        3.在A类中用到了B类的静态常量,这里B类不会被初始化。常量在编译阶段会存到调用类的常量池中,本质上没有直接调用定义常量的类
        
    双亲委派模型:
        1.虚拟机的角度看类加载器种类:

             
  a.启动类加载器(Bootstrap ClassLoader),用C++实现。
             
  b.所有的其他类加载器,都由Java实现。并且都继承于java.lang.ClassLoader类

        2.开发人员的角度看类加载器种类:
             
  a.启动类加载器(Bootstrap ClassLoader):负责加载/lib目录下。(按照文件名识别)

             
  b.扩展类加载器(Extension ClassLoader):这个类加载器由sun.misc.Launcher$ExtClassLoader实现,它负责加载/lib/ext目录中的,或者被java.ext.dirs系统变量所指定的路径中所有的类库

             
  c.应用程序类加载器(Application ClassLoader):这个类加载器由sun.misc.Launcher$AppClassLoader实现,由于ClassLoader的getSystemClassLoader方法返回值也是它,所以一般它也被称为系统加载器。


        工作过程:
            如果一个类收到了类加载的请求,它首先不会自己去尝试去加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此。
    因此所有的类加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。
    
       双亲委派模型带来的好处:
            1.[稳定性]同一个类始终会给同一个类加载器去加载,例如java.lang.Object在rt.jar中。那么在各种类加载器环境中都会是委派给启动类加载器,所以系统中也只会有一个Objec类
    

         ClassLoader实现双亲委派模型源码:

/**
*使用指定的二进制名称来加载类。此方法的默认实现将按以下顺序搜索类: 
1.调用 findLoadedClass(String) 来检查是否已经加载类。
2.在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。 
3.调用 findClass(String) 方法查找类。
如果使用上述步骤找到类,并且 resolve 标志为真,则此方法将在得到的 Class 对象上调用 resolveClass(Class) 方法。 
鼓励用 ClassLoader 的子类重写 findClass(String),而不是使用此方法,ClassLoader的findClass方法默认是抛出ClassNotFoundException

**/ 
protected Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);
                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

版权声明:本文为博主原创文章,未经博主允许不得转载。

02-Reference & GC

一、引用

    Java中引用的定义很传统:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表着一个引用。这个定义很纯粹,但是太过狭隘,一个对象在这种定义下只有被引用或者没有被引用两种状态,对于如何描述一些“食之无味弃之可惜”的对象就显得无能为力。我们希望能描述这样一类对象:当内存空间还足够时,则能保存在内存中;如果内存在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都符合这样的应用场景。
    在JDK1.2之后,Java对引用的概念进行了扩充,将引用分为:
        以下四种引用强度依次逐渐减弱
        1.强引用(Strong Reference)
            强引用就是指在程序代码中普遍存在的,类似“Object obj = new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。

        2.软引用(Soft Reference)
            软引用用来描述一些还有用,但并非必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,会把这些对象列进回收范围之中并进行第二次回收。如果这次回收还是没有足够的内存,才会抛出内存溢出异常。在JDK1.2之后,提供了SoftReference类来实现软引用。

        3.弱引用(Weak Reference)
            弱引用也是用来描述非必须对象的,但是它的强度比弱引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集器发生之前。当垃圾收集器工作时,无论当前的内存是否足够,都会回收掉只被弱引用关联的对象。在JDK1.2之后,提供了WeakReference类来实现弱引用。

        4.虚引用(Phantom Reference)
            虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是希望能在这个对象被收集器回收时收到一个系统通知。在JDK1.2之后,提供了PhantomReference来实现虚引用。

二、判断对象已死算法
    1.引用计数算法(Reference Counting)
        定义:给对象中添加一个引用计数器,每当有个地方引用它时,计算器值就加一;当引用失效时,计数器值就减1;任何时候计算器都为0的对象就是不可能再被使用的。
        客观地说,引用计数算法的实现简单,判定效率也很高,在大部分情况下它都是一个不错的算法,但是Java中没有选用它来管理内存,其中最主要的原因是它很难解决对象之间的相互循环引用的问题

    2.根搜索算法(GC Roots Tracing)
        基本思路:通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始往下搜索,搜索走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。
        在Java语言里,可作为GC Roots的对象包括以下几种:
        1.虚拟机栈(栈帧中的本地变量表)中引用的对象。
        2.方法区中的类静态属性引用的对象。
        3.方法区中的常量引用的对象。
        4.本地方法栈JNI(即一般说的Native方法)的引用的对象。

三、对象死亡的两次标记过程
    在根搜索算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经过两次标记过程:如果对象在进行根搜索后发现没有与GC Roots相连接的引用链,那它会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize方法或者finalize已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。
    经过上面的判定如果有必要执行finalize方法,那么这个对象将会被放置在一个名为F-Queue的队列之中,并在稍后由一条虚拟机自动建立的、低优先级的Finalizer线程去执行。这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束。这样做的原因是,如果一个对象在finalize方法中执行缓慢,或者发生了死循环(更极端的情况),将很可能会导致F-Queue队列中的其他对象永久处于等待状态,甚至导致整个内存回收系统崩溃。finalize方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize中拯救自己–只要重新与引用链上的任何一个对象建立关联即可,譬如把自己(this关键字)赋值给某个类的变量或对象的成员变量,那在第二次标记时它将被移除出“即将回收”的集合;如果对象这时候还没有逃脱,那它就真的离死不远了。

代码测试如下:

package com.billstudy.jvm;

/**
 * Created by Bill on 2015-07-16 16:11
 * 测试GC自救,finalize只会被调用一次
 * Email: LuckyBigBill@gmail.com
 */
public class FinalizeEscapeGC {

    public static FinalizeEscapeGC SAVE_HOOK = null;

    public void isAlive(){
        System.out.println("yes, i am still alive :)");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed!");
        SAVE_HOOK = this;
    }

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

        SAVE_HOOK = new FinalizeEscapeGC();

        // 对象第一次拯救自己
        SAVE_HOOK = null;
        System.gc();
        // Finalizer方法优先级低,暂停等会儿它
        Thread.sleep(500);
        if (SAVE_HOOK != null){
            SAVE_HOOK.isAlive();
        }else{
            System.out.println("no, i am dead :(");
        }

        // 和上面代码相同,这次自救失败了
        SAVE_HOOK = null;
        System.gc();

        Thread.sleep(500);
        if (SAVE_HOOK != null){
            SAVE_HOOK.isAlive();
        }else{
            System.out.println("no, i am dead :(");
        }



    }
}

四、垃圾回收算法
    1.标记-清除算法
        该算法分为”标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象.
         主要缺点:
               
1.效率问题,标记和清除过程的效率都不高

             
  2.空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

         回收示意图:
            
    2.复制算法
        为了解决效率问题,一种称为“复制”(Copying)的收集算法出现了,它将可用内存按容量划分为大小相等的两快,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上,然后再把已使用过的内存空间一次清理掉。这样使得每次都是要对其中的一块进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可。实现简单,运行高效。只是这种算法的代价是将内存缩小为原来的一半,未免太高了一点
        
    3.标记-整理算法
        复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活极端情况,所以老年代一般不能直接选用这种算法。
        根据老年代的特点,有人提出了另外一种”标记-整理”(Mark-Compact)算法,标记过程仍然与“标记-清除一样”,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都想一端移动,然后直接清理掉端边界以外的内存,示意图如下:
          


    4.分代收集算法
        当前商业虚拟机的垃圾收集都采用”分代收集”(Generational Collection)算法,这种算法并没有什么新的思想,只是根据对象的存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活。那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用”标记-清理”或“标记-整理”算法来进行回收
        



版权声明:本文为博主原创文章,未经博主允许不得转载。

01-Jvm 内存区域复习笔记

Java内存区域
    
    1.程序计数器(Program Counter Register)
        在虚拟机中一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。 在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成
        由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有个独立的程序计数器,各条线程之间的计数器互不影响,独立存储。我们称这类内存区域为”线程私有”的内存
    如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行虚拟机字节码指令的地址;如果正在执行的Native方法,这个计算器值则为空(Undefined),此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

    2.Java虚拟机栈(Java Virtual Machine Stacks)    
        与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中充入栈到出栈的过程
        平常大家说堆(Heap)栈(Stack),这种划分比较粗糙。所说的“栈”指的就是虚拟机栈,或者说是虚拟机栈中的局部变量表部分。局部变量表存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(Reference类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个执行对象起始地址的引用指针,也可能是执行一个代表对象的句柄或其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。
    64位长度的Long和Double类型的数据会占用2个局部变量空间(Slot),其他的数据类型只占用1个。局部变量表所需的内存空间在编译期间完成分配,也就是一个方法的局部变量空间是完成确定的,在方法运行期间不会改变局部变量表的大小。

    3.本地方法栈(Native Method Stacks)
        和虚拟机栈发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机只想你个Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Nativce方法服务。虚拟机规范中对本地方法栈的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如Sun
HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。


    4.Java堆
        对大多数应用来说,Java堆(Java Heap)是Java虚拟机所管理的内存最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。词内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规划中的描述是:所有的对象实例以及数组都要在堆上分配,但是随着JIT编译器的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在对上也渐渐变得不是那么“绝对了”。
    同时Java堆还是垃圾收集器管理的主要区域,因此很多时候也被称作”GC 堆”(Garbage Collected Heap)。如果从内存回收的角度看,由于现在的收集器基本都是采用的分代收集算法,所以Java堆中还可以细分为:新生代和老年代

    5.方法区
        方法区(Method Area)和Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java堆区分开来。

    6.运行时常量池(Runtime Constant Pool)
        运行时常量池是方法区是一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内存将在类加载后存放到方法区的运行时常量池中。
        相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只能在编译期产生,也就是并非预置入Class文件中常量池的内存才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的intern方法。
        既然运行时常量池是方法区的一部分,自然会收到方法区内存的限制,当常量池无法再申请到内存时会抛出OutOfMemryError异常。
    
    7.直接内存(Direct Memory)
        直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。
        在JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。
        显然,本机直接的内存分配不会收到Java堆大小的限制,但是,既然是内存,则肯定还是会受到本机总内存(包括RAM以及SWAP区或者分页文件)的大小及处理器寻址空间的限制。服务器管理员配置虚拟机参数时,一般会根据实际内存设置-Xmx等参数信息,但经常会忽略掉直接内存,使得各个内存区域的总和大于物理内存限制(包物理上的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常。 


版权声明:本文为博主原创文章,未经博主允许不得转载。

Hadoop 2.4.1 搭建Ha遇到问题记录

15/06/19 17:12:44 ERROR namenode.FSNamesystem: FSNamesystem initialization failed.
java.io.IOException: Invalid configuration: a shared edits dir must not be specified if HA is not enabled. // 明明我配置了HA,却说没有,下面的配置写错了
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.(FSNamesystem.java:710)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.(FSNamesystem.java:654)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.format(NameNode.java:892)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1310)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1424)
15/06/19 17:12:44 INFO namenode.FSNamesystem: Stopping services started for active state
15/06/19 17:12:44 FATAL namenode.NameNode: Exception in namenode join
java.lang.NullPointerException
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.stopActiveServices(FSNamesystem.java:1118)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.close(FSNamesystem.java:1446)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.(FSNamesystem.java:781)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.(FSNamesystem.java:654)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.format(NameNode.java:892)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1310)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1424)
15/06/19 17:12:44 INFO util.ExitUtil: Exiting with status 1
15/06/19 17:12:44 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at v1/192.168.32.91
************************************************************/

.写成了-

                dfs.ha.automatic-failover-enabled
                true
        
正确如下:

                dfs.ha.automatic-failover.enabled
                true
        

2.journalnode的端口配置错误,导致不能格式化namenode,journalnode监听的端口是:8485,而不是8445.
3.格式化standby namnenode时,有两种方式
    1.将active namenode格式化完成后,将整个hadoop.tmp.dir路径全部拷贝到standby机器上。
    2.在active namenode格式化完成后,并且格式化zkfc(只需要在active上格式化一次,standby上的zkfc不需要再次格式化)启动好了namenode之后。 在standby namenode上执行:hdfs namenode -bootstrapStandby 也可以.如果active namenode没有启动的话,这里会报错。因为standby
namenode是通过active namenode的9000端口通讯的。若active namenode没有启动,则9000没有程序监听提供服务,standby尝试连接9次后会爆异常并且退出。


没有启动active namenode时,报错如下:
[root@v2 hadoop]# hdfs namenode -bootstrapStandby
15/06/19 19:28:45 INFO namenode.NameNode: STARTUP_MSG: 
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = v2/192.168.32.92
STARTUP_MSG:   args = [-bootstrapStandby]
STARTUP_MSG:   version = 2.4.1
STARTUP_MSG:   classpath = /root/hadoop/etc/hadoop:/root/hadoop/share/hadoop/common/lib/asm-3.2.jar:/root/hadoop/share/hadoop/common/lib/xz-1.0.jar:/root/hadoop/share/hadoop/common/lib/junit-4.8.2.jar:/root/hadoop/share/hadoop/common/lib/httpcore-4.2.5.jar:/root/hadoop/share/hadoop/common/lib/jetty-6.1.26.jar:/root/hadoop/share/hadoop/common/lib/commons-net-3.1.jar:/root/hadoop/share/hadoop/common/lib/jetty-util-6.1.26.jar:/root/hadoop/share/hadoop/common/lib/commons-compress-1.4.1.jar:/root/hadoop/share/hadoop/common/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/common/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/common/lib/hadoop-auth-2.4.1.jar:/root/hadoop/share/hadoop/common/lib/stax-api-1.0-2.jar:/root/hadoop/share/hadoop/common/lib/jackson-xc-1.8.8.jar:/root/hadoop/share/hadoop/common/lib/netty-3.6.2.Final.jar:/root/hadoop/share/hadoop/common/lib/httpclient-4.2.5.jar:/root/hadoop/share/hadoop/common/lib/jsr305-1.3.9.jar:/root/hadoop/share/hadoop/common/lib/avro-1.7.4.jar:/root/hadoop/share/hadoop/common/lib/slf4j-api-1.7.5.jar:/root/hadoop/share/hadoop/common/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/common/lib/commons-codec-1.4.jar:/root/hadoop/share/hadoop/common/lib/commons-el-1.0.jar:/root/hadoop/share/hadoop/common/lib/jasper-compiler-5.5.23.jar:/root/hadoop/share/hadoop/common/lib/guava-11.0.2.jar:/root/hadoop/share/hadoop/common/lib/xmlenc-0.52.jar:/root/hadoop/share/hadoop/common/lib/paranamer-2.3.jar:/root/hadoop/share/hadoop/common/lib/commons-math3-3.1.1.jar:/root/hadoop/share/hadoop/common/lib/mockito-all-1.8.5.jar:/root/hadoop/share/hadoop/common/lib/jaxb-api-2.2.2.jar:/root/hadoop/share/hadoop/common/lib/commons-beanutils-core-1.8.0.jar:/root/hadoop/share/hadoop/common/lib/jsch-0.1.42.jar:/root/hadoop/share/hadoop/common/lib/hadoop-annotations-2.4.1.jar:/root/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar:/root/hadoop/share/hadoop/common/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/common/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/common/lib/commons-logging-1.1.3.jar:/root/hadoop/share/hadoop/common/lib/jets3t-0.9.0.jar:/root/hadoop/share/hadoop/common/lib/jsp-api-2.1.jar:/root/hadoop/share/hadoop/common/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/common/lib/snappy-java-1.0.4.1.jar:/root/hadoop/share/hadoop/common/lib/jasper-runtime-5.5.23.jar:/root/hadoop/share/hadoop/common/lib/jaxb-impl-2.2.3-1.jar:/root/hadoop/share/hadoop/common/lib/jersey-json-1.9.jar:/root/hadoop/share/hadoop/common/lib/commons-httpclient-3.1.jar:/root/hadoop/share/hadoop/common/lib/commons-beanutils-1.7.0.jar:/root/hadoop/share/hadoop/common/lib/commons-collections-3.2.1.jar:/root/hadoop/share/hadoop/common/lib/java-xmlbuilder-0.4.jar:/root/hadoop/share/hadoop/common/lib/activation-1.1.jar:/root/hadoop/share/hadoop/common/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/common/lib/commons-cli-1.2.jar:/root/hadoop/share/hadoop/common/lib/commons-configuration-1.6.jar:/root/hadoop/share/hadoop/common/lib/commons-digester-1.8.jar:/root/hadoop/share/hadoop/common/lib/servlet-api-2.5.jar:/root/hadoop/share/hadoop/common/lib/commons-lang-2.6.jar:/root/hadoop/share/hadoop/common/lib/jettison-1.1.jar:/root/hadoop/share/hadoop/common/lib/zookeeper-3.4.5.jar:/root/hadoop/share/hadoop/common/lib/jackson-jaxrs-1.8.8.jar:/root/hadoop/share/hadoop/common/hadoop-nfs-2.4.1.jar:/root/hadoop/share/hadoop/common/hadoop-common-2.4.1-tests.jar:/root/hadoop/share/hadoop/common/hadoop-common-2.4.1.jar:/root/hadoop/share/hadoop/hdfs:/root/hadoop/share/hadoop/hdfs/lib/asm-3.2.jar:/root/hadoop/share/hadoop/hdfs/lib/jetty-6.1.26.jar:/root/hadoop/share/hadoop/hdfs/lib/jetty-util-6.1.26.jar:/root/hadoop/share/hadoop/hdfs/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/hdfs/lib/netty-3.6.2.Final.jar:/root/hadoop/share/hadoop/hdfs/lib/jsr305-1.3.9.jar:/root/hadoop/share/hadoop/hdfs/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-codec-1.4.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-el-1.0.jar:/root/hadoop/share/hadoop/hdfs/lib/guava-11.0.2.jar:/root/hadoop/share/hadoop/hdfs/lib/xmlenc-0.52.jar:/root/hadoop/share/hadoop/hdfs/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-daemon-1.0.13.jar:/root/hadoop/share/hadoop/hdfs/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-logging-1.1.3.jar:/root/hadoop/share/hadoop/hdfs/lib/jsp-api-2.1.jar:/root/hadoop/share/hadoop/hdfs/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/hdfs/lib/jasper-runtime-5.5.23.jar:/root/hadoop/share/hadoop/hdfs/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-cli-1.2.jar:/root/hadoop/share/hadoop/hdfs/lib/servlet-api-2.5.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-lang-2.6.jar:/root/hadoop/share/hadoop/hdfs/hadoop-hdfs-nfs-2.4.1.jar:/root/hadoop/share/hadoop/hdfs/hadoop-hdfs-2.4.1.jar:/root/hadoop/share/hadoop/hdfs/hadoop-hdfs-2.4.1-tests.jar:/root/hadoop/share/hadoop/yarn/lib/asm-3.2.jar:/root/hadoop/share/hadoop/yarn/lib/xz-1.0.jar:/root/hadoop/share/hadoop/yarn/lib/jetty-6.1.26.jar:/root/hadoop/share/hadoop/yarn/lib/jetty-util-6.1.26.jar:/root/hadoop/share/hadoop/yarn/lib/commons-compress-1.4.1.jar:/root/hadoop/share/hadoop/yarn/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/yarn/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/yarn/lib/stax-api-1.0-2.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-xc-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/jsr305-1.3.9.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/commons-codec-1.4.jar:/root/hadoop/share/hadoop/yarn/lib/aopalliance-1.0.jar:/root/hadoop/share/hadoop/yarn/lib/jline-0.9.94.jar:/root/hadoop/share/hadoop/yarn/lib/guava-11.0.2.jar:/root/hadoop/share/hadoop/yarn/lib/jaxb-api-2.2.2.jar:/root/hadoop/share/hadoop/yarn/lib/leveldbjni-all-1.8.jar:/root/hadoop/share/hadoop/yarn/lib/javax.inject-1.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/commons-logging-1.1.3.jar:/root/hadoop/share/hadoop/yarn/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/yarn/lib/jaxb-impl-2.2.3-1.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-json-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/commons-httpclient-3.1.jar:/root/hadoop/share/hadoop/yarn/lib/commons-collections-3.2.1.jar:/root/hadoop/share/hadoop/yarn/lib/activation-1.1.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/guice-servlet-3.0.jar:/root/hadoop/share/hadoop/yarn/lib/commons-cli-1.2.jar:/root/hadoop/share/hadoop/yarn/lib/servlet-api-2.5.jar:/root/hadoop/share/hadoop/yarn/lib/commons-lang-2.6.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-guice-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-client-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/jettison-1.1.jar:/root/hadoop/share/hadoop/yarn/lib/zookeeper-3.4.5.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-jaxrs-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/guice-3.0.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-common-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-nodemanager-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-resourcemanager-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-tests-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-common-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-applications-unmanaged-am-launcher-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-api-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-client-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-web-proxy-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-applicationhistoryservice-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/asm-3.2.jar:/root/hadoop/share/hadoop/mapreduce/lib/xz-1.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/hamcrest-core-1.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/commons-compress-1.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/mapreduce/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/mapreduce/lib/netty-3.6.2.Final.jar:/root/hadoop/share/hadoop/mapreduce/lib/avro-1.7.4.jar:/root/hadoop/share/hadoop/mapreduce/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/mapreduce/lib/aopalliance-1.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/paranamer-2.3.jar:/root/hadoop/share/hadoop/mapreduce/lib/javax.inject-1.jar:/root/hadoop/share/hadoop/mapreduce/lib/hadoop-annotations-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/mapreduce/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/mapreduce/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/snappy-java-1.0.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/mapreduce/lib/guice-servlet-3.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/junit-4.10.jar:/root/hadoop/share/hadoop/mapreduce/lib/jersey-guice-1.9.jar:/root/hadoop/share/hadoop/mapreduce/lib/guice-3.0.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-app-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-hs-plugins-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-hs-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-shuffle-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.4.1-tests.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-common-2.4.1.jar:/root/hadoop/contrib/capacity-scheduler/*.jar
STARTUP_MSG:   build = http://svn.apache.org/repos/asf/hadoop/common -r 1604318; compiled by 'jenkins' on 2014-06-21T05:43Z
STARTUP_MSG:   java = 1.7.0_15
************************************************************/
15/06/19 19:28:45 INFO namenode.NameNode: registered UNIX signal handlers for [TERM, HUP, INT]
15/06/19 19:28:45 INFO namenode.NameNode: createNameNode [-bootstrapStandby]
15/06/19 19:28:47 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
15/06/19 19:28:49 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:50 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 1 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:51 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 2 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:52 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 3 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:53 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 4 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:54 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 5 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:55 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 6 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:56 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 7 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:57 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 8 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:58 INFO ipc.Client: Retrying connect to server: v1/192.168.32.91:9000. Already tried 9 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
15/06/19 19:28:58 FATAL ha.BootstrapStandby: Unable to fetch namespace information from active NN at v1/192.168.32.91:9000: Call From v2/192.168.32.92 to v1:9000 failed on connection exception: java.net.ConnectException: Connection refused; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused
15/06/19 19:28:58 INFO util.ExitUtil: Exiting with status 2
15/06/19 19:28:58 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at v2/192.168.32.92
************************************************************/
启动了active如下:

[root@v2 hadoop]# hdfs namenode -bootstrapStandby
15/06/19 19:31:39 INFO namenode.NameNode: STARTUP_MSG: 
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = v2/192.168.32.92
STARTUP_MSG:   args = [-bootstrapStandby]
STARTUP_MSG:   version = 2.4.1
STARTUP_MSG:   classpath = /root/hadoop/etc/hadoop:/root/hadoop/share/hadoop/common/lib/asm-3.2.jar:/root/hadoop/share/hadoop/common/lib/xz-1.0.jar:/root/hadoop/share/hadoop/common/lib/junit-4.8.2.jar:/root/hadoop/share/hadoop/common/lib/httpcore-4.2.5.jar:/root/hadoop/share/hadoop/common/lib/jetty-6.1.26.jar:/root/hadoop/share/hadoop/common/lib/commons-net-3.1.jar:/root/hadoop/share/hadoop/common/lib/jetty-util-6.1.26.jar:/root/hadoop/share/hadoop/common/lib/commons-compress-1.4.1.jar:/root/hadoop/share/hadoop/common/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/common/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/common/lib/hadoop-auth-2.4.1.jar:/root/hadoop/share/hadoop/common/lib/stax-api-1.0-2.jar:/root/hadoop/share/hadoop/common/lib/jackson-xc-1.8.8.jar:/root/hadoop/share/hadoop/common/lib/netty-3.6.2.Final.jar:/root/hadoop/share/hadoop/common/lib/httpclient-4.2.5.jar:/root/hadoop/share/hadoop/common/lib/jsr305-1.3.9.jar:/root/hadoop/share/hadoop/common/lib/avro-1.7.4.jar:/root/hadoop/share/hadoop/common/lib/slf4j-api-1.7.5.jar:/root/hadoop/share/hadoop/common/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/common/lib/commons-codec-1.4.jar:/root/hadoop/share/hadoop/common/lib/commons-el-1.0.jar:/root/hadoop/share/hadoop/common/lib/jasper-compiler-5.5.23.jar:/root/hadoop/share/hadoop/common/lib/guava-11.0.2.jar:/root/hadoop/share/hadoop/common/lib/xmlenc-0.52.jar:/root/hadoop/share/hadoop/common/lib/paranamer-2.3.jar:/root/hadoop/share/hadoop/common/lib/commons-math3-3.1.1.jar:/root/hadoop/share/hadoop/common/lib/mockito-all-1.8.5.jar:/root/hadoop/share/hadoop/common/lib/jaxb-api-2.2.2.jar:/root/hadoop/share/hadoop/common/lib/commons-beanutils-core-1.8.0.jar:/root/hadoop/share/hadoop/common/lib/jsch-0.1.42.jar:/root/hadoop/share/hadoop/common/lib/hadoop-annotations-2.4.1.jar:/root/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar:/root/hadoop/share/hadoop/common/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/common/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/common/lib/commons-logging-1.1.3.jar:/root/hadoop/share/hadoop/common/lib/jets3t-0.9.0.jar:/root/hadoop/share/hadoop/common/lib/jsp-api-2.1.jar:/root/hadoop/share/hadoop/common/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/common/lib/snappy-java-1.0.4.1.jar:/root/hadoop/share/hadoop/common/lib/jasper-runtime-5.5.23.jar:/root/hadoop/share/hadoop/common/lib/jaxb-impl-2.2.3-1.jar:/root/hadoop/share/hadoop/common/lib/jersey-json-1.9.jar:/root/hadoop/share/hadoop/common/lib/commons-httpclient-3.1.jar:/root/hadoop/share/hadoop/common/lib/commons-beanutils-1.7.0.jar:/root/hadoop/share/hadoop/common/lib/commons-collections-3.2.1.jar:/root/hadoop/share/hadoop/common/lib/java-xmlbuilder-0.4.jar:/root/hadoop/share/hadoop/common/lib/activation-1.1.jar:/root/hadoop/share/hadoop/common/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/common/lib/commons-cli-1.2.jar:/root/hadoop/share/hadoop/common/lib/commons-configuration-1.6.jar:/root/hadoop/share/hadoop/common/lib/commons-digester-1.8.jar:/root/hadoop/share/hadoop/common/lib/servlet-api-2.5.jar:/root/hadoop/share/hadoop/common/lib/commons-lang-2.6.jar:/root/hadoop/share/hadoop/common/lib/jettison-1.1.jar:/root/hadoop/share/hadoop/common/lib/zookeeper-3.4.5.jar:/root/hadoop/share/hadoop/common/lib/jackson-jaxrs-1.8.8.jar:/root/hadoop/share/hadoop/common/hadoop-nfs-2.4.1.jar:/root/hadoop/share/hadoop/common/hadoop-common-2.4.1-tests.jar:/root/hadoop/share/hadoop/common/hadoop-common-2.4.1.jar:/root/hadoop/share/hadoop/hdfs:/root/hadoop/share/hadoop/hdfs/lib/asm-3.2.jar:/root/hadoop/share/hadoop/hdfs/lib/jetty-6.1.26.jar:/root/hadoop/share/hadoop/hdfs/lib/jetty-util-6.1.26.jar:/root/hadoop/share/hadoop/hdfs/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/hdfs/lib/netty-3.6.2.Final.jar:/root/hadoop/share/hadoop/hdfs/lib/jsr305-1.3.9.jar:/root/hadoop/share/hadoop/hdfs/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-codec-1.4.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-el-1.0.jar:/root/hadoop/share/hadoop/hdfs/lib/guava-11.0.2.jar:/root/hadoop/share/hadoop/hdfs/lib/xmlenc-0.52.jar:/root/hadoop/share/hadoop/hdfs/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-daemon-1.0.13.jar:/root/hadoop/share/hadoop/hdfs/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-logging-1.1.3.jar:/root/hadoop/share/hadoop/hdfs/lib/jsp-api-2.1.jar:/root/hadoop/share/hadoop/hdfs/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/hdfs/lib/jasper-runtime-5.5.23.jar:/root/hadoop/share/hadoop/hdfs/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-cli-1.2.jar:/root/hadoop/share/hadoop/hdfs/lib/servlet-api-2.5.jar:/root/hadoop/share/hadoop/hdfs/lib/commons-lang-2.6.jar:/root/hadoop/share/hadoop/hdfs/hadoop-hdfs-nfs-2.4.1.jar:/root/hadoop/share/hadoop/hdfs/hadoop-hdfs-2.4.1.jar:/root/hadoop/share/hadoop/hdfs/hadoop-hdfs-2.4.1-tests.jar:/root/hadoop/share/hadoop/yarn/lib/asm-3.2.jar:/root/hadoop/share/hadoop/yarn/lib/xz-1.0.jar:/root/hadoop/share/hadoop/yarn/lib/jetty-6.1.26.jar:/root/hadoop/share/hadoop/yarn/lib/jetty-util-6.1.26.jar:/root/hadoop/share/hadoop/yarn/lib/commons-compress-1.4.1.jar:/root/hadoop/share/hadoop/yarn/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/yarn/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/yarn/lib/stax-api-1.0-2.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-xc-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/jsr305-1.3.9.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/commons-codec-1.4.jar:/root/hadoop/share/hadoop/yarn/lib/aopalliance-1.0.jar:/root/hadoop/share/hadoop/yarn/lib/jline-0.9.94.jar:/root/hadoop/share/hadoop/yarn/lib/guava-11.0.2.jar:/root/hadoop/share/hadoop/yarn/lib/jaxb-api-2.2.2.jar:/root/hadoop/share/hadoop/yarn/lib/leveldbjni-all-1.8.jar:/root/hadoop/share/hadoop/yarn/lib/javax.inject-1.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/commons-logging-1.1.3.jar:/root/hadoop/share/hadoop/yarn/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/yarn/lib/jaxb-impl-2.2.3-1.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-json-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/commons-httpclient-3.1.jar:/root/hadoop/share/hadoop/yarn/lib/commons-collections-3.2.1.jar:/root/hadoop/share/hadoop/yarn/lib/activation-1.1.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/guice-servlet-3.0.jar:/root/hadoop/share/hadoop/yarn/lib/commons-cli-1.2.jar:/root/hadoop/share/hadoop/yarn/lib/servlet-api-2.5.jar:/root/hadoop/share/hadoop/yarn/lib/commons-lang-2.6.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-guice-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/jersey-client-1.9.jar:/root/hadoop/share/hadoop/yarn/lib/jettison-1.1.jar:/root/hadoop/share/hadoop/yarn/lib/zookeeper-3.4.5.jar:/root/hadoop/share/hadoop/yarn/lib/jackson-jaxrs-1.8.8.jar:/root/hadoop/share/hadoop/yarn/lib/guice-3.0.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-common-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-nodemanager-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-resourcemanager-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-tests-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-common-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-applications-unmanaged-am-launcher-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-api-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-client-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-web-proxy-2.4.1.jar:/root/hadoop/share/hadoop/yarn/hadoop-yarn-server-applicationhistoryservice-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/asm-3.2.jar:/root/hadoop/share/hadoop/mapreduce/lib/xz-1.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/hamcrest-core-1.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/commons-compress-1.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/log4j-1.2.17.jar:/root/hadoop/share/hadoop/mapreduce/lib/commons-io-2.4.jar:/root/hadoop/share/hadoop/mapreduce/lib/netty-3.6.2.Final.jar:/root/hadoop/share/hadoop/mapreduce/lib/avro-1.7.4.jar:/root/hadoop/share/hadoop/mapreduce/lib/jackson-mapper-asl-1.8.8.jar:/root/hadoop/share/hadoop/mapreduce/lib/aopalliance-1.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/paranamer-2.3.jar:/root/hadoop/share/hadoop/mapreduce/lib/javax.inject-1.jar:/root/hadoop/share/hadoop/mapreduce/lib/hadoop-annotations-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/jackson-core-asl-1.8.8.jar:/root/hadoop/share/hadoop/mapreduce/lib/jersey-core-1.9.jar:/root/hadoop/share/hadoop/mapreduce/lib/protobuf-java-2.5.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/snappy-java-1.0.4.1.jar:/root/hadoop/share/hadoop/mapreduce/lib/jersey-server-1.9.jar:/root/hadoop/share/hadoop/mapreduce/lib/guice-servlet-3.0.jar:/root/hadoop/share/hadoop/mapreduce/lib/junit-4.10.jar:/root/hadoop/share/hadoop/mapreduce/lib/jersey-guice-1.9.jar:/root/hadoop/share/hadoop/mapreduce/lib/guice-3.0.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-app-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-hs-plugins-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-hs-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-shuffle-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.4.1-tests.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.4.1.jar:/root/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-common-2.4.1.jar:/root/hadoop/contrib/capacity-scheduler/*.jar
STARTUP_MSG:   build = http://svn.apache.org/repos/asf/hadoop/common -r 1604318; compiled by 'jenkins' on 2014-06-21T05:43Z
STARTUP_MSG:   java = 1.7.0_15
************************************************************/
15/06/19 19:31:39 INFO namenode.NameNode: registered UNIX signal handlers for [TERM, HUP, INT]
15/06/19 19:31:39 INFO namenode.NameNode: createNameNode [-bootstrapStandby]
15/06/19 19:31:41 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
=====================================================
About to bootstrap Standby ID bnn2 from:
           Nameservice ID: bns1
        Other Namenode ID: bnn1
  Other NN's HTTP address: http://v1:50070
  Other NN's IPC  address: v1/192.168.32.91:9000
             Namespace ID: 32897138
            Block pool ID: BP-134496651-192.168.32.91-1434751114027
               Cluster ID: CID-c5890502-45a9-425e-9ae3-aa70c3eff8a6
           Layout version: -56
=====================================================
15/06/19 19:31:44 INFO common.Storage: Storage directory /root/hadoop/tmp/dfs/name has been successfully formatted.
15/06/19 19:31:45 INFO namenode.TransferFsImage: Opening connection to http://v1:50070/imagetransfer?getimage=1&txid=0&storageInfo=-56:32897138:0:CID-c5890502-45a9-425e-9ae3-aa70c3eff8a6
15/06/19 19:31:46 INFO namenode.TransferFsImage: Image Transfer timeout configured to 60000 milliseconds
15/06/19 19:31:46 INFO namenode.TransferFsImage: Transfer took 0.01s at 0.00 KB/s
15/06/19 19:31:46 INFO namenode.TransferFsImage: Downloaded file fsimage.ckpt_0000000000000000000 size 350 bytes.
15/06/19 19:31:46 INFO util.ExitUtil: Exiting with status 0
15/06/19 19:31:46 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at v2/192.168.32.92
************************************************************/

4.hbase启动时,如果不同节点时间不同的话,启动只有HMaster会起来,别的HRegionServer都会挂掉。同步时间即可,HBase需要用到hadoop的{core-site.xml/hdfs-site.xml},否则会将配置好的ha hdfsname(hdfs://bns1/hbase)当成hostname去解析,把hdfs相关文件拷贝到hbase/conf下就能正常运行了。
5.hive配置元数据快记法:
    4个配置项前缀:javax.jdo.option.Connection[URL/UserName/Password/DriverName]
    createDatabaseIfNotExist
    配置mysql允许远程连接:
        #(执行下面的语句  *.*:所有库下的所有表   %:任何IP地址或主机都可以连接)
GRANT ALL PRIVILEGES ON *.* TO ‘root’@’%’ IDENTIFIED BY ‘123’ WITH GRANT OPTION;
FLUSH PRIVILEGES;
        如果这么配置完了之后,可以远程登录但是本机登录不了的时候。可以用mysqladmin给本地重新修改下密码
        /usr/bin/mysqladmin -uroot -h currentHostName password ‘new-password’

版权声明:本文为博主原创文章,未经博主允许不得转载。

Spark 通讯模块 以及常用分布式通讯方式

Spark的Cluster Manager可以有Local、Standalone、Mesos、YARN等部署模式.

常用分布式通信方式:
    1. RPC(Remote Produce Call)
           
  
  RPC远程过程调用协议,基于C/S模型调用。过程大致可以理解为本地分布式对象向本机发送请求,不用自己编写底层通讯机制。通过网络向服务器发送请求,服务器对象接收参数,进行处理,再把处理后的结果发送回客户端。
    2.RMI(Remote Method Invocation)
       
  
       RMI和RPC一样都是调用远程的方法,可以把RMI看做的用Java语言实现了RPC协议。RPC不支持对象通信,支持对象传输,这也是RMI相比RPC的优越之处
    3.JMS(Java Remote Service)
              
  
JMS是在各个Java类之间传递消息的标准,其支持P2P和pub/stub两种消息模型,即点对点和发布订阅模型。其优点在于:支持异步通信,消息生产者和消费者耦合度低。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无须专用连接来连接它们
    4.EJB(Enterprise Java Bean)
             
  EJB是Java EE的一个规范,该规范描述了分布式应用程序需要解决的事务处理,安全、日志、分布式等问题。与此同时,Sun公司也实现了自己定义的这一个标准,相当于自己颁布一个标准。EJB是一个特殊的Java类,按照Java服务器接口定义,放在容器里可以帮助该类管理事务、分布式、安全等,只有大型分布式系统间才会用到EJB,一般小型程序不会用到。

    
    5.Web Service
       Web Service是网络间跨语言、跨平台的分布式系统间的通信标准。传输XML、JSON等格式的数据,应用范围较广.但是同构语言不建议使用,效率太低,也不适合传输大数据量的数据,XML无用数据太多

版权声明:本文为博主原创文章,未经博主允许不得转载。

spark 1.3.1 master 源码初探01

首先打开远程调试:
    1.在spark/conf/spark-env.xml里面加入下列代码允许master远程调试
          
export SPARK_MASTER_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=10000"
    2.IDEA里面创建远程调试配置
        
    3.在服务器上启动master
    3.点击debug(小虫子)就可以开始了


入口:

    org.apache.spark.deploy.master.Master:865 Line Mian

进入startSystemAndActor,这里会通过一系列安全校验后通过Akka建立Actor    




   下面跟进AkkaUtils.createActorSystem



尝试启动服务




若是启动失败,重新尝试以及计算端口 




开始启动




ActorSystem启动完成,下面开始看启动Master:



主构造器中有意思的代码:



查看Master
preStart中,订阅事件以及检测Worker心跳




执行到这里master启动就差不多了
 , 有时间接着总结。 




版权声明:本文为博主原创文章,未经博主允许不得转载。

StormDRPC 概念以及简单例子测试

Storm里面引入DRPC主要是利用storm的实时计算能力来并行化CPU intensive的计算。DRPCstorm topology以函数的参数流作为输入,而把这些函数调用的返回值作为topology的输出流。

 

DRPC其实不能算是storm本身的一个特性, 它是通过组合storm的原语spoutbolt, topology而成的一种模式(pattern)

Storm DRPC工作机制

Distributed RPC是由一个”DPRC Server”协调的(storm自带了一个实现)

DRPC服务器协调

1) 接收一个RPC请求。

2) 发送请求到storm topology 

3) storm topology接收结果。

4) 把结果发回给等待的客户端。从客户端的角度来看一个DRPC调用跟一个普通的RPC调用没有任何区别。比如下面是客户端如何调用RPCexclaimation方法的,方法的参数是: hello

 

DRPCClient client = new DRPCClient(“drpc-host”, 3772);

String result = client.execute(“exclaimation”, “hello”);

 

 

DRPC的工作流大致是这样的:

 

 

客户端给DRPC服务器发送要执行的方法的名字,以及这个方法的参数。实现了这个函数的topology使用DRPCSpoutDRPC服务器接收函数调用流。每个函数调用被DRPC服务器标记了一个唯一的id。 这个topology然后计算结果,在topology的最后一个叫做ReturnResultsbolt会连接到DRPC服务器,并且把这个调用的结果发送给DRPC服务器(通过那个唯一的id标识)DRPC服务器用那个唯一id来跟等待的客户端匹配上,唤醒这个客户端并且把结果发送给它。

 

LinearDRPCTopologyBuilder

 

Storm自带了一个称作LinearDRPCTopologyBuildertopology builder, 它把实现DRPC的几乎所有步骤都自动化了,包括:

设置spout

把结果返回给DRPC服务器

代码示例:

Blot:

package com.billstudy.storm.drpc;
import backtype.storm.topology.BasicOutputCollector;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseBasicBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
/**
 * 将用户输入的字符串,加1后输出
 * @author Bill
 * @since V1.0 2015年7月7日 - 上午10:47:59
 */
public class DRPCBlotOf1 extends BaseBasicBolt{
	private static final long serialVersionUID = 1L;
	/**
	 * 往下走的时候,需要把DRPC的元数据带上。
	 * 在tupule的第一个元素中
	 */
	@Override
	public void execute(Tuple input, BasicOutputCollector collector) {
		Object drpcMeta = input.getValue(0); // 元数据
		String clientData = input.getString(1); // 客户端传递来的数据
		collector.emit(new Values(drpcMeta,clientData + "1"));
	}
	@Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {
		declarer.declare(new Fields("id","result"));
	}
}

Driver:

package com.billstudy.storm.drpc;
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.LocalDRPC;
import backtype.storm.StormSubmitter;
import backtype.storm.drpc.LinearDRPCTopologyBuilder;
/**
 * DPRC Driver
 * @author Bill
 * @since V1.0 2015年7月7日 - 上午10:55:52
 */
public class DRPCMain {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) throws Exception{
		
		// 使用DRPC
		LinearDRPCTopologyBuilder drpcTopologyBuilder = new LinearDRPCTopologyBuilder("drpc-test");
		drpcTopologyBuilder.addBolt(new DRPCBlotOf1(),3);
		
		Config config = new Config();
		
		if(args == null || args.length == 0){
			LocalDRPC drpc = new LocalDRPC();
			LocalCluster cluster = new LocalCluster();
			cluster.submitTopology("drpc-demo", config, drpcTopologyBuilder.createRemoteTopology());
			
			for (String word : new String[]{"hello","world","rpc"}) {
				System.out.println("result : " + word + " : " + drpc.execute("drpc-test", word));
			}
		}else {
			config.setNumWorkers(3);
			StormSubmitter.submitTopology(args[0], config, drpcTopologyBuilder.createRemoteTopology());
		}
		
		
	}
}

Storm集群需要配置以下:
注意drpc的部分
# with the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
########### These MUST be filled in for a storm configuration
storm.zookeeper.servers:
    - "v5"
    - "v6"
    - "v7"
# 
nimbus.host: "v5"
#supervisor.slots.ports
#-8801
#-8802
#-8803
#-8804
#-8805
#-8806
# 
# 
# ##### These may optionally be filled in:
#    
## List of custom serializations
# topology.kryo.register:
#     - org.mycompany.MyType
#     - org.mycompany.MyType2: org.mycompany.MyType2Serializer
#
## List of custom kryo decorators
# topology.kryo.decorators:
#     - org.mycompany.MyDecorator
#
## Locations of the drpc servers
drpc.servers:
    - "v5"
#     - "server2"

然后配置文件分发各个子节点,启动nimbus,drpc,supervisor就可以测试了

scp /root/storm/conf/storm.yaml v6:$PWD
scp /root/storm/conf/storm.yaml v7:$PWD
storm nimbus &
storm drpc &
storm supervisor & #这句需要在v6,v7上面执行,上面两句在v5上面执行就好了
#提交打好的jar
storm jar DRPC.jar com.billstudy.storm.drpc.DRPCMain drpc-test-task
#可以到v5:8080上面看到任务提交成功了,就可以启动DRPCClient测试了

DRPCClient程序 通过Storm drpc服务监听的3772端口进行通讯
execute执行有两个参数:
    1:drpc-test这是创建LinearDRPCTopologyBuilder时指定的名称
  2: Bill 这是传入的参数
测试完成 。 ^ _ ^ . 

版权声明:本文为博主原创文章,未经博主允许不得转载。

ZooKeeper典型应用场景一览

ZooKeeper是一个高可用的分布式数据管理与系统协调框架。基于对Paxos算法的实现,使该框架保证了分布式环境中数据的强一致性,也正是基于这样的特性,使得ZooKeeper解决很多分布式问题。网上对ZK的应用场景也有不少介绍,本文将结合作者身边的项目例子,系统地对ZK的应用场景进行一个分门归类的介绍。

值得注意的是,ZK并非天生就是为这些应用场景设计的,都是后来众多开发者根据其框架的特性,利用其提供的一系列API接口(或者称为原语集),摸索出来的典型使用方法。因此,也非常欢迎读者分享你在ZK使用上的奇技淫巧。

ZooKeeper典型应用场景一览

数据发布与订阅(配置中心) 

发布与订阅模型,即所谓的配置中心,顾名思义就是发布者将数据发布到ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。

· 应用中用到的一些配置信息放到ZK上进行集中管理。这类场景通常是这样:应用在启动的时候会主动来获取一次配置,同时,在节点上注册一个Watcher,这样一来,以后每次配置有更新的时候,都会实时通知到订阅的客户端,从来达到获取最新配置信息的目的。

· 分布式搜索服务中,索引的元信息和服务器集群机器的节点状态存放在ZK的一些指定节点,供各个客户端订阅使用。

· 分布式日志收集系统。这个系统的核心工作是收集分布在不同机器的日志。收集器通常是按照应用来分配收集任务单元,因此需要在ZK上创建一个以应用名作为path的节点P,并将这个应用的所有机器ip,以子节点的形式注册到节点P上,这样一来就能够实现机器变动的时候,能够实时通知到收集器调整任务分配。

· 系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息的发问。通常是暴露出接口,例如JMX接口,来获取一些运行时的信息。引入ZK之后,就不用自己实现一套方案了,只要将这些信息存放到指定的ZK节点上即可。

注意:在上面提到的应用场景中,有个默认前提是:数据量很小,但是数据更新可能会比较快的场景。

负载均衡

这里说的负载均衡是指软负载均衡。在分布式环境中,为了保证高可用性,通常同一个应用或同一个服务的提供方都会部署多份,达到对等服务。而消费者就须要在这些对等的服务器中选择一个来执行相关的业务逻辑,其中比较典型的是消息中间件中的生产者,消费者负载均衡。

消息中间件中发布者和订阅者的负载均衡,linkedin开源的KafkaMQ和阿里开源的metaq都是通过zookeeper来做到生产者、消费者的负载均衡。这里以metaq为例如讲下:
生产者负载均衡metaq发送消息的时候,生产者在发送消息的时候必须选择一台broker上的一个分区来发送消息,因此metaq在运行过程中,会把所有broker和对应的分区信息全部注册到ZK指定节点上,默认的策略是一个依次轮询的过程,生产者在通过ZK获取分区列表之后,会按照brokerIdpartition的顺序排列组织成一个有序的分区列表,发送的时候按照从头到尾循环往复的方式选择一个分区来发送消息。

消费负载均衡:

在消费过程中,一个消费者会消费一个或多个分区中的消息,但是一个分区只会由一个消费者来消费。MetaQ的消费策略是:

· 每个分区针对同一个group只挂载一个消费者。

· 如果同一个group的消费者数目大于分区数目,则多出来的消费者将不参与消费。

· 如果同一个group的消费者数目小于分区数目,则有部分消费者需要额外承担消费任务。

在某个消费者故障或者重启等情况下,其他消费者会感知到这一变化(通过 zookeeper watch消费者列表),然后重新进行负载均衡,保证所有的分区都有消费者进行消费。

命名服务(Naming Service)

命名服务也是分布式系统中比较常见的一类场景。在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址,远程对象等等——这些我们都可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。通过调用ZK提供的创建节点的 API,能够很容易创建一个全局唯一的path,这个path就可以作为一个名称。

阿里巴巴集团开源的分布式服务框架Dubbo中使用ZooKeeper来作为其命名服务,维护全局的服务地址列表,点击这里查看Dubbo开源项目。在Dubbo实现中:

服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。

服务消费者启动的时候,订阅/dubbo/${serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入自己的URL地址。

注意,所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。

另外,Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/${serviceName}目录下所有提供者和消费者的信息。

分布式通知/协调

ZooKeeper中特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对ZK上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点的),其中一个系统updateznode,那么另一个系统能够收到通知,并作出相应处理

· 另一种心跳检测机制:检测系统和被检测系统之间并不直接关联起来,而是通过zk上某个节点关联,大大减少系统耦合。

· 另一种系统调度模式:某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改了ZK上某些节点的状态,而ZK就把这些变化通知给他们注册Watcher的客户端,即推送系统,于是,作出相应的推送任务。

· 另一种工作汇报模式:一些类似于任务分发系统,子任务启动后,到zk来注册一个临时节点,并且定时将自己的进度进行汇报(将进度写回这个临时节点),这样任务管理者就能够实时知道任务进度。

总之,使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合

集群管理与Master选举

· 集群机器监控:这通常用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应。这样的场景中,往往有一个监控系统,实时检测集群机器是否存活。过去的做法通常是:监控系统通过某种手段(比如ping)定时检测每个机器,或者每个机器自己定时向监控系统汇报我还活着 这种做法可行,但是存在两个比较明显的问题:

1. 集群中机器有变动的时候,牵连修改的东西比较多。

2. 有一定的延时。

利用ZooKeeper有两个特性,就可以实时另一种集群机器存活性监控系统:

1. 客户端在节点 x 上注册一个Watcher,那么如果 x?的子节点变化了,会通知该客户端。

2. 创建EPHEMERAL类型的节点,一旦客户端和服务器的会话结束或过期,那么该节点就会消失。

例如,监控系统在 /clusterServers 节点上注册一个Watcher,以后每动态加机器,那么就往 /clusterServers 下创建一个 EPHEMERAL类型的节点:/clusterServers/{hostname}. 这样,监控系统就能够实时知道机器的增减情况,至于后续处理就是监控系统的业务了。

· Master选举则是zookeeper中最为经典的应用场景了。

在分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算,网络I/O处理),往往只需要让整个集群中的某一台机器进行执行,其余机器可以共享这个结果,这样可以大大减少重复劳动,提高性能,于是这个master选举便是这种场景下的碰到的主要问题。

利用ZooKeeper的强一致性,能够保证在分布式高并发情况下节点创建的全局唯一性,即:同时有多个客户端请求创建 /currentMaster 节点,最终一定只有一个客户端请求能够创建成功。利用这个特性,就能很轻易的在分布式环境中进行集群选取了。

另外,这种场景演化一下,就是动态Master选举。这就要用到?EPHEMERAL_SEQUENTIAL类型节点的特性了。

上文中提到,所有客户端创建请求,最终只有一个能够创建成功。在这里稍微变化下,就是允许所有请求都能够创建成功,但是得有个创建顺序,于是所有的请求最终在ZK上创建结果的一种可能情况是这样: /currentMaster/{sessionId}-1 ,?/currentMaster/{sessionId}-2 ,?/currentMaster/{sessionId}-3 ….. 每次选取序列号最小的那个机器作为Master,如果这个机器挂了,由于他创建的节点会马上小时,那么之后最小的那个机器就是Master了。

· 在搜索系统中,如果集群中每个机器都生成一份全量索引,不仅耗时,而且不能保证彼此之间索引数据一致。因此让集群中的Master来进行全量索引的生成,然后同步到集群中其它机器。另外,Master选举的容灾措施是,可以随时进行手动指定master,就是说应用在zk在无法获取master信息时,可以通过比如http方式,向一个地方获取master

· Hbase中,也是使用ZooKeeper来实现动态HMaster的选举。在Hbase实现中,会在ZK上存储一些ROOT表的地址和 HMaster的地址,HRegionServer也会把自己以临时节点(Ephemeral)的方式注册到Zookeeper中,使得HMaster可以随时感知到各个HRegionServer的存活状态,同时,一旦HMaster出现问题,会重新选举出一个HMaster来运行,从而避免了 HMaster的单点问题

分布式锁

分布式锁,这个主要得益于ZooKeeper为我们保证了数据的强一致性。锁服务可以分为两类,一个是保持独占,另一个是控制时序

· 所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁,通过 create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。

· 控制时序,就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。

分布式队列

队列方面,简单地讲有两种,一种是常规的先进先出队列,另一种是要等到队列成员聚齐之后的才统一按序执行。对于第一种先进先出队列,和分布式锁服务中的控制时序场景基本原理一致,这里不再赘述。

第二种队列其实是在FIFO队列的基础上作了一个增强。通常可以在 /queue 这个znode下预先建立一个/queue/num 节点,并且赋值为n(或者直接给/queue赋值n),表示队列大小,之后每次有队列成员加入后,就判断下是否已经到达队列大小,决定是否可以开始执行了。这种用法的典型场景是,分布式环境中,一个大任务Task A,需要在很多子任务完成(或条件就绪)情况下才能进行。这个时候,凡是其中一个子任务完成(就绪),那么就去 /taskList 下建立自己的临时时序节点(CreateMode.EPHEMERAL_SEQUENTIAL),当 /taskList 发现自己下面的子节点满足指定个数,就可以进行下一步按序进行处理了。

 

Zookeeper实现分布式锁

package com.billstudy.zookeeper;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

/**
 * 注册服务,并且自动监听可用服务列表
 * @author Bill
 * @since V1.0 2015年6月24日 - 上午10:03:24
 */
public class AppServer {

	private ZooKeeper zk = null;
	
	// 树前缀
	private static final String zkParentPrefix = "/appserver";

	private static final String zkChildPrefix = "/app"; 
	
	// 维护可用列表
	private final ArrayList availableServerList = new ArrayList();
	
	public void connectZk(String address){
		try {
			zk = new ZooKeeper("hadoop-server05:2181,hadoop-server06:2181,hadoop-server07:2181", 5000, new Watcher() {
				@Override
				public void process(WatchedEvent event) {
					
					System.out.println(event.toString());
					
					if (event.getType() == EventType.NodeChildrenChanged
						&& event.getPath().startsWith(zkParentPrefix)
							) {
						flushServerList();
					}
				}
			});
			
			// 如果根节点没有,则先创建
			if (zk.exists(zkParentPrefix, true) == null) {
				zk.create(zkParentPrefix, "AppServer root dir ".getBytes("UTF-8"), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				System.out.println("znode :" + zkParentPrefix + "is not exists , create successful !");
			}
			
			// 根据当前address创建临时连续子节点,这样多个不同的app child节点不会重复。 zk会自己维护序列
			String childPath = zk.create(zkParentPrefix + zkChildPrefix, address.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
			
			System.out.println("create " + childPath + " successful, address is :" + address);
			
			
			flushServerList();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * 收到子节点更新后,刷新当前可用服务列表
	 * @author Bill
	 * @since V1.0 2015年6月24日 - 上午10:08:19
	 */
	protected void flushServerList() {
		availableServerList.clear();
		try {
			List children = zk.getChildren(zkParentPrefix, true);
			for (String child : children) {
				byte[] data = zk.getData(zkParentPrefix + "/" + child, true,new Stat());
				availableServerList.add(new String(data,"UTF-8"));
			}
			System.out.println("current available server list:" + availableServerList);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 此处可以用来处理业务逻辑,目前让主线程挂起
	 * @author Bill
	 * @since V1.0 2015年6月24日 - 上午10:24:00
	 */
	public void handle(){
		try {
			// System.out.println("handle ...");
			TimeUnit.HOURS.sleep(Long.MAX_VALUE);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		
		if (args.length != 1) {
			System.err.println("The program first argument must be address !");
			System.exit(1);
		}
		AppServer appServer = new AppServer();
		appServer.connectZk(args[0]);
		appServer.handle();
	}
	
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Zookeeper实现服务上下线监控服务列表

package com.billstudy.zookeeper;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

/**
 * 注册服务,并且自动监听可用服务列表
 * @author Bill
 * @since V1.0 2015年6月24日 - 上午10:03:24
 */
public class AppServer {

	private ZooKeeper zk = null;
	
	// 树前缀
	private static final String zkParentPrefix = "/appserver";

	private static final String zkChildPrefix = "/app"; 
	
	// 维护可用列表
	private final ArrayList availableServerList = new ArrayList();
	
	public void connectZk(String address){
		try {
			zk = new ZooKeeper("hadoop-server05:2181,hadoop-server06:2181,hadoop-server07:2181", 5000, new Watcher() {
				@Override
				public void process(WatchedEvent event) {
					
					System.out.println(event.toString());
					
					if (event.getType() == EventType.NodeChildrenChanged
						&& event.getPath().startsWith(zkParentPrefix)
							) {
						flushServerList();
					}
				}
			});
			
			// 如果根节点没有,则先创建
			if (zk.exists(zkParentPrefix, true) == null) {
				zk.create(zkParentPrefix, "AppServer root dir ".getBytes("UTF-8"), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				System.out.println("znode :" + zkParentPrefix + "is not exists , create successful !");
			}
			
			// 根据当前address创建临时连续子节点,这样多个不同的app child节点不会重复。 zk会自己维护序列
			String childPath = zk.create(zkParentPrefix + zkChildPrefix, address.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
			
			System.out.println("create " + childPath + " successful, address is :" + address);
			
			
			flushServerList();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * 收到子节点更新后,刷新当前可用服务列表
	 * @author Bill
	 * @since V1.0 2015年6月24日 - 上午10:08:19
	 */
	protected void flushServerList() {
		availableServerList.clear();
		try {
			List children = zk.getChildren(zkParentPrefix, true);
			for (String child : children) {
				byte[] data = zk.getData(zkParentPrefix + "/" + child, true,new Stat());
				availableServerList.add(new String(data,"UTF-8"));
			}
			System.out.println("current available server list:" + availableServerList);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 此处可以用来处理业务逻辑,目前让主线程挂起
	 * @author Bill
	 * @since V1.0 2015年6月24日 - 上午10:24:00
	 */
	public void handle(){
		try {
			// System.out.println("handle ...");
			TimeUnit.HOURS.sleep(Long.MAX_VALUE);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		
		if (args.length != 1) {
			System.err.println("The program first argument must be address !");
			System.exit(1);
		}
		AppServer appServer = new AppServer();
		appServer.connectZk(args[0]);
		appServer.handle();
	}
	
}

版权声明:本文为博主原创文章,未经博主允许不得转载。