1.Zookeeper=文件系统+通知机制 2.Zookeeper特点 1)Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群 2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。所以Zookeeper适合安装奇数台服务器 3)每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的 4)来自同一个Client的更新请求按其发送顺序依次执行 5)数据更新原子性,一次数据更新要么成功,要么失败 6)实时性,在一定时间范围内,Client能读到最新数据 3.数据结构 ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树 每个节点称做一个 ZNode。每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识 4.应用场景 统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线 5.Zookeeper下载安装 (1)安装JDK (2)安装Zookeeper 下载地址:https://zookeeper.apache.org/ tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /opt/ mv apache-zookeeper-3.5.7-bin zookeeper-3.5.7 mv zoo_sample.cfg zoo.cfg mkdir /opt/zookeeper-3.5.7/zkData vim zoo.cfg dataDir=/opt/zookeeper-3.5.7/zkData (3)操作Zookeeper 启动Zookeeper:bin/zkServer.sh start 查看Zookeeper:bin/zkServer.sh status 停止Zookeeper:bin/zkServer.sh stop 启动Zookeeper客户端:bin/zkCli.sh (4)配置参数 tickTime:Zookeeper服务器与客户端心跳时间,单位毫秒 initLimit:初始连接最大心跳次数 syncLimit:同步通信最大心跳次数,超过syncLimit * tickTime,Leader则认为Follwer死掉,从服务器列表中删除Follwer dataDir:保存Zookeeper中的数据路径 clientPort = 2181:客户端连接端口 6.Zookeeper集群操作 (1)关闭防火墙 systemctl stop firewalld systemctl disable firewalld (2)vim /etc/hostname (3)vim /etc/hosts 192.168.91.130 node1 192.168.91.129 node2 192.168.91.128 node3 (4)在/opt/zookeeper-3.5.7/zkData 目录下创建myid文件,vi myid 添加与server对应的编号 (5)vim zoo.cfg server.1=node1:2888:3888 server.2=node2:2888:3888 server.3=node3:2888:3888 参数解读server.A=B:C:D A表示是第几号服务器 B是这个服务器的地址 C是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口 D是用来执行选举时服务器相互通信的端口 (6)reboot后分别启动Zookeeper bin/zkServer.sh start bin/zkServer.sh status 命令行语法: 创建节点: create -e -s /test "test" (-s 节点带序列,-e 临时节点) 获得节点的值:get /test (-s 附加次级信息,-w 监听节点内容变化) 修改节点值:set /test "nice" 删除节点:delete /test (deleteall递归删除节点) 查看子节点:ls /test (-s 附加次级信息,-w 监听子节点变化) 7.选举机制 假设集群有5台服务器,超过半数(3票)选为leader (1)第一次启动 服务器1启动,发起选举,服务器1投自己一票,不够半数以上(3票),选举无法完成,服务器1状态保持为 LOOKING 服务器2启动,发起选举,服务器2投自己一票,服务器2 myid最大,LOOKING状态下的服务器1更改选票投服务器2,此时服务器1=0票,服务器2=2票,没有半数以上结果,选举无法完成,服务器1,2状态保持LOOKING 服务器3启动,发起选举,服务器3投自己一票,服务器3 myid最大,LOOKING状态下的服务器1、2更改选票投服务器3,此次投票结果:服务器1=0票,服务器2=0票,服务器3=3票,服务器3当选Leader,服务器1,2更改状态为FOLLOWING,服务器3更改状态为LEADING 服务器4启动,发起选举,服务器4投自己一票,:服务器3=3票,服务器4=1票,此时服务器4服从多数,更改选票信息为服务器3,并更改状态为FOLLOWING 服务器5启动,同4 (2)非第一次启动,服务器运行期间无法和Leader保持连接 ①Leader存在,某Follwer无法和Leader保持连接,该机器发起选举,会被告知Leader的信息,该机器需要和Leader机器建立连 接,并进行状态同步 ②Leader不存在,发起选举,比较(EPOCH,ZXID,SID) 选举Leader规则: ①EPOCH大的直接胜出 ②EPOCH相同,ZXID大的胜出 ③ZXID相同,SID大的胜出 Epoch:每个Leader任期的代号 ZXID:事务ID,用来 标识一次服务器状态的变更 SID:服务器ID,和myid一致 8.节点信息 (1)查看znode中所包含的内容 ls / (2)查看znode详细数据 ls -s / [zookeeper]cZxid = 0x0 ctime = Wed Dec 31 16:00:00 PST 1969 -> znode被创建的毫秒数 mZxid = 0x0 -> znode最后更新的事务zxid mtime = Wed Dec 31 16:00:00 PST 1969 -> znode最后修改的毫秒数 pZxid = 0x0 -> znode最后更新的子节点事务zxid cversion = -1 -> znode子节点修改次数 dataVersion = 0 -> znode数据变化号 aclVersion = 0 -> znode访问控制列表的变化号 ephemeralOwner = 0x0 -> 临时节点=znode拥有者的session id,不是临时节点=0 dataLength = 0 -> znode的数据长度 numChildren = 1 -> znode子节点数量 (3)znode类型 Persistent:持久,客户端和服务器端断开连接后,创建的节点不删除 Ephemeral:短暂,客户端和服务器端断开连接后,创建的节点删除 创建节点: create -e -s /test "test" (-s 节点带序列,-e 临时节点) 9.监听器原理 1)监听节点的变化 get -w path 2)监听子节点的变化 ls -w path ZK客户端: 创建两个线程,一个负责网络连接通信(connet),一个负责监听(listener) 通过connect线程将注册的监听事件发送给ZK服务端listener线程监听到ZK服务端的通知,调用process()方法 ZK服务端: 将ZK客户端发过来的监听事件添加到监听器列表,有数据或路径变化时通知ZK客户端 10.Zookeeper写数据流程 (1)zookeeper中任意节点收到写请求,如果是follower节点,则会把写请求转发给leader,如果是leader节点就直接进行下一步 (2)leader生成一个新的事务并为这个事务生成一个唯一的ZXID (3)leader将这个事务发送给所有的follows节点 (4)follower节点将收到的事务请求加入到历史队列(history queue)中,并返回ack确认包 (5)当leader收到半数以上的follower的ack消息,leader就进行写入操作,并且发送给所有follower 进行这个写request 持久化操作的commit(也带有这个zxid),当follower接收到commit还会进行一次check(队列中zxid和commit中的zxid比较),正确则进行写入操作,否则去sync leader数据 即leader接受到写请求(标记为zxid)就会发送proposal给所有follower,follower接受到请求先把zxid写入到队列中并返回ack确认包, 当leader收到超过半数follower回传的ack后就进行写入操作,并且发送给所有follower 进行这个写request 持久化操作的commit(也带有这个zxid), 当follower接收到commit还会进行一次check(队列中zxid和commit中的zxid比较),正确则进行写入操作,否则去sync leader数据



