Zookeeper笔记

来源:互联网 发布:点点虫 知乎 编辑:程序博客网 时间:2024/06/06 03:08

前言

名词解释

  • Leader:管理集群用,写的请求会先Forward到Leader,然后由Leader来通过ZooKeeper中的原子广播协议,将请求广播给所有的Follower,Leader收到一半以上的写成功的Ack后,就认为该写成功了,就会将该写进行持久化,并告诉客户端写成功了
  • Follower:处理及响应客户端请求,如果是写的请求,会先Forward到Leader端
  • Client:请求的发起方
  • Session:Client和Zookeeper之间通信会创建Session
  • Watcher:ZooKeeper支持一种Watch操作,Client可以在某个ZNode上设置一个Watcher,来Watch该ZNode上的变化。如果该ZNode上有相应的变化,就会触发这个Watcher,把相应的事件通知给设置Watcher的Client。需要注意的是,ZooKeeper中的Watcher是一次性的,即触发一次就会被取消,如果想继续Watch的话,需要客户端重新设置Watcher
  • Recovery:集群的启动和恢复
  • Broadcast:广播,如果有数据变动时,Leader会广播给其他Server
  • Looking:寻找Leader的状态
  • Following:Follower对应的状态
  • Leading:Leader对应的状态
  • Observing:Observer对应的状态

基础

1.zookeeper配置文件中常用配置解读

  • tickTime:服务器之间或者客户端和服务器之间的心跳间隔(单位:毫秒)
  • initLimit:Follower与Leader之间初始连接时能容忍的最多心跳数(tickTime的数量)
  • syncLimit:Follower与Leader之间请求和应答之间能容忍的最多心跳数(tickTime的数量)
  • dataDir:数据文件目录
  • dataLogDir:日志文件目录
  • clientPort:客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求
  • 另:服务器列表,各服务器之间都相同
    server.[myid]=[IP地址][通信端口][选举端口]
    1)myid即当前Server的serverid,简称sid,将本台Server的myid值写入dataDir目录创建的myid文件中,
    例:echo ‘1’ > dataDir/myid
    说明当前的Server的sid为1
    2)IP地址即当前服务器的IP地址
    3)通信端口,如果当前Server成为Leader,则用于监听来自Follower的请求
    4)选举端口,每个Server都需要监听,用于Server之间选举Leader时通信用

2.简单命令

  • 启动:zkServer.sh start
  • 查看状态:zkServer.sh status
  • 客户端连接:zkCli.sh

进阶

工作过程

  • Server启动,加载配置,并将历史数据加载到内存中
  • 选举Leader,过程见Leader选举
  • Leader与集群中各Follower之间同步数据,如果出错,将重新执行选举Leader步骤
  • 具体工作,如果Follower接收到客户端的读请求,则直接返回,如果收到写请求,将告知Leader,由Leader广播给所有Follower,当半数以上Follower给予成功响应后,则返回给客户端写入成功。

Leader选举

FastLeaderElection算法

FastLeader算法也是Zookeeper种Leader选举的默认算法,一个集群环境的Zookeeper,在启动或者异常时都会选举一个实例作为Leader,这个Leader可以协调集群中的一些事务,下面来看看是如何选举Leader的:

  • 集群中的多台Server,在第一次选举发起时都会推荐自己为Leader(推荐信息包含:zxid[最大数据号,此号为递增的,最大代表最新,zxid64位,前32位是epoch(可以想象为时间戳或操作序号)值,后32位是zxid],sid[serverid]),每次收到其他更好(更好:有个简单的规则,zxid即持有数据最新,即sid越大)的推荐Server时,会更新当前被推荐的Server,并广播给其他Server进行投票,直到拥有N/2 + 1票数通过为止。当一个新的Server加入集群时,也会触发Leader选举,只不过其它Server会将当前Leader是谁直接告诉新加入的节点。

  • 举例说明:假如有三台服务器,即sid分别为1、2、3,此时先启动sid为1的服务器,由于只有一台服务器,此时该服务器为Looking
    状态。于是我们启动sid为2的服务器,这时sid为2的服务器将发起投票,推荐自己为Leader,但由于无法得到半数以上的投票,因此不能成为Leader,即进入Looking状态。于是我们再启动sid为3的服务器,这时sid为3的服务器跟2相同,推荐自己为Leader,由于三台服务器上都不存在旧的数据,但sid为3的服务器id最大,因此会成为新的Leader。当然如果有四台服务器,但是由于第三台启动时已经选举出Leader,则sid为4的服务器启动时,会直接告知其选举结果

源码

QuorumPeerMain

Zookeeper Server启动类

main方法

参数

String[] args
此参数只包含一个配置文件,即zoo.cfg的路径。

initializeAndRun方法

参数

String[] args
此参数只包含一个配置文件,即zoo.cfg的路径。

调用方

main方法

解析
  • 解析zoo.cfg配置文件,存入QuorumPeerConfig
  • 启动定期清理snapshot文件的任务,DatadirCleanupManager
    如果想使此任务正常执行,须在zoo.cfg中配置两个属性:
    1)snap保存条数,即清理后最多保存几条,默认3条,且不能小于3条
    autopurge.snapRetainCount=3
    2)自动清理时间间隔,单位:小时,且不能小于0
    #autopurge.purgeInterval=1
    3)也可手动清理,命令如下:
    java -cp zookeeper.jar:log4j.jar:conf org.apache.zookeeper.server.PurgeTxnLog <dataDir> <snapDir> -n <count>

runFromConfig方法

参数

QuorumPeerConfig config
Zookeeper配置对象。

调用方

initializeAndRun方法

解析
  • 启动服务线程之前,都会创建ServerCnxnFactory并启动,此线程(NIO Server)用于接收客户端请求
  • 启动服务线程,如果server数超过1个,即集群的情况下,则以主线程(集群方式)启动此服务;否则会以standalone mode方式启动,即单机
  • 投票决策方式,QuorumVerifier,包含两种:
    1)QuorumMaj,即常用的N/2 + 1,过半即可
    2)QuorumHierarchical,如果配置了group才以此种方式决策,不想研究,偷个懒

QuorumPeer

Zookeeper线程类

start方法

Zookeeper线程启动

参数

调用方

QuorumPeerMain.runFromConfig方法

loadDataBase方法

加载本地数据(此方法处理逻辑中包含故障恢复时的相关处理,此处标记,暂不赘述)

参数

调用方

start方法

cnxnFactory.start()方法

启动接收客户端请求的线程

参数

调用方

start方法

startLeaderElection方法

选举Leader

参数

调用方

start方法

0 0
原创粉丝点击