[TOC]java
ZooKeeper致力于提供一个高性能、高可用,且具有严格的顺序访问控制能力的分布式协调服务,是雅虎公司建立,是Google的Chubby一个开源的实现,也是Hadoop和Hbase的重要组件. node
设计目标:算法
CAP理论:一个分布式系统不可能同时知足一致性、可用性和分区容错性这三个 基本需求,最多只能同时知足其中的两项; apache
TIPS:架构师的精力每每就花在怎么样根据业务场景在A和C直接寻求平衡;api
BASE理论:即便没法作到强一致性,但分布式系统能够根据本身的业务特色,采 用适当的方式来使系统达到最终的一致性;缓存
Zookeeper常应用如下场景:bash
序号 | 参数名 | 说明 |
---|---|---|
1 | clientPort | 客户端链接server的端口,即对外服务端口,通常设置为2181 |
2 | dataDir | 存储快照文件snapshot的目录。默认状况下,事务日志也会存储在这里。建议同时配置参数dataLogDir, 事务日志的写性能直接影响zk性能。 |
3 | tickTime | ZK中的一个时间单元。ZK中全部时间都是以这个时间单元为基础,进行整数倍配置的。例如,session的最小超时时间是2*tickTime |
4 | dataLogDir | 事务日志输出目录。尽可能给事务日志的输出配置单独的磁盘或是挂载点,这将极大的提高ZK性能 |
5 | globalOutstandingLimit | 最大请求堆积数。默认是1000。ZK运行的时候, 尽管server已经 没有空闲来处理更多的客户端请求了,可是仍是容许客户端将请求提交到服务器上来,以提升吞吐性能。固然,为了防止Server内存 溢出,这个请求堆积数仍是须要限制下的。(Java system property: zookeeper.globalOutstandingLimit.) |
6 | preAllocSize | 预先开辟磁盘空间,用于后续写入事务日志。默认是64M,每一个事务日志大小就是64M。若是ZK的快照频率较大的话,建议适当减少 这个参数。(Java system property: zookeeper.preAllocSize) |
7 | snapCount | 每进行snapCount次事务日志输出后,触发一次快照(snapshot),此时,ZK会生成一个snapshot.文件,同时建立一个新的事务日志文件log.。 默认是100000.(真正的代码实现中,会进行必定的随机数处理,以避 免 所 有 服 务 器 在 同 一 时 间 进 行 快 照 而 影 响 性 能 )(Java system property: zookeeper.snapCount) |
8 | traceFile | 用于记录全部请求的log,通常调试过程当中可使用,可是生产环境不建 议使用,会严重影响性能。(Java system property:? requestTraceFile) |
9 | maxClientCnxns | 单个客户端与单台服务器之间的链接数的限制,是ip级别的,默认是60若是设置为0,那么代表不做任何限制。请注意这个限制的使用范围,仅仅是单台客户端机器与单台ZK服务器之间的链接数限制,不是针对指定客户端IP,也不是ZK集群的链接数限制,也不是单台ZK对全部客户端的 链接数限制。 |
10 | clientPortAddress | 对于多网卡的机器,能够为每一个IP指定不一样的监听端口。默认状况是所 有IP都监听 clientPort指定的端口。 New in 3.3.0 |
11 | minSessionTimeou tmaxSessionTimeout | Session超时时间限制,若是客户端设置的超时时间不在这个范围,那么会被强制设置为最大或最小时间。默认的Session超时时间是在2* tickTime ~ 20 * tickTime 这 个 范 围 New in 3.3.0 |
12 | fsync.warningthresholdms | 事务日志输出时,若是调用fsync方法超过指定的超时时间,那么会在日志中输出警告信息,默认是1000ms |
13 | autopurge.purgeInterval | 清理任务的时间间隔,单位为hours |
14 | autopurge.snapRetainCount | zkserver启动时会开启一个org.apache.zookeeper.server.DatadirCleanupManager的线程,用于清理"过时"的snapshot文件和其相应的txn log file,此参数用于设定须要被retain保留的文件个数(从QuorumPeerMain跟踪代码) |
15 | electionAlg | 选举算法,默认为3,能够选择(0,1,2,3), 0表示使用原生的UDP(LeaderElection), 1表示使用费受权的UDP 2表示使用受权的UDP(AuthFastLeaderElection) 3基于TCP的快速选举(FastLeaderElection) |
16 | initLimit | Leader与learner创建链接中 socket通信read所阻塞的时间(initLimit * tickTime) 若是是Leaner数量较多或者leader的数量很大, 能够增长此值 |
17 | SyncLimit | learner与leader创建链接中,socket通信read阻塞的时间.其中包括数据同步/数据提交等 |
18 | peerType | zkserver 类型 observer 观察者, participant参与者 ,默认为参与者 |
19 | leaderServes | 系统属性 zookeeper.leaderServes leader是否接受client请求,默认为yes即leader能够接受client的链接,在zk cluster 环境中,当节点数为>3时,建议关闭 |
20 | cnxTimeout | 系统属性:zookeeper.cnxTimeout leader选举时socket链接打开的时长,只有在electionAlg=3有效 |
21 | skipACL | 系统属性:zookeeper.skipACL 默认为no,是否跳过ACL检查 |
22 | forceSync | 系统属性:zookeeper.forceSync 默认yes 在update执行以前,是否强制对操做当即持久写入txn log文件.关闭此选项,会形成服务器失效后,还没有持久化的数据丢失 |
23 | jute.maxbuffer | 每一个节点最大数据量,是默认是1M。这个限制必须在server和client 端都进行设置才会生效。 |
客户端与服务端的一次会话链接,本质是TCP长链接,经过会话能够进行心跳检测和数据传输; 服务器
ZooKeeper的视图结构和标准的Unix文件系统相似,其中每一个节点称为“数据节点”或ZNode,每一个znode能够存储数据,还能够挂载子节点,所以能够称之为“树”网络
特性:session
Zookeeper节点类型
对于持久接地啊和临时节点,同一个Znode下,节点的名称是惟一的 -实现分布式锁的基础
Zookeeper节点状态属性
事件监听器,客户端能够在节点上注册监听器,当特定的事件发生后,zk会通知到感兴趣的客户 端;eventType: NodeCreated、NodeDeleted、NodeDataChanged、NodeChildrenChange
Zk采用ACL(access control lists)策略来控制权限,5种权限:create、read,write,delete,admin。
ACL机制,表示为scheme:id:permissions,第一个字段表示采用哪种机制,第二个id表示用户,permissions表示相关权限(如只读,读写,管理等)。zookeeper提供了以下几种机制( scheme):
world: 它下面只有一个id, 叫anyone, world:anyone表明任何人,zookeeper中对全部人有权限的结点就是属于world:anyone的
auth: 它不须要id, 只要是经过authentication的user都有权限(zookeeper支持经过kerberos来进行authencation, 也支持username/password形式的authentication)
digest: 它对应的id为username:BASE64(SHA1(password)),它须要先经过username:password形式的authentication
ip: 它对应的id为客户机的IP地址,设置的时候能够设置一个ip段,好比ip:192.168.1. 0/16, 表示匹配前16个bit的IP段
super: 在这种scheme状况下,对应的id拥有超级权限,能够作任何事情(cdrwa)
在准备好相应的配置以后能够直接经过zkServer.sh 这个脚本进行服务的相关操做:
使用zkCli.sh -server 127.0.0.1:2181 链接到Zookeeper服务
ls/
复制代码
ls2 /
复制代码
查看当前节点数据并能看到更新次数等数据
create /zk "test"
复制代码
建立一个新的znode节点“zk" 以及与它关联的字符串
get /zk
复制代码
确认znode是否包含建立的字符串
set /zk "zkbak"
复制代码
对zk所关联的字符串进行设置和修改
delete /zk
复制代码
将建立的znode节点进行删除,若是存在子节点则删除会失败
rmr /zk
复制代码
将刚才建立的znode删除,同时删除子节点
quit
复制代码
help
复制代码
获取指定节点的ACL信息
设置指定节点的ACL信息
注册会话受权信息
echo stat|nc 127.0.0.1 2181
复制代码
echo ruok|nc 127.0.0.1 2181
复制代码
echo kill | nc 127.0.0.1 2181
复制代码
echo conf | nc 127.0.0.1 2181
复制代码
echo cons | nc 127.0.0.1 2181
复制代码
echo envi |nc 127.0.0.1 2181
复制代码
echo reqs | nc 127.0.0.1 2181
复制代码
echo wchs | nc 127.0.0.1 2181
复制代码
echo wchc | nc 127.0.0.1 2181
复制代码
echo wchp | nc 127.0.0.1 2181
复制代码
java -cp ../../zookeeper-3.4.6.jar;../../lib/slf4j-api-1.6.1.jar org.apache.zookeeper.server.LogFormatter log.xxxx
复制代码
java -cp ../../zookeeper-3.4.6.jar;../../lib/slf4j-api-1.6.1.jar org.apache.zookeeper.server.SnapshotFormatter snapshot.xxxx
复制代码
zookeeper官方提供的java客户端API;
核心API
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
复制代码
public String void create(final String path, byte data[], List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx)
复制代码
public List<String> void getChildren(final String path, Watcher watcher, Stat stat, Children2Callback cb, Object ctx)
复制代码
public List<String> void getData(final String path, Watcher watcher, Stat stat, DataCallback cb, Object ctx)
复制代码
public Static void setData(final String path, byte data[], int version, StatCallback cb, Object ctx)
复制代码
public Static void exists(final String path, Watcher watcher, StatCallback cb, Object ctx)
复制代码
public void addAuthInfo(String scheme, byte auth[])
复制代码
org.apache.zookeeper.Watcher(KeeperState、EventType)
(1)没有专门的API去注册watcher,依附于增删改查API;
(2)watch是一次性产品
(3)watch的process方法中,可对不一样事件进行处理;
原生客户端开发弊端
开源的zk客户端,在原生API基础上封装,是一个更易于使用的zookeeper客户端; 引入Maven依赖
<!-- zkclient依赖 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
复制代码
核心API
public ZkClient(final String zkServers, final int sessionTimeout,final int connectionTimeout, final ZkSerializer zkSerializer, final long operationRetryTimeout)
复制代码
String create(final String path, Object data, final CreateMode mode)
复制代码
public void createPersistent(String path,boolean createParents,List<ACL> acl)
复制代码
public void createPersistent(String path, Object data, List<ACL> acl)
复制代码
public String createPersistentSequential(String path,Object data,List<ACL> acl)
复制代码
public String createPersistentSequential(String path,Object data,List<ACL> acl
复制代码
public String createEphemeralSequential(String path,Object data,List<ACL> acl)
复制代码
public boolean delete(String path,int version)
复制代码
public boolean deleteRecursive(String path)
复制代码
public List<String> getChildren(String path)
复制代码
public <T> T readData(String path, boolean returnNullIfPathNotExists)
复制代码
public <T> T readData(String path, Stat stat)
复制代码
public void writeData(String path, Object datat, int expectedVersion)
复制代码
public Stat writeDataReturnStat(String path,Object datat,int expectedVersion)
复制代码
public boolean exists(String path)
复制代码
public void addAuthInfo(String scheme, final byte[] auth);
复制代码
public void setAcl(final String path, final List<ACL> acl);
复制代码
开源的zk客户端,在原生API基础上封装,apache顶级项目;
<!-- curator依赖 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
复制代码
序列化支持很差
Curator 核心API
CuratorFrameworkFactory.newClient(String connectString, int sessionTimeoutM int connectionTimeoutMs, RetryPolicy retryPolicy)
复制代码
CuratorFrameworkFactory.builder().connectString("192.168.11.56:2180")
.sessionTimeoutMs(30000).connectionTimeoutMs(30000)
.canBeReadOnly(false)
.retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE))
.build();
复制代码
retryPolicy 链接策略:
RetryOneTime: 只重连一次.
RetryNTime: 指定重连的次数N.
RetryUtilElapsed: 指定最大重连超时时间和重连时间间隔,间歇性重连直到超时或者连接成功.
ExponentialBackoffRetry: 基于"backoff"方式重连,和RetryUtilElapsed的区别是重连的时间间隔是动态
BoundedExponentialBackoffRetry: 同ExponentialBackoffRetry,增长了最大重试次数的控制.
复制代码
client.create().creatingParentIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(aclList)
.forPath(path, "hello, zk".getBytes());
复制代码
client.delete().guaranteed().deletingChildrenIfNeeded()
.withVersion(version).forPath(path)
复制代码
client.getData().storingStatIn(stat).forPath(path);
client.getChildren().forPath(path);
复制代码
client.setData().withVersion(version).forPath(path, data)
复制代码
client.checkExists().forPath(path);
复制代码
Build.authorization(String scheme, byte[] auth)
复制代码
client.setACL().withVersion(version)
.withACL(ZooDefs.Ids.CREATOR_ALL_ACL)
.forPath(path);
复制代码
Cache是curator中对事件监听的包装,对事件的监听能够近似看作是本地缓存视图和远程zk视图的对比过程
- NodeCache 节点缓存用于处理节点自己的变化 ,回调接口NodeCacheListener
- PathChildrenCache 子节点缓存用于处理节点的子节点变化,回调接口 PathChildrenCacheListener
- TreeCache NodeCache和PathChildrenCache的结合体,回调接口TreeCacheListener
复制代码
Collection<CuratorTransactionResult> results = client.transaction().forOperations(operations);
复制代码
public void processResult(CuratorFramework client, CuratorEvent event)
CuratorEventType 事件类型
org.apache.zookeeper.KeeperException.Code
复制代码