设为首页 收藏本站
查看: 835|回复: 0

[经验分享] Zookeeper功能及应用场景

[复制链接]

尚未签到

发表于 2017-4-19 08:17:27 | 显示全部楼层 |阅读模式
  编写不易,转载请注明(http://shihlei.iteye.com/blog/2075801)!
一概述
 
    Zookeeper是针对大型分布式系统的可靠协调系统。
 
    核心服务总结如下



  • 可靠的协调系统用于存储客户端集群相互协作的信息。(Zookeeper核心机制会保证数据在所有的Zookeeper数据结点的一致性,客户并发修改任何Zookeeper结点的数据效果都是一致的)。

  • 数据变更通知推送:当客户端修改某个数据时,例如:变更,增加,删除(对于瞬时ZNode,客户端失联自动删除ZNode),Zookeeper主动通知监听该数据变化的客户端。

二 数据存储
 

  1)Zookeeper 中存储数据的结点为ZNode 有唯一路径,并有类似于树形的结构


      DSC0000.png
 
  2)ZNode有如下4种类型:



  • PERSISTENT:持久性ZNode,不会随着client session的close/expire而消失。
  • PERSISTENT_SEQUENTIAL:有顺序的持久性ZNode。
  • EPHEMERAL:暂时行ZNode,生命周期依赖于client session,对应session close/expire后其znode也会消失。
  • EPHEMERAL_SEQUENTIAL:有顺序的暂时行ZNode。

  3)ZNode能注册监听,当发生变化时回通知监听的客户端。集群管理,分布式锁都依赖于此。
 
操作ZNode样例:
 

public void run(ZooKeeper zk) throws KeeperException, InterruptedException {
String nodePath = "/TestNode";
byte[] nodeDate = "TestNodeData".getBytes();
// 1 创建znode ,CreateMode.EPHEMERAL 为临时的,客户端断开则无法看到znode信息
// 创建一个znode(必须有父节点)
String result = zk.create(nodePath, nodeDate, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("Create znode at : " + result);
// 2 测试一个znode是否存在,并且查询它的元数据,null表示不存在
Stat stat = zk.exists(nodePath, false);
System.out.println("Create Exist znode : " + stat);
// 3 获取一个znode的ACL,每个znode被创建时都会带有一个ACL列表,用于决定谁可以对它执行何种操作。
System.out.println("ACL List ===============");
List<ACL> aclList = zk.getACL(nodePath, stat);
for (ACL a : aclList) {
System.out.println(a);
}
// 4 获取一个znode的子节点列表
List<String> childs = zk.getChildren(nodePath, false);
for (String c : childs) {
System.out.println(c);
}
// 5.1 设置一个znode所保存的数据
nodeDate = zk.getData(nodePath, false, stat);
System.out.println("NodeDate : " + new String(nodeDate));
// 5.2 设置一个znode所保存的数据
byte[] newNodeDate = "TestNodeData_NewData".getBytes();
// 注:Zookeeper中的更新操作是有条件的。在使用delete或者setData操作时必须提供被更新znode的版本号,如果版本号不匹配,则更新操作失败。
zk.setData(nodePath, newNodeDate, stat.getVersion());
}
 
 
三 应用场景
 



  • 感知集群变化:Client启动在统一目录下时注册EPHEMERAL ZNode,当一台Client当机,其他znode可以收到通知,添加机器同。

  • Master选举:对等机之间选取Master,Master失效后自动重选。实现:Client 创建EPHEMERAL_SEQUENTIAL ZNode,启动时,Sequental 号最小的当选为Master。

  • 集群同步锁:Client 集群间实现同步操作。实现:Client 执行同步操作前创建 EPHEMERAL_SEQUENTIAL ZNode,如果ZNode Sequental 号最小则获得锁执行,否则等待其他Client释放锁。

   同步锁实现:

package x.bd.zookeeper.lock;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
/**
* 共享锁:原理,当客户端要进行某种操作时,在Zookeeper上注册Znode,如果当前序号为自己,则进行处理,处理完成后释放,其他等待处理的线程监控
*
* 这里用不同的Thread 模拟不同的Server
*
* 注:这种锁的概念同样可以应用与Master操作,其他同步的Salver等待
*
* 存在问题:判断锁的时候需要获取最小的锁,排序获得
*
* @author shilei
*
*/
public class LockTest implements Watcher {
private ZooKeeper zk;
// Zookeeper 锁根
private static final String LOCK_ROOT = "/Lock";
// 当前客户端注册锁名
private String lockName;
// 线程锁,用于没有获得执行锁时阻塞
private Integer threadLock = -1;
public LockTest(String server) throws Exception {
zk = new ZooKeeper(server, 3000, this);
}
/**
* 注册锁
*
* @throws Exception
*/
public void lock() throws Exception {
// 注册锁根结点
Stat rootStat = zk.exists(LOCK_ROOT, false);
if (rootStat == null) {
String rootPath = zk.create(LOCK_ROOT, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("Create root : " + rootPath);
}
// 在服务器注册自己的锁
lockName = zk.create(LOCK_ROOT + "/lock_", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("Create lock : " + lockName);
// 循环判断服务器当前锁是否为自己的锁
while (true) {
// 设置观察
List<String> lockList = zk.getChildren(LOCK_ROOT, true);
Collections.sort(lockList);
if (!lockName.endsWith(lockList.get(0))) {
// 当前锁非本服务器注册,等待
synchronized (threadLock) {
threadLock.wait();
}
} else {
// 获得锁成功
return;
}
}
}
/**
* 释放锁
*
* @throws Exception
*/
public void unLock() throws Exception {
Stat stat = zk.exists(lockName, false);
if (stat != null) {
zk.delete(lockName, stat.getVersion());
}
}
/**
* 竞争锁
*/
public void process(WatchedEvent event) {
// 事件发生在锁目录上
String path = event.getPath();
if (path != null && path.startsWith(LOCK_ROOT)) {
// 监控的是root node 需要判断node children changed 事件
if (event.getType() == Event.EventType.NodeChildrenChanged) {
// 事件类型为锁删除事件,激活锁判断
synchronized (threadLock) {
threadLock.notify();
}
}
}
}
public void shutdown() throws InterruptedException {
zk.close();
}
/**
* 期望结果:线程处理过程没有多个线程的嵌套流程
*/
public static void main(String[] args) throws Exception {
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
public void run() {
try {
String server = "8.8.8.13:2181";
LockTest lockTest = new LockTest(server);
// 注册锁
lockTest.lock();
// 执行获取锁后的任务
System.out.println("Thread : " + Thread.currentThread().getId() + " start ! ");
Thread.sleep(1000 + new Random().nextInt(5000));
System.out.println("Thread : " + Thread.currentThread().getId() + " finish ! ");
// 获取锁后的任务执行完毕,释放
lockTest.unLock();
lockTest.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}

 
 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-366105-1-1.html 上篇帖子: zookeeper系列之概要介绍 下篇帖子: How to read zookeeper object
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表