Hadoop————Zookeeper强化

1、Zookeeper的作用

1.管理大量主机的协同服务。
2.分布式应用,实现分布式读写技术。
3.zk提供的服务:

Naming service              //按名称区分集群中的节点.
Configuration management    //对加入节点的最新化处理。
Cluster management          //实时感知集群中节点的增减.
Leader election             //leader选举
Locking and synchronization service //修改时锁定数据,实现容灾.
Highly reliable data registry       //节点宕机数据也是可用的。

2、zk安装(单机版,s201)
1.jdk

2.下载zookeeper-3.4.9.tar.gz

3.tar开

4.符号连接环境变量

$>ln -s zookeeper-3.4.9 zk

5.配置zk,复制zoo.cfg.sample–>zoo.cfg

[zk/conf/zoo.conf]
    # The number of milliseconds of each tick
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/home/centos/zookeeper
    clientPort=2181

6.启动zk服务器

$>bin/zkServer.sh start

7.验证zk

$>netstat -anop | grep 2181

8.启动客户端连接到服务器

$>zkCli.sh -server s201:2181   //进入zk命令行
$zk]help                       //查看帮助
$zk]quit                       //退出
$zk]create /a tom              //
$zk]get /a                     //查看数据
$zk]ls /                       //列出节点
$zk]set /a tom                 //设置数据
$zk]delete /a                  //删除一个节点
$zk]rmr /a                     //递归删除所有节点。

9.通过api访问zk

添加依赖pom.xml

<?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>

            <groupId>com.it18zhang</groupId>
            <artifactId>ZooKeeperDemo</artifactId>
            <version>1.0-SNAPSHOT</version>

            <dependencies>
                <dependency>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                    <version>3.4.9</version>
                </dependency>

                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.11</version>
                </dependency>
            </dependencies>
        </project>

API访问操作zk

package cn.ctgu.zktest;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Test;

import java.io.IOException;
import java.util.List;


