精华内容
下载资源
问答
  • HBase集群搭建实验(2)_伪分布式部署(使用内置ZooKeeper
    千次阅读
    2020-01-16 12:29:36

     HBase伪分布式模式
    1)HBase使用HDFS存储数据,所有进程运行在同一个节点上,不同的HBase或ZooKeeper守护进程运行在不同的JVM(Java Virtual Machine)中

    2)使用HBase内置的ZooKeeper
    3)比较适用于在硬件配置一般的用于开发的计算机上运行,适用于HBase的开发和测试环境

     

    实验前提:HBase伪分布式部署依赖于Hadoop伪分布式部署,本实验紧接Hadoop伪分布式实验,在Hadoop伪分布式部署完成并运行成功的基础上,继续进行Hbase伪分布式部署实验

    实验目标:单台Linux虚拟机主机上部署伪分布式数据库HBase ,用于教学演示

    实验环境:    虚拟机VirtualBox     操作系统 Centos7    Hadoop版本  hadoop-2.6.0-cdh5.7.0    Hbase版本 hbase-1.2.0-cdh5.7.0.tar.gz    由于HBase依赖于HDFS,所以选择安装包版本时必须注意HBase和Hadoop的版本兼容性,官方发布的HBase各版本对JDK和Hadoop各版本的支持情况参考(版本兼容性):https://blog.csdn.net/e_wsq/article/details/81365029
    集群规划:  无需复制虚拟机,直接利用Hadoop伪分布式的单台主机hadoop完成Hbase伪分布式部署

    主机IP主机名集群角色(进程名称)
    192.168.56.20hadoopNameNode DataNode SecondaryNameNode
    HMaster HRegionServer
    HQuorumPeer(HBase自带的ZooKeeper进程)

    〇 首先要部署完成并运行成功Hadoop伪分布式集群

    1)启动伪分布式集群中的单台主机hadoop

    2)在win7用XSHELL远程登录Linux,注意VirtualBox主机网络管理器的虚拟网卡IP(192.168.56.1)地址和虚拟机Linux处于一个网段

    3)上传HBase安装包到Linux的/root目录,解压缩hbase-1.2.0-cdh5.7.0.tar.gz安装包到指定目录/usr/local

    tar -zxvf /root/hbase-1.2.0-cdh5.7.0.tar.gz -C /usr/local/        解压缩到/usr/local目录

    4)设置HBase环境变量并使之生效

    vi /etc/profile   在配置文件profile的末尾增加以下内容:

    # hbase
    export HBASE_HOME=/usr/local/hbase-1.2.0-cdh5.7.0
    export PATH=$PATH:$HBASE_HOME/bin

    执行source /etc/profile命令使得HBase环境变量生效

    5)关闭防火墙firewall和SeLinux

    执行关闭防火墙命令 systemctl disable firewalld      执行关闭SeLinux命令 setenforce 0 

    6)检查hadoop主机到自己的SSH免密登录(特别重要)

    执行ssh hadoop命令,检查免密登录是否成功,免密登录成功后,必须输入exit退出并返回原会话,以免搞混

    7)修改HBase的配置文件(关键步骤)

    cd /usr/local/hbase-1.2.0-cdh5.7.0/conf    切换到HBase的配置文件所在目录

    a)先修改配置文件hbase-env.sh

    vi hbase-env.sh 修改以下配置参数:

    export JAVA_HOME=/usr/local/java/jdk1.8

    export HBASE_MANAGES_ZK=true                # 使用HBase内置的Zookeeper!!!

    执行source hbase-env.sh命令使得HBase配置参数生效

    b)修改配置文件hbase-site.xml

    vi hbase-site.xml修改以下参数:

    在<configuration> </configuration>之间增加蓝色字体配置参数

    <configuration>
      <property>
        <name>hbase.rootdir</name>
        <value>hdfs://hadoop:8020/hbase</value>
      </property>
      <property>
        <name>hbase.zookeeper.property.dataDir</name>
        <value>/root/hbase/zookeeper</value>
      </property>
      <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
      </property>

    <property>
      <name>hbase.zookeeper.quorum</name>
      <value>hadoop</value>
    </property>

    </configuration>

    参数说明:

    hbase.cluster.distributed:HBase群集的模式,对于单机模式值为false,对于伪分布式和完全分布式模式值为true。如果为false,将在同一个JVM中运行所有HBase和ZooKeeper守护进程

    hbase.rootdir:用于指定HBase数据在HDFS的存储路径

    hbase.zookeeper.property.dataDir:用于指定HBase自带的ZooKeeper存储数据的本地路径

    c)修改regionservers文件

    vi regionservers

    删除原有行,新添加一行:

    hadoop

    8)创建ZooKeeper存放数据的目录

    cd /root 切换到root目录

    执行命令mkdir -p /root/hbase/zookeeper 在root目录下创建两级子目录hbase/zookeeper

    路径/root/hbase/zookeeper和hbase-site.xml文件中的hbase.zookeeper.property.dataDir参数值相同

    注意:经过实际测试发现,以上三级子目录zookeeper 可以不事先创建,只需要在/root目录下执行mkdir hbase命令创建二级子目录hbase即可,启动HBase时会自动创建三级子目录zookeeper

    9)启动HDFS

    执行start-dfs.sh脚本命令启动HDFS

    10)启动HBase

    执行start-hbase.sh脚本命令启动HBase

    11)执行java进程查看命令jps,hadoop主机出现以下进程,说明HDFSHBase自带的ZooKeeper以及HBase都已启动成功:

    [root@hadoop ~]# jps
    3985 Jps
    3075 HRegionServer
    2276 DataNode
    2184 NameNode

    2936 HMaster
    2860 HQuorumPeer
    2462 SecondaryNameNode

    12)在win7下,用chrome浏览器访问HBase自带的web配置网站 http://192.168.56.20:60010 ,能出现如下页面说明访问成功:

    14)测试一下HBase是否成功连接HDFS

    测试方法:如果HBase成功连接HDFS,会在HDFS上创建目录路径/hbase

    执行hadoop fs -ls /命令,检查HDFS根目录下是否存在hbase子目录

    15)执行命令hbase shell进入hbase的shell命令行环境

    16)HBase Shell命令的简单测试

      执行命令create 'testTable', 'testFamily'     创建一张表testTable,包含一个列族testFamily 

     执行命令list  列出HBase中的所有表

    执行命令describe 'testTable'   描述表testTable的属性信息

    更多相关内容
  • 大数据技术基础实验报告-Zookeeper的安装配置和应用实践
  • 部署全分布模式Hadoop集群 实验报告一、实验目的 1. 熟练掌握 Linux 基本命令。 2. 掌握静态 IP 地址的配置、主机名和域名映射的修改。 3. 掌握 Linux 环境下 Java 的安装、环境变量的配置、Java 基本命令的使用。 ...
  • ZooKeeper分布式协调服务)使用介绍

    多人点赞 热门讨论 2021-11-08 21:05:22
    ZooKeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护...ZooKeeper 可以用于实现分布式系统中常见的发布/订阅、负载均衡、命令服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

    一、ZooKeeper 简介

    ZooKeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护。ZooKeeper 可以用于实现分布式系统中常见的发布/订阅、负载均衡、命令服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。 它具有以下特性:

    • 顺序一致性: 来自客户端的更新操作将会按照顺序被应用;
    • 原子性: 即要么全部更新成功,要么要不更新失败,没有部分的结果;
    • 统一的系统镜像: 即不管客户端连接的是哪台服务器,都能看到同样的服务视图(也就是无状态的)
    • 可靠性: 一旦写入操作被执行,那么这个状态将会被持久化,直到其它客户端的修改生效。
    • 实时性: 一旦一个事务被成功应用,ZooKeeper 可以保证客户端立即读取到这个事务变更后的最新状态的数据。

    1.ZooKeeper 设计目标

    • ZooKeeper 致力于为那些高吞吐的大型分布式系统提供一个高性能、高可用、且具有严格顺序访问控制能力的分布式协调服务。

    1)简单的数据模型:

    • ZooKeeper 通过树形结构来存储数据,它由一系列被称为 ZNode 的数据节点组成,类似于常见的文件系统;
    • 不过和常见的文件系统不同,ZooKeeper 将数据全量存储在内存中,以此来实现高吞吐,减少访问延迟。

    2)可配置 Cluster:

    • 为了保证高可用,最好是以集群形态部署 ZooKeeper,这样只要集群中大部分机器是可用的,那么 ZooKeeper 本身仍然可用。

    在这里插入图片描述
    上图中每一个 Server 代表一个安装 ZooKeeper 服务的服务器,组成 ZooKeeper 服务的服务器都会在内存中维护当前的服务器状态,并且每台服务器间都保持着通信。并通过 Zab 协议来保持数据的一致性。

    3)顺序访问:

    • 对于来自客户端的每个更新请求,ZooKeeper 都会分配一个全局唯一的递增 ID,这个 ID 决定了所有事务操作的先后顺序。

    4)高性能高可用

    • ZooKeeper 将数据全量存储在内存中以保持高性能,并通过服务集群来实现高可用;
    • 由于 ZooKeeper 的所有更新和删除都是基于事务的,所以其在读多写少的应用场景中有着很高的性能表现。

    2.核心概念

    Cluster 角色:

    角色作用
    Leader提供读写服务,并维护集群状态(经过选举产生)
    Follower提供读写服务,并定期向 Leader 汇报自己的节点状态(同时也参加 过半写成功 的策略和 Leader 的选举)
    OBServer提供读写服务,并定期向 Leader 汇报自己的节点状态(因为不参加策略和选举,所以可以在不影响写性能的情况下提升集群的读性能)

    1)Session 会话

    当 Client 通过 TCP 长连接 连接到 ZooKeeper 服务器时,Session 便开始建立连接,并通过 tickTime(心跳检测)机制来保持有效的会话状态。通过这个连接,Client 可以发送请求并接收响应,同时也可以接收到 Watch 事件的通知。

    另外,当由于网络故障或者 Client 主动断开等原因,导致连接断开,此时只要在会话超时时间之内重新建立连接,则之间创建的会话依然有效。(这个取决于 tickTime 配置)

    2)数据节点

    ZooKeeper 数据模型是由一系列基本数据单元 ZNode(数据节点)组成的节点树,其中根节点为 /(每个节点上都会保存自己的数据和节点信息);ZooKeeper 中的节点可以分为两大类:

    • 持久节点: 节点一旦创建,除非被主动删除,否则一直存在。
    • 临时节点: 一旦创建该节点的客户端会话(Session)失效,则所有该客户端创建的临时节点都会被删除。

    3)Watcher

    ZooKeeper 中一个常用的功能是 Watcher(事件监听器),它允许用户在指定节点上针对感兴趣的事件注册监听,当事件发生时,监听器会被触发,并将事件推送到客户端。该机制是 ZooKeeper 实现分布式协调服务的重要特性。

    4)ACL

    ZooKeeper 采用 ACL(Access Control Lists)策略来进行权限控制,类似于 Unix 文件系统的控制权限:

    命令作用
    create可以进行创建操作
    read可以进行查看操作
    write可以对创建的内容进行写入操作
    delete可以进行删除操作
    admin可以进行配置权限操作

    3.Zab 协议介绍

    • Zab(ZooKeeper Atomic Broadcast 原子广播)协议是为分布式协调服务 ZooKeeper 专门设计的一种 支持崩溃恢复的原子广播协议;
    • 在 ZooKeeper 中,主要依赖 Zab 协议来实现分布式数据一致性;
    • 基于 Zab 协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本间的数据一致性。

    二、ZooKeeper Cluster 安装

    准备工作:

    主机名操作系统IP 地址
    ZooKeeperCentOS 7.4192.168.1.1
    安装 JDK:下载地址(需要创建 Oracle 账号)
    [root@ZooKeeper ~]# ls
    anaconda-ks.cfg  jdk-8u181-linux-x64.tar.gz
    [root@ZooKeeper ~]# tar zxf jdk-8u181-linux-x64.tar.gz 
    [root@ZooKeeper ~]# ls
    anaconda-ks.cfg  jdk1.8.0_181  jdk-8u181-linux-x64.tar.gz
    [root@ZooKeeper ~]# mv jdk1.8.0_181 /usr/local/java
    [root@ZooKeeper ~]# cat <<"END" >> /etc/profile
    export JAVA_HOME=/usr/local/java
    export PATH=$PATH:$JAVA_HOME/bin
    END
    [root@ZooKeeper ~]# source /etc/profile
    [root@ZooKeeper ~]# java -version
    

    在这里插入图片描述

    1.安装 ZooKeeper

    [root@ZooKeeper ~]# wget http://dlcdn.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz
    [root@ZooKeeper ~]# ls
    anaconda-ks.cfg  apache-zookeeper-3.6.3-bin.tar.gz  jdk-8u181-linux-x64.tar.gz
    [root@ZooKeeper ~]# tar zxf apache-zookeeper-3.6.3-bin.tar.gz
    [root@ZooKeeper ~]# mv apache-zookeeper-3.6.3-bin /usr/local/zookeeper
    [root@ZooKeeper ~]# mkdir /usr/local/zookeeper/data
    [root@ZooKeeper ~]# cat <<END >> /usr/local/zookeeper/conf/zoo.cfg
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/usr/local/zookeeper/data
    clientPort=2181
    END
    

    注解:

    • tickTime:Client 和服务器间的通信会话限制(相当于健康检查,tickTime 的时间为 ms (1s = 1000ms)
    • initLimit:Leader 和 Follower 间初始通信限制。
    • syncLimit:Leader 和 Follower 间同步通信限制(当响应时间超于 syncLimit * tickTime 时,Leader 便会将 Follower 进行移除)
    • dataDir:此目录用于存放保存在内存数据库中的快照信息(当未配置 dataLogDir 参数时,日志信息也会存放到此目录)
    • clientPort:ZooKeeper 监听的端口,用于客户端连接使用。

    启动 ZooKeeper

    [root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start						# 启动
    [root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh status						# 查看状态
    

    在这里插入图片描述
    连接到 ZooKeeper

    [root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
    Welcome to ZooKeeper!
    JLine support is enabled
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
    [zk: 127.0.0.1:2181(CONNECTED) 0] 
    
    • 当连接成功后,系统会输出 ZooKeeper 的相关配置信息和相关环境,并在屏幕上输出 Welcome to ZooKeeper! 等信息。

    2.使用 Golang 连接 ZooKeeper 的 API 接口

    [root@ZooKeeper ~]# git clone https://github.com/samuel/go-zookeeper.git
    [root@ZooKeeper ~]# mv go-zookeeper /usr/local/go/src/
    
    package main
    import (
        "fmt"
        "time"
        "go-zookeeper/zk"
    )
    func main() {
        Hosts := []string{"192.168.1.1:2181"}
        conn, _, err := zk.Connect(Hosts,time.Second * 5)
        defer conn.Close()
        if err != nil {
            fmt.Println(err)
            return
        }
    }
    

    在这里插入图片描述
    通过 Golang 实现对 ZooKeeper 的增删改查:

    package main
    import (
        "fmt"
        "time"
        "go-zookeeper/zk"
    )
    var (
        path = "/Zzz"
    )
    //
    func add(conn *zk.Conn) {
        var data = []byte("Hello ZooKeeper")
        // flags 的四种取值方式:
        // 0 (永久.除非手动删除)
        // zk.FlagEphemeral = 1 (短暂. session 断开则该节点也被删除)
        // zk.FlagSequence = 2 (会自动在节点后面添加序号)
        // 3 (Ephemeral  Sequence. 即短暂且自动添加序号)
    	var flags int32 = 0
    	// 获取访问控制权限
    	acls := zk.WorldACL(zk.PermAll)
    	create, err := conn.Create(path,data,flags,acls)
    	if err != nil {
    	    fmt.Printf("创建失败: %v\n",err)
    		return
        }
    	fmt.Printf("创建: %v 成功\n",create)
    }
    // 
    func get(conn *zk.Conn) {
        data, _, err := conn.Get(path)
    	if err != nil {
    	    fmt.Printf("查询 %s 失败,err: %v\n",path,err)
    	    return
    	}
    	fmt.Printf("%s 的值为 %s\n",path,string(data))
    }
    // 删除与增加不同在于其函数中的 Version 参数. 其中 Version 使用 CAS 支持 (可以通过此种方式保证原子性)
    // 
    func modify(conn *zk.Conn) {
        new_data := []byte("This is ZooKeeper")
        _, sate, _ := conn.Get(path)
        _, err := conn.Set(path,new_data,sate.Version)
        if err != nil {
    	    fmt.Printf("数据修改失败: %v\n",err)
    	    return
        }
        fmt.Println("数据修改成功")
    }
    // 
    func del(conn *zk.Conn) {
        _, sate, _ := conn.Get(path)
        err := conn.Delete(path,sate.Version)
        if err != nil {
            fmt.Printf("数据删除失败: %v\n",err)
    	    return
        }
        fmt.Println("数据删除成功")
    }
    func main() {
        hosts := []string{"192.168.1.1:2181"}
        conn, _, err := zk.Connect(hosts,time.Second * 5)
        defer conn.Close()
        if err != nil {
            fmt.Println(err)
    	    return
        }
        /* 增删改查 */
        add(conn)
        get(conn)
        modify(conn)
        get(conn)
        del(conn)
    }
    

    3.配置 ZooKeeper Cluster

    • 在原来的基础上,在增加两台服务器:
    主机名操作系统IP 地址
    ZooKeeper-2CentOS 7.4192.168.1.2
    ZooKeeper-3CentOS 7.4192.168.1.3
    1)将 Java 和 ZooKeeper 传给新的服务器:
    [root@ZooKeeper ~]# scp -r /usr/local/java root@192.168.1.2:/usr/local/
    [root@ZooKeeper ~]# scp -r /usr/local/zookeeper root@192.168.1.2:/usr/local/
    

    2)在新的服务器上启动 ZooKeeper:

    [root@ZooKeeper ~]# cat <<END >> /etc/profile
    export JAVA_HOME=/usr/local/java
    export PATH=$PATH:$JAVA_HOME/bin
    END
    [root@ZooKeeper ~]# source /etc/profile
    [root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start
    

    3)配置 Cluster 集群(三台服务器上操作一样)

    [root@ZooKeeper ~]# cat <<END >> /usr/local/zookeeper/conf/zoo.cfg
    server.1=192.168.1.1:2888:3888
    server.2=192.168.1.2:2889:3889
    server.3=192.168.1.3:2890:3890
    END
    

    4)创建 myid 文件

    [root@ZooKeeper ~]# echo "1" > /usr/local/zookeeper/data/myid
    [root@ZooKeeper-2 ~]# echo "2" > /usr/local/zookeeper/data/myid
    [root@ZooKeeper-2 ~]# echo "3" > /usr/local/zookeeper/data/myid
    
    • 需要确保每台服务器的 myid 文件中数字不同,并且和自己所在机器的 zoo.cfgserver.id=host:port:portid 值一样。
    • 另外,id 的范围是 1 ~ 255

    5)重启 ZooKeeper 服务

    [root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh restart			# 三台服务器都要重启
    

    查看 ZooKeeper 状态:
    在这里插入图片描述
    验证:
    在这里插入图片描述

    展开全文
  • 由于集群至少需要三台服务器,我就拿上次做的MongoDB Master, Slave, Arbiter环境来做Hadoop集群。服务器还是ibmcloud 免费提供的。其中Arbiter在这里做的也是slave的角色。 Hostname IP  Server ...

    一、环境配置


    由于集群至少需要三台服务器,我就拿上次做的MongoDB Master, Slave, Arbiter环境来做Hadoop集群。服务器还是ibmcloud 免费提供的。其中Arbiter在这里做的也是slave的角色。

    Hostname IP  Server Type
    Master 192.168.0.28 Centos6.2
    Slave 192.168.0.29 Ubuntu14.04
    Arbiter 192.168.0.30 Ubuntu14.04

    配置三台机器的Master hosts文件如下:

    cat  /etc/hosts
    127.0.0.1   localhost Database-Master  localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.0.28    Database-Master master
    192.168.0.29    Database-Slave slave
    192.168.0.30    Database-Arbiter arbiter

    Master机器有安装ansible,其他所需要的软件包地址:

    http://apache.fayea.com/hadoop/common/hadoop-2.6.4/hadoop-2.6.4.tar.gz

    http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.8/zookeeper-3.4.8.tar.gz

    http://apache.opencas.org/hbase/1.2.0/hbase-1.2.0-bin.tar.gz

    http://download.oracle.com/otn-pub/java/jdk/8u73-b02/jdk-8u73-linux-x64.tar.gz


    java我解压缩到/usr/java/目录下,然后编辑环境变量.zshrc


    export  JAVA_HOME= /usr/java/jdk1 .8.0_73
    export  PATH=$JAVA_HOME /bin :$PATH
    export  CLASSPATH=.:$JAVA_HOME /lib/dt .jar:$JAVA_HOME /lib/tool .jar

    然后重新加载,使变量生效, source .zshrc.

    然后需要集群见无密码登录,此前做MongoDB实验的时候已经设置过,再次不在赘述。


    二、Hadoop的安装和配置


    1.    首先将刚才下载的hadoop-2.6.4.tar.gz文件解压到/home/ibmcloud/hadoop,然后编辑etc/hadoop/core-site.xml


         <property>
             <name>fs.default.name< /name >
             <value>hdfs: //master :9000< /value >
         < /property >
    < /configuration >

    2.    添加JAVA_HOME变量到hadoop-env.sh

    export JAVA_HOME=/usr/java/jdk1.8.0_73

    3.    hdfs-site.xml

    <configuration>
         <property>
             <name>dfs.name. dir < /name >
             <value> /home/ibmcloud/hadoop/name < /value >
         < /property >
         <property>
             <name>dfs.data. dir < /name >
             <value> /home/ibmcloud/hadoop/data < /value >
         < /property >
         <property>
             <name>dfs.replication< /name >
             <value>3< /value >
         < /property >
     
    < /configuration >

    4.    将mapred-site.xml.template 改名mapred-site.xml

    <configuration>
         <property>
             <name>mapred.job.tracker< /name >
             <value>master:9001< /value >
         < /property >
     
    < /configuration >

    5.    add master and slave

    echo  "master"  >~ /hadoop/etc/hadoop/master
    echo  -e  "slave\narbiter"  >~ /hadoop/etc/hadoop/slaves

    6.    copy hadoop folder to slave and arbiter

    ansible all -m copy -a "src=hadoop dest=~ '

    7.    启动hadoop集群

    第一次执行,需要格式化namenode,以后启动不需要执行此步骤。


    hadoop/bin/hadoop -format

    然后启动hadoop

    hadoop/sbin/start-all.sh

    启动完成后,如果没有什么错误,执行jps查询一下当前进程,NameNode是Hadoop Master进程,SecondaryNameNode,ResourceManager是Hadoop进程。

    $ jps                      
    23076 NameNode
    20788 ResourceManager
    23302 SecondaryNameNode
    27559 Jps

    三、ZooKeeper集群安装


    1.    解压缩zookeeper-3.4.8.tar.gz并重命名zookeeper, 进入zookeeper/conf目录,cp zoo_sample.cfg zoo.cfg 并编辑


    egrep  - v  '^$|^#'  zoo.cfg
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir= /home/ibmcloud/zookeeper/data
    clientPort=2181
    server.1=192.168.0.28:2888:3888
    server.2=192.168.0.29:2888:3888
    server.3=192.168.0.30:2888:3888

    2.    新建并编辑myid文件

    mkdir /home/zookeeper/dataecho "1" /home/zookeeper/data/myid

    3.    然后同步zookeeper到其他两个节点,然后在其他节点需要修改myid为相应的数字。

    ansible all -m copy -a "src=zookeeper dest=~ '

    4.    启动zookeeper,查看启动信息

    2016-03-15 06:43:01,755 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.28:57379
    2016-03-15 06:43:01,757 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.28:57379
    2016-03-15 06:43:01,760 [myid:1] - INFO  [CommitProcessor:1:ZooKeeperServer@645] - Established session 0x15378e1050a0006 with negotiated timeout 40000  for  client  /192 .168.0.28:57379
    2016-03-15 06:43:02,211 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.28:57383
    2016-03-15 06:43:02,215 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.28:57383
    2016-03-15 06:43:02,217 [myid:1] - INFO  [CommitProcessor:1:ZooKeeperServer@645] - Established session 0x15378e1050a0007 with negotiated timeout 40000  for  client  /192 .168.0.28:57383
    2016-03-15 06:46:57,531 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@1008] - Closed socket connection  for  client  /192 .168.0.28:57379  which  had sessionid 0x15378e1050a0006
    2016-03-15 06:46:57,544 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@1008] - Closed socket connection  for  client  /192 .168.0.28:57383  which  had sessionid 0x15378e1050a0007
    2016-03-15 06:46:57,555 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@1008] - Closed socket connection  for  client  /192 .168.0.28:57372  which  had sessionid 0x15378e1050a0005
    2016-03-15 06:47:10,171 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.30:60866
    2016-03-15 06:47:10,184 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.30:60866
    2016-03-15 06:47:10,186 [myid:1] - INFO  [CommitProcessor:1:ZooKeeperServer@645] - Established session 0x15378e1050a0008 with negotiated timeout 40000  for  client  /192 .168.0.30:60866
    2016-03-15 06:47:10,625 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.28:58169
    2016-03-15 06:47:10,626 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.28:58169
    2016-03-15 06:47:10,629 [myid:1] - INFO  [CommitProcessor:1:ZooKeeperServer@645] - Established session 0x15378e1050a0009 with negotiated timeout 40000  for  client  /192 .168.0.28:58169
    2016-03-15 06:47:11,199 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.30:60867
    2016-03-15 06:47:11,200 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.30:60867
    2016-03-15 06:47:11,204 [myid:1] - INFO  [CommitProcessor:1:ZooKeeperServer@645] - Established session

     来自Slave的信息:

    2016-03-15 06:43:02,667 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.28:58604
    2016-03-15 06:43:02,667 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.28:58604
    2016-03-15 06:43:02,670 [myid:2] - INFO  [CommitProcessor:2:ZooKeeperServer@645] - Established session 0x25378e0edf00006 with negotiated timeout 40000  for  client  /192 .168.0.28:58604
    2016-03-15 06:46:55,407 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.28:59328
    2016-03-15 06:46:55,410 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.28:59328
    2016-03-15 06:46:55,415 [myid:2] - INFO  [CommitProcessor:2:ZooKeeperServer@645] - Established session 0x25378e0edf00007 with negotiated timeout 40000  for  client  /192 .168.0.28:59328
    2016-03-15 06:46:57,242 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@1008] - Closed socket connection  for  client  /192 .168.0.28:59328  which  had sessionid 0x25378e0edf00007
    2016-03-15 06:46:57,928 [myid:2] - WARN  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@357] - caught end of stream exception
    EndOfStreamException: Unable to  read  additional data from client sessionid 0x25378e0edf00006, likely client has closed socket
         at org.apache.zookeeper.server.NIOServerCnxn.doIO(NIOServerCnxn.java:230)
         at org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:203)
         at java.lang.Thread.run(Thread.java:745)
    2016-03-15 06:46:57,929 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@1008] - Closed socket connection  for  client  /192 .168.0.28:58604  which  had sessionid 0x25378e0edf00006
    2016-03-15 06:47:08,780 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.28:59377
    2016-03-15 06:47:08,786 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.28:59377
    2016-03-15 06:47:08,789 [myid:2] - INFO  [CommitProcessor:2:ZooKeeperServer@645] - Established session 0x25378e0edf00008 with negotiated timeout 40000  for  client  /192 .168.0.28:59377
    2016-03-15 06:49:57,202 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from  /192 .168.0.28:59911
    2016-03-15 06:49:57,212 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:ZooKeeperServer@900] - Client attempting to establish new session at  /192 .168.0.28:59911
    2016-03-15 06:49:57,215 [myid:2] - INFO  [CommitProcessor:2:ZooKeeperServer@645] - Established session 0x25378e0edf00009 with negotiated timeout 40000  for  client  /192 .168.0.28:59911
    2016-03-15 06:52:15,489 [myid:2] - WARN  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@357] - caught end of stream exception
    EndOfStreamException: Unable to  read  additional data from client sessionid 0x25378e0edf00009, likely client has closed socket
         at org.apache.zookeeper.server.NIOServerCnxn.doIO(NIOServerCnxn.java:230)
         at org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:203)
         at java.lang.Thread.run(Thread.java:745)
    2016-03-15 06:52:15,490 [myid:2] - INFO  [NIOServerCxn.Factory:0.0.0.0 /0 .0.0.0:2181:NIOServerCnxn@1008] - Closed socket connection  for  client  /192 .168.0.28:59911  which  had sessionid 0x25378e0edf00009

    5.    再次查看jps, 此时会看到zookeeper进程QuorumPeerMain

    $ jps
    23076 NameNode
    20788 ResourceManager
    30821 Jps
    23302 SecondaryNameNode
    30538 QuorumPeerMain

    四、HBase集群的安装和配置

    1.    解压缩hbase-1.2.0-bin.tar.gz并重命名为hbase, 编辑/hbase/conf/hbase-env.sh

    egrep  - v  '^$|^#'  hbase- env .sh
    export  JAVA_HOME= /usr/java/jdk1 .8.0_73
    export  HBASE_CLASSPATH= /home/ibmcloud/hadoop/etc/hadoop
    export  HBASE_OPTS= "-XX:+UseConcMarkSweepGC"
    export  HBASE_MASTER_OPTS= "$HBASE_MASTER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"
    export  HBASE_REGIONSERVER_OPTS= "$HBASE_REGIONSERVER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"
    export  HBASE_MANAGES_ZK= false

    2.    编辑hbase-site.xml

    < configuration >
         < property >
             < name >hbase.rootdir</ name >
             < value >hdfs://master:9000/hbase</ value >
         </ property >
         < property >
             < name >hbase.master</ name >
             < value >master</ value >
         </ property >
         < property >
             < name >hbase.cluster.distributed</ name >
             < value >true</ value >
         </ property >
         < property >
             < name >hbase.zookeeper.property.clientPort</ name >
             < value >2181</ value >
         </ property >
         < property >
             < name >hbase.zookeeper.quorum</ name >
             < value >master,slave,arbiter</ value >
         </ property >
         < property >
             < name >zookeeper.session.timeout</ name >
             < value >60000000</ value >
         </ property >
         < property >
             < name >dfs.support.append</ name >
             < value >true</ value >
         </ property >
    </ configuration >

    3.    添加Slave, Arbiter 到regionservers

    4.    分发hbase到其他两个节点


    ansible all -m copy -a "src=hbase dest=~"

    五、启动集群


    1.     启动zookeeper


    zookeeper/bin/zkServer.sh start

    2.    启动Hadoop

    $ hadoop /sbin/start-all .sh
    This script is Deprecated. Instead use start-dfs.sh and start-yarn.sh
    16 /03/15  07:33:09 WARN util.NativeCodeLoader: Unable to load native-hadoop library  for  your platform... using  builtin -java classes where applicable
    Starting namenodes on [master]
    master: namenode running as process 23076. Stop it first.
    arbiter: datanode running as process 2111. Stop it first.
    slave: datanode running as process 19992. Stop it first.
    Starting secondary namenodes [0.0.0.0]
    0.0.0.0: secondarynamenode running as process 23302. Stop it first.
    16 /03/15  07:33:16 WARN util.NativeCodeLoader: Unable to load native-hadoop library  for  your platform... using  builtin -java classes where applicable
    starting yarn daemons
    resourcemanager running as process 20788. Stop it first.
    arbiter: starting nodemanager, logging to  /home/ibmcloud/hadoop/logs/yarn-ibmcloud-nodemanager-Database-Arbiter .out
    slave: starting nodemanager, logging to  /home/ibmcloud/hadoop/logs/yarn-ibmcloud-nodemanager-Database-Slave .out

    3.    启动hbase

    $ hbase /bin/start-hbase .sh
    master running as process 10144. Stop it first.
    arbiter: regionserver running as process 3515. Stop it first.
    slave: starting regionserver, logging to  /home/ibmcloud/hbase/bin/ .. /logs/hbase-ibmcloud-regionserver-Database-Slave .out
    slave: Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed  in  8.0
    slave: Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=128m; support was removed  in  8.0

    查询各个节点的集群进程情况

    Master:


    # ibmcloud at Database-Master in ~ [7:33:44]
    $ jps
    10144 HMaster
    23076 NameNode
    20788 ResourceManager
    20773 Jps
    23302 SecondaryNameNode
    30538 QuorumPeerMain

    Slave:

    # ibmcloud at Database-Slave in ~/hbase/bin [6:47:55]
    $ jps
    19992 DataNode
    26794 Jps
    16397 QuorumPeerMain
    26526 HRegionServer

    Arbiter:

    # ibmcloud at Database-Arbiter in ~/hbase/bin [6:46:34]
    $ jps
    2016 QuorumPeerMain
    3515 HRegionServer
    3628 Jps
    2111 DataNode

    进程都已经开启,进入habse shell环境,

    $ hbase /bin/hbase  shell                
     
    2016-03-15 07:35:04,687 WARN  [main] util.NativeCodeLoader: Unable to load native-hadoop library  for  your platform... using  builtin -java classes where applicable
    HBase Shell; enter  'help<RETURN>'  for  list of supported commands.
    Type  "exit<RETURN>"  to leave the HBase Shell
    Version 1.2.0, r25b281972df2f5b15c426c8963cbf77dd853a5ad, Thu Feb 18 23:01:49 CST 2016
     
    hbase(main):001:0> 
    hbase(main):002:0* status
     
    ERROR: org.apache.hadoop.hbase.PleaseHoldException: Master is initializing

    提示master还是initialzing, 我的虚拟机1.5G内存,单核,10G硬盘,跑着MongoDB, PHP, Nginx, 加上Hadoop集群,肯定消化不良了。如图:


    查看链接发现Hadoop监听网卡是内网的,加上端口转发,打开公网地址查看一下Hadoop运行状态

    sudo iptables -t nat -I PREROUTING -d 129.41.153.232 -p tcp --dport  50070 -j DNAT --to 192.168.0.28:50070

    然后打开浏览器输入http://129.41.153.232:50070/dfshealth.html#tab-overview,如图,hadoop状态


    YARN状态:Hbase状态:


    其中遇到的问题又hbase启动不起来,一直报permission denied,后来发现Slave, Arbiter bin目录下的脚本没有给执行权限,然后logs下日志文件的权限不对。


    参考文章:

    http://songlee24.github.io/2015/07/20/hadoop-hbase-zookeeper-distributed-mode/

    http://stackoverflow.com/questions/21166542/hbase-does-not-run-after-start-hbase-sh-permission-denied




    展开全文
  • zookeeper 主要是解决分布式环境下的服务协调问题而产生的,如果我们要去实现一个 zookeeper 这样的中间件, 我们需要做什么? 1. 防止单点故障 如果要防止 zookeeper 这个中间件的单点故障,那就势必要做集群。...

    zookeeper 的设计猜想

    zookeeper 主要是解决分布式环境下的服务协调问题而产生的,如果我们要去实现一个 zookeeper 这样的中间件, 我们需要做什么? 

    1. 防止单点故障

    如果要防止 zookeeper 这个中间件的单点故障,那就势必要做集群。而且这个集群如果要满足高性能要求的话,还得是一个高性能高可用的集群。高性能意味着这个集群能够分担客户端的请求流量,高可用意味着集群中的某一个节点宕机以后,不影响整个集群的数据和继续提供服务的可能性。

    结论: 所以这个中间件需要考虑到集群,而且这个集群还需要分摊客户端的请求流量

    2. 接着上面那个结论再来思考,如果要满足这样的一个高性能集群,我们最直观的想法应该是,每个节点都能接收到请求,并且每个节点的数据都必须要保持一致。要实现各个节点的数据一致性,就势必要一个 leader 节点负责协调和数据同步操作。这个我想大家都知道,如果在这样一个集群中没有 leader 节点,每个节点都可以接收所有请求,那么这个集群的数据同步的复杂度是非常大。

    结论:所以这个集群中涉及到数据同步以及会存在leader 节点

    3. 继续思考,如何在这些节点中选举出 leader 节点,以及leader 挂了以后,如何恢复呢?

    结论:所以 zookeeper 用了基于 paxos 理论所衍生出来的 ZAB 协议

    4. leader 节点如何和其他节点保证数据一致性,并且要求是强一致的。在分布式系统中,每一个机器节点虽然都能够明确知道自己进行的事务操作过程是成功和失败, 但是却无法直接获取其他分布式节点的操作结果。所以当一个事务操作涉及到跨节点的时候,就需要用到分布式事务,分布式事务的数据一致性协议有 2PC协议和3PC 协议。

    基于这些猜想,我们基本上知道 zookeeper 为什么要用到zab 理论来做选举、为什么要做集群、为什么要用到分布式事务来实现数据一致性了。

    关于 2PC 提交

    (Two Phase Commitment Protocol)当一个事务操作需要跨越多个分布式节点的时候,为了保持事务处理的ACID特性,就需要引入一个“协调者”(TM)来统一调度所有分布式节点的执行逻辑,这些被调度的分布式节点被称为 AP。

    TM 负责调度 AP 的行为,并最终决定这些 AP 是否要把事务真正进行提交;因为整个事务是分为两个阶段提交,所以叫 2pc

    阶段一:提交事务请求(投票)

    1. 事务询问

    协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应

    2. 执行事务

    各个参与者节点执行事务操作,并将 Undo 和 Redo 信息记录到事务日志中,尽量把提交过程中所有消耗时间的操作和准备都提前完成确保后面 100%成功提交事务

    3. 各个参与者向协调者反馈事务询问的响应

    如果各个参与者成功执行了事务操作,那么就反馈给参与者yes 的响应,表示事务可以执行;如果参与者没有成功执行事务,就反馈给协调者 no 的响应,表示事务不可以执行,上面这个阶段有点类似协调者组织各个参与者对一次事务操作的投票表态过程,因此 2pc 协议的第一个阶段称为“投票阶段”,即各参与者投票表名是否需要继续执行接下去的事务提交操作。

    阶段二:执行事务提交

    在这个阶段,协调者会根据各参与者的反馈情况来决定最终是否可以进行事务提交操作,正常情况下包含两种可能:执行事务、中断事务

    zookeeper 的集群

    在 zookeeper 中,客户端会随机连接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据,如果是写请求,那么请求会被转发给 leader 提交事务, 然后 leader 会广播事务,只要有超过半数节点写入成功, 那么写请求就会被提交(类 2PC 事务)

    所有事务请求必须由一个全局唯一的服务器来协调处理,这个服务器就是 Leader 服务器,其他的服务器就是follower。leader 服务器把客户端的失去请求转化成一个事务 Proposal(提议),并把这个 Proposal 分发给集群中的所有 Follower 服务器。之后 Leader 服务器需要等待所有Follower 服务器的反馈,一旦超过半数的 Follower 服务器进行了正确的反馈,那么 Leader 就会再次向所有的Follower 服务器发送 Commit 消息,要求各个 follower 节点对前面的一个 Proposal 进行提交; 

    集群角色

    Leader 角色

    Leader 服务器是整个 zookeeper 集群的核心,主要的工作任务有两项

    1. 事物请求的唯一调度和处理者,保证集群事物处理的顺序性

    2. 集群内部各服务器的调度者 

    Follower 角色

    Follower 角色的主要职责是

    1. 处理客户端非事物请求、转发事物请求给 leader 服务器

    2. 参与事物请求 Proposal 的投票(需要半数以上服务器通过才能通知 leader commit 数据; Leader 发起的提案, 要求 Follower 投票)

    1. 参与 Leader 选举的投票

    Observer 角色

    Observer 是 zookeeper3.3 开始引入的一个全新的服务器角色,从字面来理解,该角色充当了观察者的角色。 观察 zookeeper 集群中的最新状态变化并将这些状态变化同步到 observer 服务器上。Observer 的工作原理与follower 角色基本一致,而它和 follower 角色唯一的不同在于 observer 不参与任何形式的投票,包括事物请求Proposal的投票和leader选举的投票。简单来说,observer服务器只提供非事物请求服务,通常在于不影响集群事物处理能力的前提下提升集群非事物处理的能力 

     

    集群组成

    通常 zookeeper 是由 2n+1 台 server 组成,每个 server 都知道彼此的存在。对于 2n+1 台 server,只要有 n+1 台(大多数)server 可用,整个系统保持可用。我们已经了解到,一个 zookeeper 集群如果要对外提供可用的服务,那么集群中必须要有过半的机器正常工作并且彼此之间能够正常通信,基于这个特性,如果向搭建一个能够允许 F 台机器 down 掉的集群,那么就要部署 2*F+1 台服务器构成的zookeeper 集群。因此 3 台机器构成的 zookeeper 集群,

    能够在挂掉一台机器后依然正常工作。一个 5 台机器集群的服务,能够对 2 台机器怪调的情况下进行容灾。如果一台由 6 台服务构成的集群,同样只能挂掉 2 台机器。因此,5 台和 6 台在容灾能力上并没有明显优势,反而增加了网络通信负担。系统启动时,集群中的 server 会选举出一台server 为 Leader,其它的就作为 follower(这里先不考虑observer 角色)。 

    之所以要满足这样一个等式,是因为一个节点要成为集群中的 leader,需要有超过及群众过半数的节点支持,这个涉及到 leader 选举算法。同时也涉及到事务请求的提交投票

    ZAB 协议

    ZAB(Zookeeper Atomic Broadcast) 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。 

    zab 协议介绍

    ZAB 协议包含两种基本模式,分别是

    1. 崩溃恢复

    2. 原子广播当整个集群在启动时,或者当 leader 节点出现网络中断、崩溃等情况时,ZAB 协议就会进入恢复模式并选举产生新的 Leader,当 leader 服务器选举出来后,并且集群中有过半的机器和该 leader 节点完成数据同步后(同步指的是数据同步,用来保证集群中过半的机器能够和 leader 服务器的数据状态保持一致),ZAB 协议就会退出恢复模式。 当集群中已经有过半的 Follower 节点完成了和 Leader 状态同步以后,那么整个集群就进入了消息广播模式。这个时候,在 Leader 节点正常工作时,启动一台新的服务器加入到集群,那这个服务器会直接进入数据恢复模式,和 leader 节点进行数据同步。同步完成后即可正常对外提供非事务请求的处理。 

    消息广播的实现原理

    如果大家了解分布式事务的 2pc 和 3pc 协议的话(不了解也没关系,我们后面会讲),消息广播的过程实际上是一个简化版本的二阶段提交过程

    1. leader 接收到消息请求后,将消息赋予一个全局唯一的64 位自增 id,叫:zxid,通过 zxid 的大小比较既可以实现因果有序这个特征

    2. leader 为每个 follower 准备了一个 FIFO 队列(通过 TCP协议来实现,以实现了全局有序这一个特点)将带有 zxid的消息作为一个提案(proposal)分发给所有的 follower

    3. 当 follower 接收到 proposal,先把 proposal 写到磁盘, 写入成功以后再向 leader 回复一个 ack

    4. 当 leader 接收到合法数量(超过半数节点)的 ACK 后,leader 就会向这些 follower 发送 commit 命令,同时会在本地执行该消息

    5. 当 follower 收到消息的 commit 命令以后,会提交该消息 

    leader 的投票过程,不需要 Observer 的 ack,也就是Observer 不需要参与投票过程,但是 Observer 必须要同步 Leader 的数据从而在处理请求的时候保证数据的一致性 

    崩溃恢复(数据恢复)

    ZAB 协议的这个基于原子广播协议的消息广播过程,在正常情况下是没有任何问题的,但是一旦 Leader 节点崩溃,或者由于网络问题导致 Leader 服务器失去了过半的Follower 节点的联系(leader 失去与过半 follower 节点联系,可能是 leader 节点和 follower 节点之间产生了网络分区,那么此时的 leader 不再是合法的 leader 了),那么就会进入到崩溃恢复模式。在 ZAB 协议中,为了保证程序的正确运行,整个恢复过程结束后需要选举出一个新的Leader为了使 leader 挂了后系统能正常工作,需要解决以下两个问题

    1. 已经被处理的消息不能丢失

    当 leader 收到合法数量 follower 的 ACKs 后,就向各个 follower 广播COMMIT 命令,同时也会在本地执行 COMMIT 并向连接的客户端返回「成功」。但是如果在各个 follower 在收到 COMMIT 命令前 leader 就挂了,导致剩下的服务器并没有执行都这条消息。

    leader 对事务消息发起 commit 操作,但是该消息在follower1 上执行了,但是 follower2 还没有收到 commit,就已经挂了,而实际上客户端已经收到该事务消息处理成功的回执了。所以在 zab 协议下需要保证所有机器都要执行这个事务消息 

    2. 被丢弃的消息不能再次出现

    当 leader 接收到消息请求生成 proposal 后就挂了,其他 follower 并没有收到此 proposal,因此经过恢复模式重新选了 leader 后,这条消息是被跳过的。 此时,之前挂了的 leader 重新启动并注册成了 follower,他保留了被跳过消息的 proposal 状态,与整个系统的状态是不一致的,需要将其删除。

     

    ZAB 协议需要满足上面两种情况,就必须要设计一个 leader 选举算法:能够确保已经被 leader 提交的事务 ,Proposal能够提交、同时丢弃已经被跳过的事务Proposal。

    针对这个要求

    1. 如果 leader 选举算法能够保证新选举出来的 Leader 服务器拥有集群中所有机器最高编号(ZXID 最大)的事务Proposal,那么就可以保证这个新选举出来的 Leader 一定具有已经提交的提案。因为所有提案被 COMMIT 之前必须有超过半数的 follower ACK,即必须有超过半数节点的服务器的事务日志上有该提案的 proposal,因此,只要有合法数量的节点正常工作,就必然有一个节点保存了所有被 COMMIT 消息的 proposal 状态 ;另外一个,zxid 是 64 位,高 32 位是 epoch 编号,每经过一次 Leader 选举产生一个新的 leader,新的 leader 会将epoch 号+1,低 32 位是消息计数器,每接收到一条消息这个值+1,新 leader 选举后这个值重置为 0.这样设计的好处在于老的 leader 挂了以后重启,它不会被选举为 leader, 因此此时它的 zxid 肯定小于当前新的 leader。当老的leader 作为 follower 接入新的 leader 后,新的 leader 会 让它将所有的拥有旧的 epoch 号的未被 COMMIT 的proposal 清除 

    关于 ZXID

    zxid,也就是事务 id,为了保证事务的顺序一致性,zookeeper 采用了递增的事务 id 号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了 zxid。实现中 zxid 是一个 64 位的数字,它高 32 位是 epoch(ZAB 协议通过 epoch 编号来区分 Leader 周期变化的策略)用来标识 leader 关系是否改变,每次一个 leader 被选出来,它都会有一个新的 epoch=(原来的 epoch+1),标识当前属于那个 leader 的统治时期。低 32 位用于递增计数。epoch:可以理解为当前集群所处的年代或者周期,每个leader 就像皇帝,都有自己的年号,所以每次改朝换代,leader 变更之后,都会在前一个年代的基础上加 1。这样就算旧的 leader 崩溃恢复之后,也没有人听他的了,因为 follower 只听从当前年代的 leader 的命令。*

    epoch 的变化大家可以做一个简单的实验,

    1. 启动一个 zookeeper 集群。

    2. 在 /tmp/zookeeper/VERSION-2 路 径 下 会 看 到 一 个 currentEpoch 文件。文件中显示的是当前的 epoch

    3. 把 leader 节点停机,这个时候在看 currentEpoch 会有变化。 随着每次选举新的 leader,epoch 都会发生变化

    leader 选举

    Leader 选举会分两个过程

           启动的时候的 leader 选举、 leader 崩溃的时候的的选举

    服务器启动时的 leader 选举

    每个节点启动的时候状态都是 LOOKING,处于观望状态, 接下来就开始进行选主流程进行 Leader 选举,至少需要两台机器(具体原因前面已经讲过了),我们选取 3 台机器组成的服务器集群为例。在集群初始化阶段,当有一台服务器 Server1 启动时,它本身是无法进行和完成 Leader 选举,当第二台服务器 Server2 启动时,这个时候两台机器可以相互通信,每台机器都试图找到 Leader,于是进入 Leader 选举过程。选举过程如下

    (1) 每个 Server 发出一个投票。由于是初始情况,Server1 和 Server2 都会将自己作为 Leader 服务器来进行投票,每次投票会包含所推举的服务器的 myid 和 ZXID、 epoch,使用(myid, ZXID,epoch)来表示,此时 Server1 的投票为(1, 0),Server2 的投票为(2, 0),然后各自将这个投票发给集群中其他机器。

    (2) 接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(epoch)、是否来自LOOKING状态的服务器。

    (3) 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行 PK,PK 规则如下

    i. 优先检查 ZXID。ZXID 比较大的服务器优先作为Leader

    ii. 如果 ZXID 相同,那么就比较 myid。myid 较大的服务器作为 Leader 服务器。 对于 Server1 而言,它的投票是(1, 0),接收 Server2 的投票为(2, 0),首先会比较两者的 ZXID,均为 0,再比较 myid,此时 Server2 的 myid 最大,于是更新自己的投票为(2, 0),然后重新投票,对于 Server2 而言, 它不需要更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可。

    (4) 统计投票。每次投票后,服务器都会统计投票信息, 判断是否已经有过半机器接受到相同的投票信息,对于 Server1、Server2 而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了 Leader。

    (5) 改变服务器状态。一旦确定了 Leader,每个服务器就会更新自己的状态,如果是 Follower,那么就变更为 FOLLOWING,如果是 Leader,就变更为 LEADING。 

    运行过程中的 leader 选举

    当集群中的 leader 服务器出现宕机或者不可用的情况时, 那么整个集群将无法对外提供服务,而是进入新一轮的Leader 选举,服务器运行期间的 Leader 选举和启动时期的 Leader 选举基本过程是一致的。

    (1) 变更状态。Leader 挂后,余下的非 Observer 服务器都会将自己的服务器状态变更为 LOOKING,然后开始进入 Leader 选举过程。

    (2) 每个 Server 会发出一个投票。在运行期间,每个服务器上的 ZXID 可能不同,此时假定 Server1 的 ZXID 为123,Server3的ZXID为122;在第一轮投票中,Server1 和 Server3 都会投自己,产生投票(1, 123),(3, 122), 然后各自将投票发送给集群中所有机器。接收来自各个服务器的投票。与启动时过程相同。

    (3) 处理投票。与启动时过程相同,此时,Server1 将会成为 Leader。

    (4) 统计投票。与启动时过程相同。

    (5) 改变服务器的状态。与启动时过程相同

    Leader 选举源码分析

    有了理论基础以后,我们先带大家读一下源码,看看他的实现逻辑。然后我们再通过图形的方式帮助大家理解。

    从入口函数 QUORUMPEERMAIN 开始

    启动主线程,QuorumPeer 重写了 Thread.start 方法

    调用 QUORUMPEER 的 START 方法

    loaddatabase, 主要是从本地文件中恢复数据,以及获取最新的 zxid

    初始化 LEADERELECTION

    配置选举算法,选举算法有 3 种,可以通过在 zoo.cfg 里面进行配置,默认是 fast 选举

    继续看 FastLeaderElection 的初始化动作,主要初始化了业务层的发送队列和接收队列

    接下来调用 fle.start() , 也就是会调用 FastLeaderElection .start()方法,该方法主要是对发送线程和接收线程的初始化 ,左边是 FastLeaderElection 的 start,右边是messager.start()

     

    wsThread 和 wrThread 的 初 始 化 动 作 在FastLeaderElection 的 starter 方法里面进行,这里面有两个内部类,一个是 WorkerSender,一个是WorkerReceiver, 负责发送投票信息和接收投票信息

    然后再回到 QuorumPeer.java。 FastLeaderElection 初始化完成以后,调用 super.start(),最终运行 QuorumPeer 的run 方法

    前面部分主要是做 JMX 监控注册

    重要的代码在这个 while 循环里

    调用 setCurrentVote(makeLEStrategy().lookForLeader());最终根据策略应该运行 FastLeaderElection 中的选举算法

    LOOKFORLEADER 开始选举

    消息如何广播,看 SENDNOTIFICATIONS

     

    WORKERSENDER

     

    FastLeaderElection 选举过程

    其实在这个投票过程中就涉及到几个类,FastLeaderElection:FastLeaderElection 实现了 Election 接口,实现各服务器之间基于 TCP 协议进行选举Notification:内部类,Notification 表示收到的选举投票信息(其他服务器发来的选举投票信息),其包含了被选举者的 id、zxid、选举周期等信息

    ToSend:ToSend表示发送给其他服务器的选举投票信息,也包含了被选举者的 id、zxid、选举周期等信息

    Messenger : Messenger 包 含 了 WorkerReceiver 和WorkerSender 两个内部类; WorkerReceiver 实现了 Runnable 接口,是选票接收器。其会不断地从 QuorumCnxManager 中获取其他服务器发来的选举消息,并将其转换成一个选票,然后保存到recvqueue 中 ;WorkerSender 也实现了 Runnable 接口,为选票发送器,其会不断地从 sendqueue 中获取待发送的选票,并将其传递到底层 QuorumCnxManager 中

    展开全文
  • 实验目标:在3台主机组成的小型集群上部署分布式协调服务ZooKeeper,用于教学演示环境要求: 虚拟机...集群规划:无需复制虚拟机,直接利用完全分布式集群的3台主机master,slave1,slave2完成部署, 需要特别说明: Zo...
  • HBase完全分布式模式: 1)不同的HBase进程分别独立运行在多台硬件配置较高的服务器主机构成的集群中,适合HBase的运维和生产环境 ...实验前提:HBase完全分布式部署方式依赖Hadoop,本实验紧接Hadoop...
  • Zookeeper学习总结

    2022-02-28 19:14:50
    Zookeeper 分布式组件的鼻祖。 一、什么是Zookeeper Zookeeper是一种分布式协调服务,...在分布式系统中,需要有zookeeper作为分布式协调组件,协调分布式系统中的状态 分布式锁 zk在实现分布式锁上,可以做到
  • Zookeeper学习个人总结

    2021-10-15 10:54:07
    NO1:说说zookeeper是什么? Zookeeper一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心,服务生产者将自己提供的服务注册到Zookeeper中心,服务的消费者在进行服务调用的时候先到Zookeeper中查找...
  • 1. 环境 HBase的版本为 1.4.1  请注意版本差异 ! ...官网版本说明地址 ...-- hbase 中自带的zookeeper数据存放...Hadoop伪分布式集群环境搭建 https://blog.csdn.net/weixin_42195284/article/details/88978897
  • 大数据实验报告,内含八个实验报告,Hadoop集群分布式搭建、Hadoop基本操作、MapReduce程序设计、Zookeeper安装与Hadoop高可用性部署、Hbase数据储存设计、 Sqoop数据迁移实战、Flume数据采集实战、Hive数据分析...
  • 2.HDFS 高可用集群规划,请保证 Hadoop 完全分布式ZooKeeper 完全分布式环境已经安装完成,以3台机为例。 3.先在一台机hadoop2上配置文件信息 进入文件夹下的配置文件目录下 cd /opt/soft/hadoop260/etc/hadoop/ ...
  • OVERVIEWHBase伪分布式部署实验环境1.HBase单机模式安装配置2.HBase伪分布式安装部署3.HBase Shell操作4.HBase Web UI管理(1)Master节点的Web管理(2)RegionServer节点的Web管理 实验环境 硬件:ubuntu 16.04 ...
  • 详细步骤:安装scala环境解压Spark的tar包向所有子节点发送 Spark 配置好的安装包测试Spark环境开启Spark集群访问Web界面 安装scala环境 1、解压scala 的 tar 包 首先我们进入到本系统的/opt/soft路径下可以看到我们...
  • 手把手教你搭建Hadoop生态系统伪分布式集群

    千次阅读 多人点赞 2020-06-08 21:33:23
    这篇博客呢,我会详细介绍怎么搭建Hadoop生态系统,实战课程嘛,搞了三天服务器,搭建完全分布式系统。 一、准备工作 三台服务器的版本信息: 主节点: 从节点1: 从节点2: 1.更新升级软件包 CentOS系统: ...
  • Zookeeper学习心得

    2021-05-12 17:02:30
    提起Zookeeper,大家就会想到分布式架构的系统,而分布式系统中都是基于CAP原则来实现的,下面就先介绍一下CAP原则 CAP原则 1.可用性 Availability 可用性是在某个考察时间,系统能够正常运行的概率或时间占有率期望...
  •  ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、...
  • ZooKeeper应用---分布式配置更新

    千次阅读 2022-03-21 15:42:11
    zookeeper API的使用,基于回调和监听的响应式编程
  • 集群部署的优点:当HMaster主节点出现故障,HMaster备用节点会用Zookeeper获取主HMaster存在的整个Hbase集群状态信息,但是Hbase可以通过Zookeeper随时感知每个HegionServer的状况,以便于控制管理。 1. 集群...
  • ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、...
  • Hadoop-2.7.2+Zookeeper-3.4.6完全分布式环境搭建 一.版本 组件名 版本 说明 JRE java version &quot;1.7.0_67&quot;Java™ SE Runtime Environment (build 1.7.0_67-b01)Java ...
  • Kafka的生产集群部署 方案背景 假设每天集群需要承载10亿数据。一天24小时,晚上12点到凌晨8点几乎没多少数据。 使用二八法则估计,也就是80%的数据(8亿)会在16个小时涌入,而且8亿的80%的数据(6.4亿)会在这16...
  • zookeeper: 为读多写少的场景所设计 并不是存储大规模业务数据 而是用于存储少量的状态和 配置信息,每个节点存储数据不能超过1MB 数据存储基于节点 znode(包含数据子节点 子节点引用 访问权限) Zookeeper ...
  • Hbase集群搭建总结

    2020-06-03 08:31:05
    参考:hadoop 分布式集群搭建 二.安装zookeeper 参考:zookeeper集群安装 三.部署hbase 1.解压缩hbase的软件包,使用命令: tar -zxvf hbase-1.3.0-bin.tar.gz 2.进入hbase的配置目录,在hbase-env.sh文件里面...
  • zookeeper全面总结

    2021-09-04 14:18:30
    主要⽤用来解决分布式集群中应⽤用系统的一致性问题, 例例如怎样避免同时操作同一数据造成脏读的问题。分布式系统中数据存在一致性的问题!! ZooKeeper 本质上是⼀个分布式的⼩文件存储系统。 提供基于类似于文件...
  • 对于实验环境下Hadoop集群网络需考虑地址规划、连通性。由于实验环境下数据负载较小、可靠性要求不高,链路一般采用单链路连接。IP地址规划在同一网络中,一般设定地址为(192.168.1.0/24)网段。具体IP地址在Centos...
  • 3.搭建Zookeeper

    2021-07-20 07:16:31
    集群规划2.解压安装3.配置zoo.cfg文件4.将配置好的文件进行文件分发5.进行启动测试 介绍Zookeeper作用: Apache ZooKeeper是一种高可用性服务,用于维护少量协调数据,通知客户端该数据的更改以及监视客户端的故障...
  • 文章目录一. 实验目的二. 实验内容三. 实验步骤及结果分析 1.... 基于ubuntukylin14.04 (6)版本,完成HBASE伪分布式配置部署 2.1 配置hbase-env.sh文件 2.2 配置hbase-site.xml文件 2.3 运行HBase 3. 基于ubuntuky
  • 分布式NoSQL列存储数据库Hbase(一) 知识点01:课程回顾 离线项目为例 数据生成:用户访问咨询数据、意向用户报名信息、考勤信息 数据采集 Flume:实时数据采集:采集文件或者网络端口 Sqoop:离线数据同步:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,172
精华内容 468
关键字:

zookeeper分布式集群部署实验报告

友情链接: ADS1100的源程序.zip