ZooKeeper详细笔记-基础概念安装部署篇

简介

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

ZooKeeper包含一个简单的原语集,提供Java和C的接口。

ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在$zookeeper_home\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。

功能

  • 记录数据
  • 支持数据读取
  • 支持监听通知机制

特点

简单

Zookeeper的核心是一个精简的文件系统,它支持一些简单的操作和一些抽象操作,例如,排序和通知。

丰富

Zookeeper的原语操作是很丰富的,可实现一些协调数据结构和协议。例如,分布式队列、分布式锁和一组同级别节点中的“领导者选举”。

高可靠

Zookeeper支持集群模式,可以很容易的解决单点故障问题。

松耦合交互

不同进程间的交互不需要了解彼此,甚至可以不必同时存在,某进程在zookeeper中留下消息后,该进程结束后其它进程还可以读这条消息。

资源库

Zookeeper实现了一个关于通用协调模式的开源共享存储库,能使开发者免于编写这类通用协议。

作用

  1. 分布式系统中的主节点选举!  比如hbase中的老大的产生 Hmaster(HA)
  2. 分布式系统中的主从节点感知!
  3. 分布式系统中的配置文件同步!
  4. 系统服务器的动态上下线感知!!!
  5. 分布式系统中的分布式的实现!分布式中的同一个对象
  6. 分布式系统中的名称服务!
  7. 分布式系统中的负载均衡! ...

Zookeeper的功能其实很简单:就是提供协调服务!

协调服务具体来说有三方面:

  1. 帮使用者存储一些状态信息
  2. 帮使用者读取一些信息
  3. 帮使用者监视一些信息的变化,并将变化作为事件通知给使用者

