一、什么是ZooKeeper?
ZooKeeper是Apache旗下开源的分布式协调服务,可以支持分布式配置、分布式同步、命名注册等服务,这是进行分布式系统开发中非常重要的一个软件,本文开始将从源码级来认识ZooKeeper。
二、ZooKeeper安装
第一步:从官网下载对应版本的安装包
第二步:修改conf目录下的zoo_sample.cfg为zoo.cfg
第三步:编辑zoo.cfg 找到dataDir字符配置好对应的位置
第四步:启动zkServer.cmd,此时ZooKeeper就可以正常启动
三、使用
可以通过help指令查看帮助命令:
常用命令介绍如下:
- ls:查看节点信息,后接节点路径,必须以“/”开头,如 ls /
- get:获取节点信息,后接节点路径,必须以“/”开头,如 get /
- create:创建节点信息,节点分为临时节点和永久节点,临时节点的生命周期在于当前的回话,回话结束临时节点也跟着失效,创建临时节点需要加上-e参数,这里还有一个-s参数,表示的是创建带顺序的节点,-t 表示是创建一个带过期时间的节点默认是关闭的,需要zookeeper.extendedTypesEnabled=true进行打开,-c是创建容器节点,容器节点特性是,当容器节点中最后一个子节点被删除,那么容器节点本身也要被删除。
- set :修改节点值,-s表示显示当前节点状态信息,-v表示当前节点版本
- delete:删除节点,-v是表示版本号
- deleteall:删除所有节点
- close:关闭当前会话
- quit:退出当前会话
- addWatch:给某个节点加上事件监听器,-m表示监听器类型,有两个取值PERSISTENT和PERSISTENT_RECURSIVE,默认是后者,如果是新增和删除子节点时:前者返回的事件类型是NodeChildrenChanged后者返回的是NodeCreated,修改自身节点时都是返回NodeDataChanged,如果是子节点前者没反应,后者返回NodeDataChanged。
-stat:列出节点信息 - ACL:权限控制,ZooKeeper中权限控制是针对某个节点,每个节点可以设置多种权限,子节点不继承父节点权限。权限控制一般采用如下方式:scheme🆔permission
secheme:授权模式,有world、auth、digest、ip,world是默认模式,表示所有用户都可以操作,auth,表示已经通过认证的用户(可以通过命令addauth来认证),digest表示需要username和password的认证方式,ip使用客户端的ip作为认证方式
ID:授权对象,也就是当前需要授权的用户或者ip地址等
permission:权限简写是crwda,也就是增删改查管理
ACL的命令有getAcl、setAcl和addauth
getAcl:后接节点路径-s表示列出节点信息,如下图,权限模式是world,id是anyone,权限是cdrwa
setAcl:setAcl path acl,我们主要说说auth和digest模式
auth:我们先创建一个节点 acl,其次我们创建一个授权用户 addauth digest acl:123456,最后设置权限setAcl /acl auth:acl:123456:cdwra,此时,退出重新登录,通过get /acl去获取节点是你就会得到NoAuth for /acl返回,此时需要重新加权限addauth digest acl:123456,这样就可以正常取值。
digest:和auth一样的模式,不同的地方在于密码是通过用户名和原始密码加密之后得到的(加密方式是先sha1后base64)如果要进行删除等操作也需要addauth digest username:password
以上就是简单命令介绍。
数据结构:
ZooKeeper是以树的结构保存数据,每个节点成为znode,他是以键值对的形式存储数据,用get命令去获取一个节点信息如下:
第一行是节点中保存的值,接下来就是节点的信息。
- cZxid:表示创建节点时的事务id
- ctime:创建节点时的时间
- mZxid:最后修改节点的事务id
- mtime:最后修改节点的时间
- pZxid:当前节点中子节点列表变化的事务id(修改子节点内容,这个id不会变)
- cversion:子节点版本号(增加删除子节点时会加1操作)
- dataVersion:数据版本号,修改节点数据的时候,版本号加1
- aclVersion:权限版本号,修改当前节点权限的时候加1
- ephemeralOwner:创建临时节点的sessionId,如果是持久化节点值为0
- dataLength:内容大小
- numChildren:子节点个数
Java api:
ZooKeeper提供了一套原生api,供开发者使用,Netflix 公司也开发了一套开源的ZooKeeper客户端框架Curator,将简单介绍一下这两种api。
原生api:
引入jar包
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
</dependency>
如下就是简单的连接测试代码:
public class ZkTest {
public static void main(String[] args) throws IOException, InterruptedException {
CountDownLatch latch=new CountDownLatch(1);
ZooKeeper zk=new ZooKeeper("127.0.0.1:2181", 10000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getState()== Event.KeeperState.SyncConnected){
latch.countDown();
System.out.println("成功连接!");
}
}
});
//因为连接需要时间,所以需要进行连接等待。
latch.await();
Stat stat=new Stat();
byte[] nn= zk.getData("/zktest",null,stat);
System.out.println(new String(nn));
zk.setData("/zktest","test".getBytes(),stat.getVersion());
nn= zk.getData("/zktest",null,stat);
System.out.println(new String(nn));
}
}
然后我们就可以通过zk对象去进行对应的操作,如果是集群下,我们只需要把集群地址以逗号分隔方式传入即可。
Curator框架:
同样需要引入对应的jar包:
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
如下所示:
public class CuratorTest {
public static void main(String[] args) throws Exception {
CuratorFramework cf= CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").sessionTimeoutMs(10000).retryPolicy(new
ExponentialBackoffRetry(1000,1)).build();
cf.start();
Stat stat=new Stat();
byte[] nn= cf.getData().storingStatIn(stat).forPath("/zktest");
System.out.println(new String(nn));
cf.create().forPath("/zksss","zktttttttttttt".getBytes());
nn= cf.getData().storingStatIn(stat).forPath("/zksss");
System.out.println(new String(nn));
System.out.println(stat.getCtime());
}
}
基本demo比较简单,具体的可以自行研究。
四、源码构建
第一步安装Ant环境,这个比较简单(有的较低版本需要)。
第二步下载源码:https://github.com/apache/zookeeper,本文下载的版本是3.7.0
第三步编译源码,直接导入到Idea中,然后install即可
第四步运行源代码,设置好运行参数,如下所示
五、总结
本文简单介绍了ZooKeeper的安装、命令的简单实用以及api的使用过程,以及源代码的构建过程,后续针对源代码进行分析,从底层逻辑来看ZooKeeper的实现过程。
以上,有任何不对的地方,请留言指正,敬请谅解。