public class TestZK {
    @Test
    public void ls() throws Exception {
        ZooKeeper zk=new ZooKeeper("172.25.11.200:2181",5000,null);
        List<String> list=zk.getChildren("/",null);
        for(String s:list){
            System.out.println(s);
        }
    }
    //递归输出zk系统目录
    @Test
    public void lsAll() throws Exception {
       ls("/");
    }
    public void ls(String path) throws Exception {
        System.out.println(path);
        ZooKeeper zk=new ZooKeeper("172.25.11.200:2181",5000,null);
        List<String> list=zk.getChildren(path,null);
        if(list==null||list.isEmpty()){
            return;
        }
        for(String s:list){
            //先输出孩子
            if(path.equals("/")){
                ls(path+s);
            }else{
                ls(path+"/"+s);
            }

        }
    }
    /*
    *
    * 设置数据
    *
    * */
    @Test
    public void setData() throws Exception {
        ZooKeeper zk=new ZooKeeper("172.25.11.200:2181",5000,null);
        //当版本号对应不上的时候则不能设置,即为之前的版本号
        zk.setData("/a","tomaslee".getBytes(),0);
    }
    /*
    *
    * 创建临时节点
    *
    * */
    @Test
    public void reateEmphoral() throws Exception {
        ZooKeeper zk=new ZooKeeper("172.25.11.200:2181",5000,null);
        zk.create("/b/b3","tom".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("hello");
    }
    /*
    *
    * 使用观察者对象
    *
    * */
    @Test
    public void testWatch() throws Exception {
        final ZooKeeper zk=new ZooKeeper("172.25.11.200:2181",5000,null);
        Stat st=new Stat();

        Watcher w=null;
        w=new Watcher(){
            //回调匿名函数
            public void process(WatchedEvent event){
                try {
                    System.out.println("数据改了!");
                    zk.getData("/a",this,null);//获取数据,注册观察者,当回调匿名函数的过程中数据再次改变了则又重新调用回调函数
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        };
        byte[]data=zk.getData("/a",w,st);//获取数据,同时注册一个观察者,当数据改变了立刻调用匿名函数
        System.out.println(new String(data));
        while(true){
            Thread.sleep(1000);
        }
    }



}

3、Zookeeper架构

3.1.Client
从server获取信息,周期性发送数据给server,表示自己还活着。
client连接时,server回传ack信息。
如果client没有收到reponse,自动重定向到另一个server.
3.2.Server
zk集群中的一员,向client提供所有service,回传ack信息给client,表示自己还活着。
3.3.ensemble
一组服务器,最小节点数是3,即zookeeper也是一个集群,通过这个集群实现协同服务。
3.4.Leader
如果连接的节点失败,自动恢复,zk服务启动时,完成leader选举。
3.5.Follower
追寻leader指令的节点。
3.5 znode

zk中的节点,维护了stat,即状态信息,由Version number, Action control list (ACL), Timestamp,Data length.构成.

data version //数据写入的过程变化
ACL //action control list,

节点类型

1.持久节点
client结束,还存在。

2.临时节点
在client活动时有效,断开自动删除。临时节点不能有子节点。
leader推选时使用。

3.序列节点
在节点名之后附加10个数字,主要用于同步和锁.
3.6 Session
Session中的请求以FIFO执行,一旦client连接到server,session就建立了。sessionid分配client。
client以固定间隔向server发送心跳,表示session是valid的,zk集群如果在超时时候,没有收到心跳,判定为client挂了,与此同时,临时节点被删除。
3.7 Watches
观察。
client能够通过watch机制在数据发生变化时收到通知。
client可以在read节点时设置观察者。watch机制会发送通知给注册的客户端。观察模式只触发一次。session过期,watch机制删除了。
4、zk工作流程

zk集群启动后,client连接到其中的一个节点,这个节点可以leader,也可以follower。
连通后,node分配一个id给client,发送ack信息给client。
如果客户端没有收到ack,连接到另一个节点。
client周期性发送心跳信息给节点保证连接不会丢失。

如果client读取数据,发送请求给node,node读取自己数据库,返回节点数据给client.

如果client存储数据,将路径和数据发送给server,server转发给leader。
leader再补发请求给所有follower。只有大多数(超过半数)节点成功响应,则写操作成功。
5、leader推选过程(最小号选举法)

1.所有节点在同一目录下创建临时序列节点。
2.节点下会生成/xxx/xx000000001等节点。
3.序号最小的节点就是leader,其余就是follower.
4.每个节点会观察小于自己节点的主机,例如000000002节点观察000000001节点。(通过注册观察者机制)
5.如果leader挂了,对应znode删除了。
6.观察者收到通知。

6、配置完全分布式zk集群

6.1 没有使用Zookeeper的HA配置

HA(high availability)高可用配置
两个名称节点,一个active(激活态),一个是standby(slave待命),slave节点维护足够多状态以便于容灾。和客户端交互的节点为active节点,standby不交互.两个节点都和JN守护进程构成组进行通信。
数据节点配置两个名称节点,分别向两个名称节点报告各自的信息。同一时刻只能有一个激活态名称节点。

脑裂:两个节点都是激活态。
为防止脑裂,JNs只允许同一时刻只有一个节点向其写数据。容灾发生时,成为active节点的namenode接管向jn的写入工作。

硬件资源
名称节点: 硬件配置相同。
JN节点:轻量级进程,至少3个节点,允许挂掉的节点数 (n - 1) / 2,不需要再运行辅助名称节点(即secondarynamenode)。

配置细节

0.s201和s206具有完全一致的配置,尤其是ssh.

1.配置nameservice

[hdfs-site.xml]
<property>
    <name>dfs.nameservices</name>
    <value>mycluster</value>
</property>

2.dfs.ha.namenodes.[nameservice ID]

[hdfs-site.xml]
<!-- myucluster下的名称节点两个id -->
<property>          
    <name>dfs.ha.namenodes.mycluster</name>
    <value>nn1,nn2</value>
</property>

3.dfs.namenode.rpc-address.[nameservice ID].[name node ID]

[hdfs-site.xml]
配置每个nn的rpc地址。
<property>
    <name>dfs.namenode.rpc-address.mycluster.nn1</name>
    <value>s201:8020</value>
</property>
<property>
    <name>dfs.namenode.rpc-address.mycluster.nn2</name>
    <value>s206:8020</value>
</property>

4.dfs.namenode.http-address.[nameservice ID].[name node ID]

配置webui端口
[hdfs-site.xml]
<property>
        <name>dfs.namenode.http-address.mycluster.nn1</name>
        <value>s201:50070</value>
</property>
<property>
        <name>dfs.namenode.http-address.mycluster.nn2</name>
        <value>s206:50070</value>
</property>

5.dfs.namenode.shared.edits.dir

名称节点共享编辑目录.
[hdfs-site.xml]
<property>
            <name>dfs.namenode.shared.edits.dir</name>
            <value>qjournal://s202:8485;s203:8485;s204:8485/mycluster</value>
</property>

6.dfs.client.failover.proxy.provider.[nameservice ID]

java类,client使用它判断哪个节点是激活态。
[hdfs-site.xml]
<property>
            <name>dfs.client.failover.proxy.provider.mycluster</name>
            <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

7.dfs.ha.fencing.methods

脚本列表或者java类,在容灾保护激活态的nn,即只维护一个nn,避免脑裂。
        [hdfs-site.xml]
        <property>
            <name>dfs.ha.fencing.methods</name>
            <value>
                    sshfence
                    shell(/bin/true)
            </value>
        </property>

        <property>
            <name>dfs.ha.fencing.ssh.private-key-files</name>
            <value>/home/centos/.ssh/id_rsa</value>
        </property>

8.fs.defaultFS

配置hdfs文件系统名称服务。
[core-site.xml]
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://mycluster</value>
</property>

9.dfs.journalnode.edits.dir

配置JN存放edit的本地路径。
[hdfs-site.xml]
<property>
            <name>dfs.journalnode.edits.dir</name>
            <value>/home/centos/hadoop/journal</value>
</property>

部署细节
1.在jn节点分别启动jn进程(s202,s203,s204)

$>hadoop-daemon.sh start journalnode

2.启动jn之后,在两个NN之间进行disk元数据同步
a)如果是全新集群,先format文件系统,只需要在一个nn上执行。

[s201]
$>hadoop namenode -format

b)如果将非HA集群转换成HA集群,复制原NN的metadata到另一个nn.
1.步骤一

[s201]
$>scp -r /home/centos/hadoop/dfs centos@s206:/home/centos/hadoop/

2.步骤二
在新的nn(未格式化的nn)上运行一下命令,实现待命状态引导。

[s206]
$>hdfs namenode -bootstrapStandby      //需要s201为启动状态,提示是否格式化,选择N.

3)在一个NN上执行以下命令,完成edit日志到jn节点的传输。

