Aldebaran

人生最棒的感觉,就是你做到别人说你做不到的事。

0%

ZooKeeper 3.4入门笔记

生田絵梨花 - 白石麻衣

前言

ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。它也是Google的Chubby一个开源的实现,是高有效和可靠的协同工作系统,Zookeeper能够用来leader选举,配置信息维护等,在一个分布式的环境中,需要一个Master实例或存储一些配置信息,确保文件写入的一致性等。

ZooKeeper设计目的

  1. 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。

  2. 可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。

  3. 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。

  4. 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。

  5. 原子性:更新只能成功或者失败,没有中间状态。

  6. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

准备工作

##下载zookeeper
$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz

数据模型

Zookeeper 会维护一个具有层次关系的数据结构,它非常类似于一个标准的文件系统,如图 所示:

01

Zookeeper 这种数据结构有如下这些特点:

  1. 每个子目录项如NameService都被称作为znode,这个znode是被它所在的路径唯一标识,如Server1这个znode的标识为/NameService/Server1。

  2. znode可以有子节点目录,并且每个znode可以存储数据,注意EPHEMERAL(临时的)类型的目录节点不能有子节点目录。

  3. znode是有版本的(version),每个znode中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据,version号自动增加。

  4. znode的类型:

    • Persistent 节点,一旦被创建,便不会意外丢失,即使服务器全部重启也依然存在。每个 Persist 节点即可包含数据,也可包含子节点。
    • Ephemeral 节点,在创建它的客户端与服务器间的 Session 结束时自动被删除。服务器重启会导致 Session 结束,因此 Ephemeral 类型的 znode 此时也会自动删除。
    • Non-sequence 节点,多个客户端同时创建同一 Non-sequence 节点时,只有一个可创建成功,其它匀失败。并且创建出的节点名称与创建时指定的节点名完全一样。
    • Sequence 节点,创建出的节点名在指定的名称之后带有10位10进制数的序号。多个客户端创建同一名称的节点时,都能创建成功,只是序号不同。
  5. znode可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是Zookeeper的核心特性,Zookeeper的很多功能都是基于这个特性实现的。

  6. ZXID:每次对Zookeeper的状态的改变都会产生一个zxid(ZooKeeper Transaction Id),zxid是全局有序的,如果zxid1小于zxid2,则zxid1在zxid2之前发生。

安装ZooKeeper

  • 单机模式

    单机安装非常简单,只要获取到 Zookeeper 的压缩包并解压到某个目录, Zookeeper 的启动脚本在 bin 目录下

      $ cd /usr/local/src/
      ## 下载从官方源下载zookeeper
      $ wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz
    
      ## 解压zookeeper到相应的目录,并进入zookeeper的conf目录。
      $ tar xf zookeeper-3.4.13.tar.gz -C /usr/local
      $ cd /usr/local/zookeeper-3.4.13/conf
    
      $ ln -s /usr/local/zookeeper-3.4.13 /usr/local/zookeeper
    
      ## 在你执行启动脚本之前,还有几个基本的配置项需要配置一下,Zookeeper 的配置文件在 conf 目录下,这个目录下有 zoo_sample.cfg 和 log4j.properties,你需要做的就是将 zoo_sample.cfg 改名为 zoo.cfg,因为 Zookeeper 在启动时会找这个文件作为默认配置文件。
      ## 下面详细介绍一下,这个配置文件中各个配置项的意义。
    
      $ cp -pv zoo_sample.cfg zoo.cfg
      $ vim zoo.cfg
      tickTime=2000
      dataDir=/data/zookeeper/zookeeper_data
      clientPort=2181
    
      ## 配置解释
      tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
      dataDir:就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
      clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
    
      $ mkdir -pv /data/zookeeper/zookeeper_data
    
  • 集群模式

    Zookeeper 不仅可以单机提供服务,同时也支持多机组成集群来提供服务。实际上 Zookeeper 还支持另外一种伪集群的方式,也就是可以在一台物理机上运行多个 Zookeeper 实例。

    当然你运行一个zookeeper也是可以的,但是在生产环境中,你最好部署3,5,7个节点。部署的越多,可靠性就越高,zookeeper集群是以宕机个数过半才会让整个集群宕机的,所以奇数个集群更佳。

    Zookeeper 的集群模式的安装和配置也不是很复杂,所要做的就是增加几个配置项。集群模式除了上面的三个配置项还要增加下面几个配置项:

      $ vim /usr/local/zookeeper/conf/zoo.cfg
      initLimit=5
      syncLimit=2
      ## 在zookeeper集群配置文件中,clientPort参数用来设置客户端连接zookeeper服务器的端口。
      ## server.1=IP1:2888:3888中,IP1指的是组成Zookeeper服务器的IP地址,2888为组成zookeeper服务器之间的通信端口,3888为用来选举leader的端口。
      server.1=192.168.211.1:2888:3888
      server.2=192.168.211.2:2888:3888
    
      - initLimit: 由于集群中的包含多台server, 其中一台为leader, 集群中其余的server为follower。 initLimit参数可以配置初始化连接时间, follower和leader之间的最长心跳时间. 此时该参数设置为5, 说明时间限制为5倍tickTime, 即5*2000=10000ms=10s.
      - syncLimit: 该参数配置leader和follower之间发送消息, 请求和应答的最大时间长度. 此时该参数设置为2, 说明时间限制为2倍tickTime, 即4000ms.
      - server.X=A:B:C 其中X是一个数字, 表示这是第几号server. A是该server所在的IP地址. B配置该server和集群中的leader交换消息所使用的端口. C配置选举leader时所使用的端口. 由于配置的是伪集群模式, 所以各个server的B, C参数必须不同.在之前设置的dataDir中新建myid文件, 写入一个数字, 该数字表示这是第几号server. 该数字必须和zoo.cfg文件中的server.X中的X一一对应,例如: ./Users/apple/zookeeper0/data/myid文件中写入0, /Users/apple/zookeeper1/data/myid文件中写入1, /Users/apple/zookeeper2/data/myid文件中写入2.
    

    在dataDir目录下配置myid,这里dataDir目录是/data/zookeeper_data

      $ echo 1 > /data/zookeeper/zookeeper_data/myid
    

    如果有多个节点,那么其他节点就把配置文件同步过去就好,myid里面的值不一样就好。

      ## 如果设置了防火墙,那么应该开启防火墙,例如
      $ iptables -I INPUT -s 192.168.0.0/16 -p tcp --dport 3888 -j ACCEPT
      $ iptables -I INPUT -s 192.168.0.0/16 -p tcp --dport 2888 -j ACCEPT
    
      ## 启动zookeeper服务。
      $ cd /usr/local/zookeeper/bin && ./zkServer.sh start
          or
      $ /usr/local/zookeeper/bin/zkServer.sh start
    
      ## PS: 默认zookeeper的日志会生成在当前目录下,如果需要指定zookeeper日志那么:
      $ vim /usr/local/zookeeper/bin/zkServer.sh
      ZOO_LOG_DIR="/data/zookeeper/zookeeper_logs"
    

参考资料

http://www.iteblog.com/archives/904

https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

http://www.jianshu.com/p/abbc1411ed9d