CRUD

1. 原生API - CRUD

  1. <dependency>
  2. <groupId>org.apache.zookeeper</groupId>
  3. <artifactId>zookeeper</artifactId>
  4. <version>3.5.7</version>
  5. </dependency>

2. ZkClient API - CRUD

略,使用不广泛,不推荐使用。

3. Curator API - CRUD

  1. <dependency>
  2. <groupId>org.apache.curator</groupId>
  3. <artifactId>curator-framework</artifactId>
  4. <version>4.3.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.curator</groupId>
  8. <artifactId>curator-recipes</artifactId>
  9. <version>4.3.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.curator</groupId>
  13. <artifactId>curator-client</artifactId>
  14. <version>4.3.0</version>
  15. </dependency>

场景:服务动态上下线

1. 实现思路

Online & Offline.drawio.png

  1. 服务端启动时向ZooKeeper注册节点(临时节点)。
  2. 客户端获取当前在线服务列表,并注册监听(一次有效)。
  3. 当服务器节点上下线时,ZooKeeper将新增或删除该节点,并触发监听事件。
  4. ZooKeeper发布服务器节点上下线通知给客户端监听者。
  5. 客户端收到通知,重新拉取服务器列表,并再次注册监听。

    2. 服务端

    1. /**
    2. * @Description 服务动态上下线监控(服务端)
    3. */
    4. public class DistributeServer {
    5. private String connectString = "bigdata-hk-node1:2181,bigdata-hk-node2:2181,bigdata-hk-node3:2181";
    6. private int sessionTimeout = 2000;
    7. private ZooKeeper zk;
    8. // 启动前请先创建ZNODE:`create /servers "servers"`
    9. public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
    10. if(args==null||args.length<1){
    11. args=new String[]{"bigdata-hk-node3"};
    12. }
    13. DistributeServer server = new DistributeServer();
    14. // 1 获取zk连接
    15. server.getConnect();
    16. // 2 注册服务器到zk集群
    17. server.register(args[0]);
    18. // 3 启动业务逻辑(睡觉)
    19. server.business();
    20. }
    21. private void business() throws InterruptedException {
    22. Thread.sleep(Long.MAX_VALUE);
    23. }
    24. private void register(String hostname) throws KeeperException, InterruptedException {
    25. String server = zk.create("/servers/"+hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
    26. System.out.println(hostname +" is online") ;
    27. System.out.println(server) ;
    28. }
    29. private void getConnect() throws IOException {
    30. zk = new ZooKeeper(connectString, sessionTimeout, watchedEvent -> System.out.println("客户端初始化连接成功...."));
    31. }
    32. }

    3. 客户端

    1. /**
    2. * @Description 服务动态上下线监控(客户端)
    3. */
    4. public class DistributeClient {
    5. private String connectString = "bigdata-hk-node1:2181,bigdata-hk-node2:2181,bigdata-hk-node3:2181";
    6. private int sessionTimeout = 2000;
    7. private ZooKeeper zk;
    8. public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
    9. DistributeClient client = new DistributeClient();
    10. // 1 获取zk连接
    11. client.getConnect();
    12. // 2 监听/servers下面子节点的增加和删除
    13. client.getServerList();
    14. // 3 业务逻辑(睡觉)
    15. client.business();
    16. }
    17. private void business() throws InterruptedException {
    18. Thread.sleep(Long.MAX_VALUE);
    19. }
    20. private void getServerList() throws KeeperException, InterruptedException {
    21. List<String> children = zk.getChildren("/servers", true);
    22. ArrayList<String> servers = new ArrayList<>();
    23. for (String child : children) {
    24. byte[] data = zk.getData("/servers/" + child, false, null);
    25. servers.add(new String(data));
    26. }
    27. System.out.println(servers);
    28. }
    29. private void getConnect() throws IOException {
    30. zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
    31. @Override
    32. public void process(WatchedEvent watchedEvent) {
    33. try {
    34. System.out.println("获取最新服务器列表-----------------------------");
    35. getServerList();
    36. } catch (KeeperException e) {
    37. e.printStackTrace();
    38. } catch (InterruptedException e) {
    39. e.printStackTrace();
    40. }
    41. }
    42. });
    43. }
    44. }

    场景:分布式锁

    1. 实现思路

  • 实现方式1(推荐)