$>hdfs namenode -initializeSharedEdits
                #查看s202,s203是否有edit数据.

4)启动所有节点.

[s201]
$>hadoop-daemon.sh start namenode      //启动名称节点
$>hadoop-daemons.sh start datanode     //启动所有数据节点

[s206]
$>hadoop-daemon.sh start namenode      //启动名称节点

HA管理

$>hdfs haadmin -transitionToActive nn1             //切成激活态
$>hdfs haadmin -transitionToStandby nn1                //切成待命态
$>hdfs haadmin -transitionToActive --forceactive nn2//强行激活
$>hdfs haadmin -failover nn1 nn2                   //模拟容灾演示,从nn1切换到nn2,只能手动容灾,不能自动容灾

6.2 使用zk配置完全分布式集群,自动容灾

节点安排
这里写图片描述
这里写图片描述

1.挑选3台主机
s201 ~ s203
2.每台机器都安装zk
tar
环境变量

3.配置zk配置文件

s201 ~ s203
[/soft/zk/conf/zoo.cfg]
...
dataDir=/home/centos/zookeeper

server.1=s201:2888:3888
server.2=s202:2888:3888
server.3=s203:2888:3888

4.在每台主机的/home/centos/zookeeper中添加myid,内容分别是1,2,3

[s201]
$>echo 1 > /home/centos/zookeeper/myid
[s202]
$>echo 2 > /home/centos/zookeeper/myid
[s203]
$>echo 3 > /home/centos/zookeeper/myid

