Contents
zookeeper简介
zookeeper是一个开源的分面式协调服务,由知名互联网公司Yahoo创建,它是Chubby的开源实现;换句话讲,zk是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于它实现数据的发布/订阅、负载均衡、名称服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列;
- 它是一个中间件,提供协调服务
两台电脑中,插入一台新的电脑,帮助其他两台来提供服务,提供计算、缓存、传递的作用。
- 作用于分布式系统,发挥其优势,可以为大数据服务
-
支持Java,提供给Java和C语言提供了API
什么是分布式系统?
- 很多台计算机组成的一个整体,一个整体一致对外并且处理同一个请求
-
是一个硬件或软件组件分布在网络中的不同的计算机之上,彼此间仅通过消息传递进行通信和协作的系统。
-
内部的每一台计算机都可以相互之间通信(rest/rpc)
-
客户端到服务器的一次请求到响应结束会经历很多台计算机的处理
特征
- 分布性、对等性、并发性、缺乏全局时钟、故障必然发生
典型问题
- 通信异常、网络区分、三态(成功、失败、超时)、节点故障
zookeerper
的特性
- 一致性:数据具有一致性,数据按照顺序分批入库
-
原子性:事务要么全部成功要么全部失败,不会出现数据不一致的情况
-
单一视图:客户端连接集群中的任意一个节点数据都是一致的
-
可靠性:每一次的操作的状态都可以保存在服务端
-
实时性:客户端可以读取到服务端的最新数据
zookeeper的作用
- master节点选举,主节点挂了以后,从节点就会接手工作,并且保证这个节点是唯一的,这也是所谓首脑模式,从而保证我们的集群式高可用的
-
统一配置文件管理,只需要部署一台服务器,则可以把相同的配置文件同步更新到其他的所有服务器,云计算中使用较多(修改了就统一配置文件)
- 发布与订阅,类似信息消息队列MQ(amq,rmq),dubbo发布者把数据存在node上,订阅会读取这个数据
-
提供分布式锁,分布式环境中不同进程之间争夺资源,类似于多个线程中的锁
- 集群管理,集群中保证数据的强一致性
session的基本原理
- 客户端与服务端之间的连接存在会话
-
每一个会话都可以设置一个超时时间
-
心跳结束,session则过期
-
Session过期,则临时检点znode会被抛弃
-
心跳机制:客户端向服务端的ping包请求
基本的概念
1.集群的角色
- Leader:选举产生,读/写
-
Follower:参与选举,可以被选举,读服务
-
Observer:参与选举,不可以被选举,提供读服务
2.会话的概念
- 客户端 <—TCP长连接—> 服务端
3.数据节点
- ZNode:zk数据模型中的数据单元,zk的数据都存储与内存之中,数据模型为树状结构(ZNode Tree),每一个ZNode都会保存自己的数据在内存中
-
持久节点:仅显示删除才消失
-
临时节点:会话终止自动消失
4.版本
- zk会为每一个ZNode维护一个称为stat的数据结构,记录了当前ZNode的三个数据版本
-
VERSION:当前的版本
-
CVERSION:当前ZNode的子节点的版本
-
AVERSION:当前ZNode的ACL版本
5.ACL
- ZK使用ACL机制进行权限控制
-
CREATE、READ、WRITE、DELETE、ADMIN
6.事件监听器(Watcher)
- ZK上,由用户指定的触发机制,在某一些事件产生时候,ZK能够将通知给相关的客户端
7.ZAB协议
- Zookeeper Atomic Broadcast,ZK原子广播协议
-
ZAB协议中存在的三种状态
- (1)Looking
-
(2)Following
-
(3)Leading
-
四个阶段
- 选举:election
-
发现:discovery
-
同步:sync
-
广播:Broadcast
8.应用场景
- 典型应用场景:
- 数据发布/订阅
-
负载均衡
-
命名服务
-
分布式协调/通知
-
集群管理
-
Master选举
Zookeeper的部署
- 部署方式:单机模式、伪分布式模式、分布式模式
JDK的安装
官方下载JDK或者使用openjdk,YUM或源码编译看自己情况
java -version
单机zookeeper部署
- 官方地址:http://zookeeper.apache.org/releases.html
zoo.cfg
- tickTime-用于计算的时间单元,例如session超时:N* tickTime
-
initLimit-用于集群,允许从节点连接并且同步到master节点的初始化连接时间,以tickTime的倍数来表示
-
syncLimit-用于集群,master主节点与从节点之间发送消息,请求和应答的时间长度
-
dataDir-必须配置
-
dataLogDir-如果不配置就会和dataDir共用
-
clientPort-连接服务器的端口
1.zoo.cfg配置参数:
tickTime=2000
dataDir=/data/zookeeper
ClientPort=2181
initLimit=5
syncLimit=2
2.指定主机的语法格式:
server.ID=IP:port:port
ID:各主机的数字标识,一般从1开始
IP:各主机的IP
3.zoo.cfg配置文件参数
基本配置参数:
clientPort=2181
dataDir=/data/zookeeper
dataLogDir:事务日志文件路径;
tickTime:
存储配置:
preAllocSize:为事务日志预先分配的磁盘空间量;默认65535KB;
snapCount:每多少次事务后执行一次快照操作;每事务的平均大小在100字节;
autopurget.snapRetainCount:
autopurge.purgeInterval:purge操作的时间间隔,0表示不启动;
fsync.warningthresholdms:zk进行事务日志fsync操作时消耗的时长报警阈值;
weight.X=N:判断quorum时投票权限,默认1;
网络配置:
maxClientCnxns:每客户端IP的最大并发连接数;
clientPortAddress:zk监听IP地址;
minSessionTimeout:
maxSessionTimeout:
集群配置:
initLimit:Follower连入Leader并完成数据同步的时长;
syncLimit:心跳检测的最大延迟;
leaderServes:默认zk的leader接收读写请求,额外还要负责协调各Follower发来的事务等;因此,为使得leader集中处理zk集群内部信息,建议不让leader直接提供服务;
cnxTimeout:Leader选举期间,各服务器创建TCP连接的超时时长;
ellectionAlg:选举算法,目前仅支持FastLeaderElection算法一种;
server.id=[hostname]:port:port[:observer]
集群内各服务器的属性参数
第一个port:follower与leader进行通信和数据同步时所使用端口;
第二个port:leader选举时使用的端口;
observer:定义指定的服务器为observer;
注意:运行为集群模式时,每个节点在其数据目录中应该有一个myid文件,其内容仅为当前server的id;
Zookeeper基本数据模型
- (1)是一个树形结构,类似于前端开发中的Tree.js组件
-
(2)zookerper的数据模型也可以理解为linux/unix的文件目录
-
(3)每一个节点都称为Node,它可以有子节点,也可以有数据
-
(4)每一个节点分为一个临时节点和永久节点,临时节点在客户端断开
-
(5)每一个zookerper节点都是各自的版本号,可以通过命令行来显现节点信息
-
(6)每当节点数据发生变化,那么该节点的版本号会累加(乐观锁)
-
(7)删除/修改过时节点,版本号不匹配则会报错
-
(8)每一个Zookeeper节点存储的数据不宜过大,一般几K
-
(9)节点可以设置权限ACL,可以通过权限来限制用户访问
模型的基本操作
- 客户端连接
-
查看node结构
-
关闭客户端连接
Zookeeper常用的命令操作
常用的命令:
- create, ls, ls2, stat, delete, rmr, get, set
监控zk的四字命令
- ruok, stat, srvr, conf, cons, wchs, envi
查看与创建
- 通过./zkcli.sh打开客户端的命令后台,连接到本地
create -e /ddy/tmp ddy-data #创建一个临时的文件,当session超时一段时间后自动的删除
create -s /ddy/sec set seq #创建临时节点或者顺序节点,持久的
set /ddy 值 版本号 #乐观锁
delete path 版本号 #不设置版本号直接删除节点,设置只删除版本号
watcher机制
- 针对每一个节点的操作,都会有一个监督者 -> watcher(事件)
-
当监控的某一个对象(znode)发生了变化,相当于触发器触发watcher事件
-
zk中的watcher是一次性的,触发后立即销毁
-
父节点、子节点增删改都能够触发watcher
-
针对不同类型的操作,触发的watcher时间也不同
- 1.(子节点)创建事件
- 2.(子节点)删除事件
- 3.(子节点)数据变化事件
watcher命令
- 通过get path [watch]设置watcher
-
父节点增删改查操作触发watcher
-
子节点增删改查操作触发watcher
watcher事件类型
- 创建父节点触发:NodeCreate
- 修改父节点数据触发:NodeDataChanged
- 删除父节点触发:NodeDeleted
-
为父节点设置watcher,创建/删除子节点触发:NodeChildrenChanged
- 为父节点创建watcher,修改子节点不会触发watch事件(如果想触发设置get)
watcher使用场景
- 统一资源配置(减少人为失误)
ACL权限控制
Access control lists
- 针对节点可以设置相关读写等权限,目的微课保障数据安全性
-
权限permissions可以指定不同的权限范围以及角色
ACL的命令行
- getacl:获取某一个节点的acl权限信息
-
setacl:设置某一个节点的acl权限信息
-
addauth:输入认证授权信息,注册时输入明文密码(登入),但是在ZK上的系统里面,密码是以加密的形式存在的
-
zk的acl通过[ scheme : id : permissions ]来构成权限列表
- scheme:代表采用的某种权限机制
(1)world:world下只有一个ID,即只有一个用户,也就是anyone,那么组合的写法就是world:anyone:[permissions]
(2)auth:代表认证登入,需要注册用户有权限就可以,形式为auth:user:password:[permissions]
(3)digest:需要对密码加密才能够访问,组合形式为,digest:username:BASE64(SHA1(password)):[permissions]
(4)ip:当设置为IP指定的IP地址,此时限制IP进行访问
(5)super:代表超级管理员,所有权限
auth和digest的区别:
前者是明文,后者是密文
setAcl/path auth:lee:lee:cdrwa
setAcl/path digest:lee:BASE64(SHA1(password))cdrwa
是等价的,再通过addauth digest lee:lee后都能操作指定节点的权限
- id:代表允许访问的用户
-
permissions:权限组合字符串
权限字符串缩写crdwa
-> create:创建子节点
-> READ:获取节点/子节点
-> WRITE:设置节点数据
-> DELETE:删除子节点
-> ADMIN:设置权限
Acl使用场景
- 开发、测试环境的分离,开发者无权限操作测试库的节点,只允许读
-
生产环境上控制指定的IP的服务可以访问相关的节点,防止混乱
zk的控制插件
-
zk可以通过它自身提供的简写命令来和服务器进行交互
-
需要安装nc命令
-
echo [commond] | nc [ip] [port]
-
官方文档:http://zookeeper.apache.org/doc/r3.4.13/zookeeperAdmin.html#sc_zkCommands
常用的命令
common | 作用 |
---|---|
stat | 查看zk的状态信息,以及是否mode |
ruok | 查看当前的zookeeper是否启动,返回imok(are you ok?)->(i am ok!) |
dump | 列出未经处理的会话和临时节点 |
conf | 查看服务器的相关配置 |
cons | 显示连接到客户顿的信息 |
envi | 显示zookeeper的环境变量信息 |
mntr | 监控zk的健康信息 |
wchs | 查看watch的信息 |
wchc、wchp | session与watch及path与watch的信息 |
Someone essentially assist to make seriously posts I would state. This is the first time I frequented your website page and so far? I surprised with the analysis you made to create this actual publish incredible. Magnificent activity!
Somebody essentially assist to make severely articles I might state. This is the very first time I frequented your website page and thus far? I amazed with the analysis you made to create this particular publish amazing. Great job!
Good site! I truly love how it is simple on my eyes and the data are well written. I am wondering how I might be notified when a new post has been made. I have subscribed to your RSS feed which must do the trick! Have a nice day!
It’s in reality a nice and useful piece of information. I’m happy that you simply shared this useful info with us. Please keep us informed like this. Thanks for sharing.
You made various nice points there. I did a search on the matter and found nearly all folks will go along with with your blog.