1.drawio.png

  • 实现方式2(不推荐)

2.drawio.png

2. 算法描述

3.drawio.png

3. 代码实现

1. 原生API

  1. /**
  2. * @Description 分布式锁(原生API)
  3. */
  4. public class DistributedLock {
  5. private String connectString = "bigdata-hk-node1:2181,bigdata-hk-node2:2181,bigdata-hk-node3:2181";
  6. private final int sessionTimeout = 2000;
  7. private final ZooKeeper zk;
  8. private CountDownLatch connectLatch = new CountDownLatch(1);
  9. private CountDownLatch waitLatch = new CountDownLatch(1);
  10. private String waitPath;
  11. private String currentMode;
  12. public static void main(String[] args) throws Exception {
  13. final DistributedLock lock1 = new DistributedLock("服务器1");
  14. final DistributedLock lock2 = new DistributedLock("服务器2");
  15. new Thread(() -> {
  16. try {
  17. lock1.zklock();
  18. System.out.println("服务器1 启动,获取到锁");
  19. int time=new Random().nextInt(8)+1;
  20. System.out.println("服务器1 恰饭大概耗时:"+time+"秒,请等待....");
  21. Thread.sleep(time * 1000);
  22. lock1.unZkLock();
  23. System.out.println("服务器1 释放锁");
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. }).start();
  28. new Thread(() -> {
  29. try {
  30. lock2.zklock();
  31. System.out.println("服务器2 启动,获取到锁");
  32. int time=new Random().nextInt(8)+1;
  33. System.out.println("服务器2 咪西大概耗时:"+time+"秒,请等待....");
  34. Thread.sleep(time * 1000);
  35. lock2.unZkLock();
  36. System.out.println("服务器2 释放锁");
  37. } catch (InterruptedException e) {
  38. e.printStackTrace();
  39. }
  40. }).start();
  41. }
  42. public DistributedLock(String clientName) throws IOException, InterruptedException, KeeperException {
  43. // 获取连接
  44. zk = new ZooKeeper(connectString, sessionTimeout, watchedEvent -> {
  45. // connectLatch 如果连接上zk 可以释放
  46. if (watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected) {
  47. connectLatch.countDown();
  48. }
  49. // waitLatch 需要释放
  50. if (watchedEvent.getType() == Watcher.Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)) {
  51. waitLatch.countDown();
  52. }
  53. });
  54. // 等待zk正常连接后,往下走程序
  55. connectLatch.await();
  56. System.out.println(clientName+"成功连接上zk集群!开始抢占分布式锁....");
  57. // 判断根节点/locks是否存在
  58. Stat stat = zk.exists("/locks", false);
  59. if (stat == null) {
  60. System.out.println("不存在/locks节点,正在创建中....");
  61. zk.create("/locks", "locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  62. }
  63. }
  64. // 对zk加锁
  65. public void zklock() {
  66. try {
  67. currentMode = zk.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
  68. // wait一小会, 让结果更清晰一些
  69. Thread.sleep(10);
  70. // 判断创建的节点是否是最小的序号节点,如果是获取到锁;如果不是,监听他序号前一个节点
  71. List<String> children = zk.getChildren("/locks", false);
  72. // 如果children 只有一个值,那就直接获取锁; 如果有多个节点,需要判断,谁最小
  73. if (children.size() == 1) {
  74. return;
  75. } else {
  76. Collections.sort(children);
  77. // 获取节点名称 seq-00000000
  78. String thisNode = currentMode.substring("/locks/".length());
  79. // 通过seq-00000000获取该节点在children集合的位置
  80. int index = children.indexOf(thisNode);
  81. // 判断
  82. if (index == -1) {
  83. System.out.println("数据异常");
  84. } else if (index == 0) {
  85. // 就一个节点,可以获取锁了
  86. return;
  87. } else {
  88. // 需要监听 他前一个节点变化
  89. waitPath = "/locks/" + children.get(index - 1);
  90. zk.getData(waitPath, true, new Stat());
  91. // 等待监听
  92. waitLatch.await();
  93. return;
  94. }
  95. }
  96. } catch (KeeperException e) {
  97. e.printStackTrace();
  98. } catch (InterruptedException e) {
  99. e.printStackTrace();
  100. }
  101. }
  102. // 解锁
  103. public void unZkLock() {
  104. // 删除节点
  105. try {
  106. zk.delete(this.currentMode, -1);
  107. } catch (InterruptedException e) {
  108. e.printStackTrace();
  109. } catch (KeeperException e) {
  110. e.printStackTrace();
  111. }
  112. }
  113. }

运行结果:

  1. 服务器1成功连接上zk集群!开始抢占分布式锁....
  2. 不存在/locks节点,正在创建中....
  3. 服务器2成功连接上zk集群!开始抢占分布式锁....
  4. 服务器1 启动,获取到锁
  5. 服务器1 恰饭大概耗时:2秒,请等待....
  6. 服务器2 启动,获取到锁
  7. 服务器2 咪西大概耗时:7秒,请等待....
  8. 服务器1 释放锁
  9. 服务器2 释放锁

2. Curator API

  1. /**
  2. * @Description 分布式锁(Curator)
  3. */
  4. public class DistributedLock {
  5. public static void main(String[] args) {
  6. // 创建分布式锁1
  7. InterProcessMutex lock1 = new InterProcessMutex(getCuratorFramework("服务器1"), "/locks");
  8. // 创建分布式锁2
  9. InterProcessMutex lock2 = new InterProcessMutex(getCuratorFramework("服务器2"), "/locks");
  10. new Thread(() -> {
  11. try {
  12. lock1.acquire();
  13. System.out.println("服务器1 获取到锁");
  14. lock1.acquire();
  15. System.out.println("服务器1 再次获取到锁");
  16. int time=new Random().nextInt(8)+1;
  17. System.out.println("服务器1 恰饭大概耗时:"+time+"秒,请等待....");
  18. Thread.sleep(time * 1000);
  19. lock1.release();
  20. System.out.println("服务器1 释放锁");
  21. lock1.release();
  22. System.out.println("服务器1 再次释放锁");
  23. } catch (Exception e) {
  24. e.printStackTrace();
  25. }
  26. }).start();
  27. new Thread(() -> {
  28. try {
  29. lock2.acquire();
  30. System.out.println("服务器2 获取到锁");
  31. lock2.acquire();
  32. System.out.println("服务器2 再次获取到锁");
  33. int time=new Random().nextInt(8)+1;
  34. System.out.println("服务器2 咪西大概耗时:"+time+"秒,请等待....");
  35. Thread.sleep(time * 1000);
  36. lock2.release();
  37. System.out.println("服务器2 释放锁");
  38. lock2.release();
  39. System.out.println("服务器2 再次释放锁");
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. }).start();
  44. }
  45. private static CuratorFramework getCuratorFramework(String clientName) {
  46. ExponentialBackoffRetry policy = new ExponentialBackoffRetry(3000, 3);
  47. CuratorFramework client = CuratorFrameworkFactory.builder().connectString("bigdata-hk-node1:2181,bigdata-hk-node2:2181,bigdata-hk-node3:2181")
  48. .connectionTimeoutMs(2000)
  49. .sessionTimeoutMs(2000)
  50. .retryPolicy(policy).build();
  51. // 启动客户端
  52. client.start();
  53. System.out.println(clientName+"成功连接上zk集群!开始抢占分布式锁....");
  54. return client;
  55. }
  56. }

运行结果:

  1. 服务器1成功连接上zk集群!开始抢占分布式锁....
  2. 服务器2成功连接上zk集群!开始抢占分布式锁....
  3. 服务器2 获取到锁
  4. 服务器2 再次获取到锁
  5. 服务器2 咪西大概耗时:3秒,请等待....
  6. 服务器2 释放锁
  7. 服务器2 再次释放锁
  8. 服务器1 获取到锁
  9. 服务器1 再次获取到锁
  10. 服务器1 恰饭大概耗时:2秒,请等待....
  11. 服务器1 释放锁
  12. 服务器1 再次释放锁

场景:HA

1. Hadoop HA

1. HDFS HA

1. 基本原理

Hadoop-2.0的HA机制官方介绍了有2种方式,一种是NFS(Network File System)方式,另外一种是QJM(Quorum Journal Manager)方式。
image.png
Hadoop-2.x之后,Clouera提出了QJM/Qurom Journal Manager,这是一个基于Paxos算法实现的HDFS HA方案,它给出了一种较好的解决思路和方案,示意图如下:
image.png

  1. 基本原理就是用2N+1台JN存储EditLog,每次写数据操作有大多数(>=N+1)返回成功时即认为该次写成功,数据不会丢失了。当然这个算法所能容忍的是最多有N台机器挂掉,如果多于N台挂掉,这个算法就失效了。这个原理是基于Paxos算法。
  2. 在HA架构里面SecondaryNameNode这个冷备角色已经不存在了,为了保持standby NN时时的与主Active NN的元数据保持一致,他们之间交互通过一系列守护的轻量级进程JournalNode。
  3. 任何修改操作在Active NN上执行时,JN进程同时也会记录修改log到至少半数以上的JN中,这时Standby NN监测到JN里面的同步log发生变化了会读取JN里面的修改log,然后同步到自己的的目录镜像树里面,如下图:

image.png
当发生故障时,Active的NN挂掉后,Standby NN会在它成为Active NN前,读取所有的JN里面的修改日志,这样就能高可靠的保证与挂掉的NN的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。

2. 详细配置

  1. 修改hdfs-site.xml配置文件。

    1. <!-- HDFS数据副本数,默认3副本:本节点+同机架节点+其他机架节点,一般不大于datanode的节点数,建议默认3副本-->
    2. <property>
    3. <name>dfs.replication</name>
    4. <value>2</value>
    5. </property>
    6. <!-- HDFS中启用权限检查配置-->
    7. <property>
    8. <name>dfs.permissions.enabled</name>
    9. <value>false</value>
    10. </property>
    11. <!--以下为Hadoop HA配置 -->
    12. <!--HDFS服务逻辑名称,需要和core-site.xml中的保持一致 -->
    13. <property>
    14. <name>dfs.nameservices</name>
    15. <value>ns</value>
    16. </property>
    17. <!-- ns下面有两个NameNode,分别是nn1,nn2 -->
    18. <property>
    19. <name>dfs.ha.namenodes.ns</name>
    20. <value>nn1,nn2</value>
    21. </property>
    22. <!-- nn1的RPC通信地址 -->
    23. <property>
    24. <name>dfs.namenode.rpc-address.ns.nn1</name>
    25. <value>bigdata-pro02-node1:8020</value>
    26. </property>
    27. <!-- nn1的http通信地址 -->
    28. <property>
    29. <name>dfs.namenode.http-address.ns.nn1</name>
    30. <value>bigdata-pro02-node1:50070</value>
    31. </property>
    32. <!-- nn2的RPC通信地址 -->
    33. <property>
    34. <name>dfs.namenode.rpc-address.ns.nn2</name>
    35. <value>bigdata-pro02-node2:8020</value>
    36. </property>
    37. <!-- nn2的http通信地址 -->
    38. <property>
    39. <name>dfs.namenode.http-address.ns.nn2</name>
    40. <value>bigdata-pro02-node2:50070</value>
    41. </property>
    42. <!-- 指定NameNode的元数据在JournalNode上的存放位置 -->
    43. <property>
    44. <name>dfs.namenode.shared.edits.dir</name>
    45. <value>qjournal://bigdata-pro02-node1:8485;bigdata-pro02-node2:8485;bigdata-pro02-node3:8485/ns</value>
    46. </property>
    47. <!-- 指定JournalNode在本地磁盘存放数据的位置,需创建 -->
    48. <property>
    49. <name>dfs.journalnode.edits.dir</name>
    50. <value>/opt/modules/hadoop-2.5.0/jn</value>
    51. </property>
    52. <!-- 开启NameNode失败自动切换,注意加.ns -->
    53. <property>
    54. <name>dfs.ha.automatic-failover.enabled.ns</name>
    55. <value>true</value>
    56. </property>
    57. <!-- 配置失败自动切换实现方式 -->
    58. <property>
    59. <name>dfs.client.failover.proxy.provider.ns</name>
    60. <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    61. </property>
    62. <!-- 配置隔离机制方法(HA功能的防脑裂方法),多个机制用换行分割,即每个机制暂用一行,sshfence / shell(/bin/true)-->
    63. <property>
    64. <name>dfs.ha.fencing.methods</name>
    65. <value>sshfence</value>
    66. </property>
    67. <!-- 配置sshfence隔离机制超时时间 -->
    68. <property>
    69. <name>dfs.ha.fencing.ssh.connect-timeout</name>
    70. <value>30000</value>
    71. </property>
    72. <!-- 使用sshfence隔离机制时需要ssh免登陆 -->
    73. <property>
    74. <name>dfs.ha.fencing.ssh.private-key-files</name>
    75. <value>/home/polaris/.ssh/id_rsa</value>
    76. </property>

    注:脑裂(split-brain),指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。

  2. 修改core-site.xml配置文件。

    1. <!-- Hadoop nameService逻辑名称,与hdfs-size.xml保持一致 -->
    2. <property>
    3. <name>fs.defaultFS</name>
    4. <value>hdfs://ns</value>
    5. </property>
    6. <!--WEB UI访问数据使用的用户名 -->
    7. <property>
    8. <name>hadoop.http.staticuser.user</name>
    9. <value>polaris</value>
    10. </property>
    11. <!-- Hadoop的临时目录,服务端参数,修改需重启。NameNode的Image/Edit目录依赖此配置 -->
    12. <property>
    13. <name>hadoop.tmp.dir</name>
    14. <value>/opt/modules/hadoop-2.5.0/tmp</value>
    15. </property>
    16. <!-- 指定zookeeper地址 -->
    17. <property>
    18. <name>ha.zookeeper.quorum</name>
    19. <value>bigdata-pro02-node1:2181,bigdata-pro02-node2:2181,bigdata-pro02-node3.kfk.com:2181</value>
    20. </property>
  3. 将修改的配置分发到其他节点。

    1. cd ${HADOOP_HOME}
    2. scp -r hdfs-site.xml polaris@bigdata-pro02-node2:${HADOOP_HOME}/etc/hadoop/hdfs-site.xml
    3. scp -r hdfs-site.xml polaris@bigdata-pro02-node3:${HADOOP_HOME}/etc/hadoop/hdfs-site.xml
    4. scp -r core-site.xml polaris@bigdata-pro02-node2:${HADOOP_HOME}/etc/hadoop/core-site.xml
    5. scp -r core-site.xml polaris@bigdata-pro02-node3:${HADOOP_HOME}/etc/hadoop/core-site.xml

    3. 自动故障转移测试

  4. 启动所有节点上面的ZooKeeper进程。

    1. cd /opt/modules/zookeeper-3.4.5/bin
    2. sh zkServer.sh start
  5. 启动所有节点上面的JournalNode进程。

    1. cd /opt/modules/hadoop-2.5.0/
    2. sbin/hadoop-daemon.sh start journalnode
  6. 在[nn1]上,对NameNode进行格式化,并启动。

    1. cd /opt/modules/hadoop-2.5.0/
    2. # NameNode 格式化(首次启动)
    3. bin/hdfs namenode -format
    4. # NameNode 格式化(非首次启动,同步Edits)
    5. bin/hdfs namenode -initializeSharedEdits
    6. # 格式化高可用,在zk上创建节点/hadoop-ha/ns
    7. bin/hdfs zkfc -formatZK
    8. # 启动NameNode,供其它NameNode同步元数据
    9. bin/hdfs namenode
  7. 在[nn2]上,同步nn1元数据信息。

    1. cd /opt/modules/hadoop-2.5.0/
    2. bin/hdfs namenode -bootstrapStandby
  8. nn2同步完数据后,在nn1上,按下ctrl+c来结束NameNode进程。然后关闭所有节点上面的JournalNode进程。

    1. cd /opt/modules/hadoop-2.5.0/
    2. sbin/hadoop-daemon.sh stop journalnode
  9. 一键启动hdfs所有相关进程。

    1. cd /opt/modules/hadoop-2.5.0/
    2. sbin/start-dfs.sh
    3. # 在各个NameNode节点上启动DFSZK Failover Controller,先在那台机器启动,那个机器的NameNode就是Active NameNode
    4. sbin/hadoop-daemon.sh start zkfc

    hdfs启动之后,kill其中Active状态的NameNode,检查另外一个NameNode是否会自动切换为Active状态。同时通过命令上传文件至hdfs,检查hdfs是否可用。

    2. YARN HA

    1. 基本原理

    ResourceManager HA由一对Active,Standby结点构成,通过RMStateStore存储内部数据和主要应用的数据及标记。目前支持的可替代的RMStateStore实现有:基于内存的MemoryRMStateStore,基于文件系统的FileSystemRMStateStore,及基于zookeeper的ZKRMStateStore。 ResourceManager HA的架构模式同NameNode HA的架构模式基本一致,数据共享由RMStateStore,而ZKFC成为 ResourceManager进程的一个服务,非独立存在。

    2. 详细配置

  10. 修改mapred-site.xml配置文件。

    1. <!-- 配置MapReduce运行环境,yarn/yarn-tez -->
    2. <property>
    3. <name>mapreduce.framework.name</name>
    4. <value>yarn</value>
    5. </property>
  11. 修改yarn-site.xml配置文件。 ```xml

    yarn.log-aggregation-enable true yarn.log-aggregation.retain-seconds 10000 yarn.nodemanager.aux-services mapreduce_shuffle

yarn.resourcemanager.ha.enabled true

yarn.resourcemanager.cluster-id rs

yarn.resourcemanager.ha.rm-ids rm1,rm2

yarn.resourcemanager.hostname.rm1 bigdata-pro02-node1

yarn.resourcemanager.hostname.rm2 bigdata-pro02-node2

yarn.resourcemanager.zk.state-store.address bigdata-pro02-node1:2181,bigdata-pro02-node2:2181, bigdata-pro02-node3:2181

yarn.resourcemanager.zk-address bigdata-pro02-node1:2181,bigdata-pro02-node2:2181, bigdata-pro02-node3:2181

yarn.resourcemanager.recovery.enabled true

yarn.resourcemanager.store.class org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore

yarn.resourcemanager.webapp.address bigdata-pro02-node1:8088

  1. 3. 将修改的配置分发到其他节点。
  2. ```bash
  3. cd ${HADOOP_HOME}
  4. scp -r yarn-site.xml polaris@bigdata-pro02-node2:${HADOOP_HOME}/etc/hadoop/yarn-site.xml
  5. scp -r yarn-site.xml polaris@bigdata-pro02-node3:${HADOOP_HOME}/etc/hadoop/yarn-site.xml
  6. scp -r mapred-site.xml polaris@bigdata-pro02-node2:${HADOOP_HOME}/etc/hadoop/mapred-site.xml
  7. scp -r mapred-site.xml polaris@bigdata-pro02-node3:${HADOOP_HOME}/etc/hadoop/mapred-site.xml

3. 自动故障转移测试

  1. 在rm1节点上启动yarn服务(先启动zk、hdfs-ha)。

    1. cd /opt/modules/hadoop-2.5.0/
    2. sbin/start-yarn.sh
  2. 在rm2节点上启动ResourceManager服务。

    1. cd /opt/modules/hadoop-2.5.0/
    2. sbin/yarn-daemon.sh start resourcemanager
  3. 浏览器查看yarn。

Web UI:http://bigdata-pro02-node1:8088、http://bigdata-pro02-node2:8088

  1. 查看ResourceManager主备节点状态。

    1. cd /opt/modules/hadoop-2.5.0/
    2. # bigdata-pro02-node1节点上执行
    3. bin/yarn rmadmin -getServiceState rm1
    4. # bigdata-pro02-node2节点上执行
    5. bin/yarn rmadmin -getServiceState rm2
  2. Hadoop集群测试WordCount运行。

    1. cd /opt/modules/hadoop-2.5.0/
    2. bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar wordcount /tmp/input /tmp/output

    3. HBase HA

    为了增加HBase集群的可用性,可以为HBase增加多个backup master。当master挂掉后,backup master可以自动接管整个HBase的集群。(配置好ZK后,不配置backup-masters,而直接在启动主节点HMaster后,再启动其它节点的HMaster,即可自动加入到备份HMaster列表中)。 ```bash cd ${HBASE_HOME}/conf vi backup-masters

##### 内容如下

bigdata-pro02-node2 ```