5.启动服务器集群

$>zkServer.sh start
        ...

6.查看每台服务器的状态

$>zkServer.sh status

7.修改zk的log目录

部署细节

在配置了上面的HA的前提下进行如下配置使得zk实现自动容灾:

1.停掉hadoop的所有进程
2.删除所有节点的日志和本地数据.
3.改换hadoop符号连接为ha,即切换到上面的HA模式下
4.登录每台JN节点主机,启动JN进程.

[s202-s204]
$>hadoop-daemon.sh start journalnode

5.登录其中一个NN,格式化文件系统(s201)

$>hadoop namenode -format

6.复制201目录的下nn的元数据到s206

$>scp -r ~/hadoop/* centos@s206:/home/centos/hadoop

7.在未格式化的NN(s206)节点上做standby引导.
7.1)需要保证201的NN启动

$>hadoop-daemon.sh start namenode

7.2)登录到s206节点,做standby引导.

$>hdfs namenode -bootstrapStandby

7.3)登录201,将s201的edit日志初始化到JN节点。

$>hdfs namenode -initializeSharedEdits

8.启动所有数据节点.

$>hadoop-daemons.sh start datanode

9.登录到206,启动NN

$>hadoop-daemon.sh start namenode

10.查看webui

http://s201:50070/
http://s206:50070/

11.自动容灾

11.1)介绍
自动容灾引入两个组件,zk quarum + zk容灾控制器(ZKFC)。
运行NN的主机还要运行ZKFC进程,主要负责:
a.健康监控
b.session管理
c.选举

11.2)部署容灾
a.停止所有进程

$>stop-all.sh

b.配置hdfs-site.xml,启用自动容灾.

[hdfs-site.xml]
<property>
    <name>dfs.ha.automatic-failover.enabled</name>
    <value>true</value>
</property>

c.配置core-site.xml,指定zk的连接地址.

<property>
            <name>ha.zookeeper.quorum</name>
            <value>s201:2181,s202:2181,s203:2181</value>
</property>

d.分发以上两个文件到所有节点。

12.登录其中的一台NN(s201),在ZK中初始化HA状态

$>hdfs zkfc -formatZK

13.启动hdfs进程.

$>start-dfs.sh

14.测试自动容在(206是活跃节点)

$>kill -9

6.3 配置RM的HA自动容灾

1.配置yarn-site.xml

<property>
            <name>yarn.resourcemanager.ha.enabled</name>
            <value>true</value>
        </property>
        <property>
            <name>yarn.resourcemanager.cluster-id</name>
            <value>cluster1</value>
        </property>
        <property>
            <name>yarn.resourcemanager.ha.rm-ids</name>
            <value>rm1,rm2</value>
        </property>
        <property>
            <name>yarn.resourcemanager.hostname.rm1</name>
            <value>s201</value>
        </property>
        <property>
            <name>yarn.resourcemanager.hostname.rm2</name>
            <value>s206</value>
        </property>
        <property>
            <name>yarn.resourcemanager.webapp.address.rm1</name>
            <value>s201:8088</value>
        </property>
        <property>
            <name>yarn.resourcemanager.webapp.address.rm2</name>
            <value>s206:8088</value>
        </property>
        <property>
            <name>yarn.resourcemanager.zk-address</name>
            <value>s201:2181,s202:2181,s203:2181</value>
        </property>

2.使用管理命令

//查看状态
$>yarn rmadmin -getServiceState rm1
//切换状态到standby
$>yarn rmadmin -transitionToStandby rm1

3.启动yarn集群

$>start-yarn.sh

4.hadoop配置了HA默认没有启动两个resourcemanager,需要手动启动另外一个

$>yarn-daemon.sh start resourcemanager

5.查看webui
6.做容灾模拟.

kill -9

猜你喜欢

转载自blog.csdn.net/jorocco/article/details/80778962