角色

 » 领导者(leader),负责进行投票的发起和决议,更新系统状态
  » 学习者(learner),包括跟随者(follower)和观察者(observer),follower用于接受客户端请求并想客户端返回结果,在选主过程中参与投票
  » Observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度
  » 客户端(client),请求发起方

Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协
     议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者
   崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后
    ,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

  • 为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(
   proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识
     leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的
   统治时期。低32位用于递增计数。
  • 每个Server在工作过程中有三种状态:
    LOOKING:当前Server不知道leader是谁,正在搜寻
    LEADING:当前Server即为选举出来的leader
    FOLLOWING:leader已经选举出来,当前Server与之同步

  其他文档:http://www.cnblogs.com/lpshou/archive/2013/06/14/3136738.html

数据存储

Zookeeper维护一个类似文件系统的数据结构:

每个子目录项如 NameService 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。

有四种类型的znode:

  • PERSISTENT-持久化目录节点

    客户端与zookeeper断开连接后,该节点依旧存在

  • PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点

    客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

  • EPHEMERAL-临时目录节点

    客户端与zookeeper断开连接后,该节点被删除

  • EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

    客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

数据读写

    » Zookeeper是一个由多个server组成的集群
  » 一个leader,多个follower
  » 每个server保存一份数据副本
  » 全局数据一致
  » 分布式读写
  » 更新请求转发,由leader实施

Zookeeper 的保证 

  » 更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行
  » 数据更新原子性,一次数据更新要么成功,要么失败
  » 全局唯一数据视图,client无论连接到哪个server,数据视图都是一致的
  » 实时性,在一定事件范围内,client能读到最新数据

Zookeeper节点数据操作流程

       

    注:1.在Client向Follwer发出一个写的请求

      2.Follwer把请求发送给Leader

      3.Leader接收到以后开始发起投票并通知Follwer进行投票

      4.Follwer把投票结果发送给Leader

      5.Leader将结果汇总后如果需要写入,则开始写入同时把写入操作通知给Leader,然后commit;

      6.Follwer把请求结果返回给Client

      

     Follower主要有四个功能:
    • 1. 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
    • 2 .接收Leader消息并进行处理;
    • 3 .接收Client的请求,如果为写请求,发送给Leader进行投票;
    • 4 .返回Client结果。
     Follower的消息循环处理如下几种来自Leader的消息:
    • 1 .PING消息: 心跳消息;
    • 2 .PROPOSAL消息:Leader发起的提案,要求Follower投票;
    • 3 .COMMIT消息:服务器端最新一次提案的信息;
    • 4 .UPTODATE消息:表明同步完成;
    • 5 .REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
    • 6 .SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。

选举机制

Leader选举过程(以3个节点的集群为例):

注:每个节点的配置文件中都有一个自己的独一无二的id

zookeeper的进程在不同的工作模式下,有不同的通信端口(比如选举时,通过端口3888通信;作为leader或者follower接收客户端请求时通过端口2181;leader和follower之间通信用2888)

注意在zk集群安装的时候 会人为的为每台机器分配一个唯一的id

集群初次启动时的选举流程

  1. 第一台机器(id=1)启动,发现没有leader,进入投票模式,投自己,并收到自己投这一票,得1票,不能当选leader(当leader的条件是,集群机器数量过半的票数
  2. 第2台机器(id=2)启动,发现没有leader,进入投票模式,投自己(因为自己的id>1 收到的另一台机器的票的id)
  3. 第1台机器收到2的票,发现集群中有一个比自己id大的机器上线了,重新投票,投id=2
  4. 第2台收到的得票数为2票,过半数,自己当选,切换模式:Leader模式
  5. 第1台就发现有Leader存在了,自己切换模式:Follower
  6. 第3台启动,发现有Leader,自动进入Follower状态

如果每个节点是同时启动的zk  同时选举自己 ,同时广播  , 同时获取别人的广播,3机器会当选

集群在运行过程中的选举流程

  1. 在某个时间点上,id=2机器挂了(leader),别的机器发现没有leader了,全体进入投票模式
  2. 先投自己,票中会携带(自己的id,自己的数据的版本号
  3. 大家都投数据版本最新的节点做leader,如果有多个节点数据版本一样,则从中选id最大的那个作为投票目标!

Zookeeper安装部署

  1. 上传安装包并解压

tar -zxf zookeeper-3.4.6.tar.gz -C /opt/apps/

修改配置文件

  •  mv  zoo_sample.cfg   zoo.cfg
  • vi zoo.cfg

dataDir=/usr/apps/zookeeper-3.4.6/zkData

# Set to "0" to disable auto purge feature

#autopurge.purgeInterval=1

server.1=linux01:2888:3888

server.2=linux02:2888:3888

server.3=linux03:2888:3888

  在各个节点上,手动创建数据存储目录

[root@spark01 apps]# mkdir -p /opt/appdata/zkdata/

[root@spark02 apps]# mkdir -p /opt/appdata/zkdata/

[root@spark02 apps]# mkdir -p /opt/appdata/zkdata/

在各个节点的数据存储目录中,生成一个myid文件,内容为它的id

[root@doit001~]# echo 1 > /usr/apps/zookeeper-3.4.6/zkData/myid

[root@doit002~]# echo 2 > /usr/apps/zookeeper-3.4.6/zkData/myid

[root@doit003~]# echo 3 > /usr/apps/zookeeper-3.4.6/zkData/myid

分发安装包

[root@spark01 apps]# scp -r zookeeper-3.4.6/ spark02:/opt/apps

[root@spark01 apps]# scp -r zookeeper-3.4.6/ spark03:/opt/apps

启动集群

zookeeper没有自带一个批启脚本,只能手动在每一台节点上一个一个地启动

每台机器都执行

bin/zkServer.sh start   zk服务启动

bin/zkServer.sh statuszk 查看服务状态

bin/zkServer.sh stop   zk停止服务

[root@doit01 bin]# ./zkServer.sh  status

JMX enabled by default

Using config: /usr/apps/zookeeper-3.4.6/bin/../conf/zoo.cfg

Mode: follower

也可以自己开发一个批启动脚本:


#!/bin/bash

for i in 1 2 3

do

ssh linux0${i} "source /etc/profile;/opt/apps/zookeeper-3.4.6/bin/zkServer.sh $1"

done



sleep 2



if [ $1 == start ]

then

for i in {1..3}

do

ssh doit0${i} "source /etc/profile;/opt/apps/zookeeper-3.4.6/bin/zkServer.sh status "

done

fi

猜你喜欢

转载自blog.csdn.net/qq_37933018/article/details/106648849