一、搭建zk集群
1. 去ZK的官网下载最稳定版本http://apache.fayea.com/zookeeper/zookeeper-3.4.9/
2. tar -zxvf zookeeper-3.4.9.tar.gz
3. 将解压缩出来的文件复制三份分别当成节点1,2,3
4. 修改conf/zoo_sample.cfg -> conf/zoo.cfg 里面需要修改port与dataDir这两个配置项的值
5. 注意机器上面必须要先安装Java包.
6. 启动 # ./zookeeper-3.4.9-node1/bin/zkServer.sh start
可以看到机器上面运行了三个ZK进程形成一个集群.
二、关于ZK
2.1 ZK是一个简单易用、高效可靠的分布式协调系统,在离线系统中有着举足轻重的作用。ZK集群中不存在单点情况,即使Leader服务器挂了,集群的选举算法也可以快速从可用的服务器中自动选出一个leader。一个ZK集群只要满足集群中有一半以上的机器可用,集群即可正常提供服务,所以搭建ZK集群,都会采用奇数台服务器。
2.2 每台服务器都保存有完整的数据,一台服务器挂了,会自动从leader同步最新的数据,保证数据的一致性。
2.3 client访问一台服务器失败后,会自动和下一台可用机器创建连接,保证客户端连接的可用性。
ZK的问题:
1. zk的client连接具有高可用性,一个服务器不可用会切换到下一个服务器,但是一个zk节点操作因连接问题失败时,需要用户自己进行单个操作的failover重试。
2. 节点内容长度有限,只能存储一些较小的统计信息。节点内容长度过长会被截断。
3. 数据持久化对磁盘要求较高,要保证服务,通常数据操作日志目录和snapshot目录需要单独放在一个磁盘中,以免影响数据备份、持久化速度。
ZK管理
1. 权限控制
ZK的权限控制主要通过ACL机制进行,一个ACL信息包括三个信息:permission/schema/id. ACL校验就是根据指定的schema算法,通过给定id在节点ACL信息中进行对比校验,校验成功则用户有ACL对应的权限。
三、看看client如何接入ZK并使用
3.1 引入客户端依赖包
org.apache.zookeeper
zookeeper
3.5.3-beta
public class ZooKeeperOperator implements Watcher {
public ZooKeeper zooKeeper;
private static final int SESSION_TIME_OUT = 2000;
private CountDownLatch countDownLatch = new CountDownLatch(1);
public void connectZookeeper(String host) throws IOException, InterruptedException {
zooKeeper = new ZooKeeper(host, SESSION_TIME_OUT, this);
countDownLatch.await();
System.out.println("连接ZK成功");
}
/***
* 实现watcher接口方法,当连接ZK成功后,ZK会通过此方法通知 watcher
* 如果接受到连接成功的event,则countDown让当前线程继续其他事情
* @param watchedEvent
*/
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == KeeperState.SyncConnected) {
System.out.println("watcher received event");
countDownLatch.countDown();
}
}
public String createNode(String path, byte[] data) throws KeeperException, InterruptedException {
return this.zooKeeper.create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public byte[] getData(String path) throws KeeperException, InterruptedException {
return this.zooKeeper.getData(path, false, null);
}
public void deletNode(String path, int version)
throws InterruptedException, KeeperException {
this.zooKeeper.delete(path, version);
}
public void closeConnect() throws InterruptedException {
if (null != zooKeeper) {
zooKeeper.close();
}
}
}
public class Client {
public static void main(String[] args) throws KeeperException, InterruptedException, IOException {
ZooKeeperOperator zooKeeperOperator = new ZooKeeperOperator();
String host = "11.xxx.xxx.xxx:2181";
zooKeeperOperator.connectZookeeper(host);
System.out.println("连接ZK成功");
byte [] data = {1, 2, 3, 4, 5};
String result = zooKeeperOperator.createNode("/test", data);
System.out.println(result);
byte[] nodeData = zooKeeperOperator.getData("/test");
System.out.println(Arrays.toString(nodeData));
}
}
a. 看看如何用ZK实现分布式锁
这个结合定时任务可以实现集群定时任务管理.
b. 看看如何用ZK实现分布式任务调度