`

Zookeeper功能及应用场景

阅读更多

编写不易,转载请注明(http://shihlei.iteye.com/blog/2075801)!

一概述

 

    Zookeeper是针对大型分布式系统的可靠协调系统。

 

    核心服务总结如下

  1. 可靠的协调系统用于存储客户端集群相互协作的信息。(Zookeeper核心机制会保证数据在所有的Zookeeper数据结点的一致性,客户并发修改任何Zookeeper结点的数据效果都是一致的)。
  2. 数据变更通知推送:当客户端修改某个数据时,例如:变更,增加,删除(对于瞬时ZNode,客户端失联自动删除ZNode),Zookeeper主动通知监听该数据变化的客户端。

二 数据存储

 

  1)Zookeeper 中存储数据的结点为ZNode 有唯一路径,并有类似于树形的结构
     
 
  2)ZNode有如下4种类型:
  1. PERSISTENT:持久性ZNode,不会随着client session的close/expire而消失。
  2. PERSISTENT_SEQUENTIAL:有顺序的持久性ZNode。
  3. EPHEMERAL:暂时行ZNode,生命周期依赖于client session,对应session close/expire后其znode也会消失。
  4. 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());
	}

 

 

三 应用场景

 

  1. 感知集群变化:Client启动在统一目录下时注册EPHEMERAL ZNode,当一台Client当机,其他znode可以收到通知,添加机器同。
  2. Master选举:对等机之间选取Master,Master失效后自动重选。实现:Client 创建EPHEMERAL_SEQUENTIAL ZNode,启动时,Sequental 号最小的当选为Master。
  3. 集群同步锁: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();
		}
	}
}

 

 

  • 大小: 8.2 KB
分享到:
评论

相关推荐

    Zookeeper 进阶之——典型应用场景(一)1

    Zookeeper 却很容易实现这个功能,实现方式也是需要获得锁的 Server 创建一个 EPHEMERAL_SEQUENTIAL 目录节点,然后调用 get

    java高级软件工程师教程快速入门Zookeeper+dubbo视频教程

    本套课程中,第一阶段深入Zookeeper原理和源码,分析Zookeeper的核心实现,并通过多个应用场景说明,体现出其重要性和广泛的应用性。第二阶段深入Dubbo RPC、SPI等核心功能点,列举多个示例加以应用说明,期望能够...

    zookeeper 分布式集群管理应用, Dubbo 实现远程调用 服务降级

    zooKeeper 是一个开放源码的分布式协调服务,主要为了解决分布式架构下数据一致性问题, 它...zookeeper 应用场景: 分布式配置中心、分布式注册中心、分布式锁、分布式队列、集群选举、分布式屏障、发布/订阅等场景。

    apache-ZooKeeper-3.7.1-bin

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件...ZooKeeper是一个强大且灵活的分布式协调服务,适用于大规模分布式系统的场景。

    Zookeeper学习教程 包括java源码

    Zookeeper是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于Zookeeper实现诸如:分布式协调/通知,集群管理,Master选举, 分布式锁,分布式队列,命名服务,数据发布/订阅,负载均衡等功能. Zookeeper非常常用...

    深入解析Zookeeper:核心特性与节点类型全景剖析

    详细介绍了Zookeeper的五种节点类型,包括持久化节点、持久化顺序节点、临时节点、临时顺序节点和容器节点,每种类型都有其独特的应用场景和功能。文章还探讨了Zookeeper在分布式系统中的经典应用,如配置中心、注册...

    分布式协调工具-ZooKeeper实现动态负载均衡

    2. Master选举则是zookeeper中最为经典的应用场景了。 在分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算,网络I/O处理),往往只需要让整个集群中的某一台机器进行执行,其余...

    大数据之ZooKeeper与Hadoop

    ZooKeeper是一个针对大型分布式系统的可靠协调系统,为分布式应用提供一致性服务,是Google的Chubby一个开源的实现。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统...

    hmily-master.zip

    功能 高可靠性 :支持分布式场景下,事务异常回滚,超时异常恢复,防止事务悬挂 易用性 :提供零侵入性式的 Spring-Boot, Spring-Namespace 快速与业务系统集成 高性能 :去中心化设计,与业务系统完全融合,天然...

    华为HCIA-Big Data V2.0 LVC公开课培训.rar

    2.1_HDFS概述及应用场景-HDFS系统架构 2.2_关键特性介绍 第三章 MapReduce分布式离线批处理和Yarn资源协调 3.1_MapReduce和Yarn基本介绍-MapReduce和Yarn功能与架构 3.2_Yarn的资源管理和任务调度-增强特性 第四...

    基于Gradle构建,使用SpringBoot在各个场景的应用,包括集成消息中间件、前后端分离、数据库、缓存+源代码+文档说明

    集成Dubbo的服务提供者,依赖zookeeper。 #### SpringBoot-Dubbo-Consumer(基于Dubbo的服务实现者) 集成Dubbo的服务消费者。 #### SpringBoot-Elasticsearch(Java 操作Es进行CURD) ## 项目备注 1、该资源内项目...

    基于开源项目bistoury的java应用故障诊断工具预研demo源码.zip

    故障诊断工具的使用场景是定位解决一些极端情况下的问题,作为传统策略无法分析故障时的诊断工具,我们并不追求日常场景下的高频使用,还是建议大家好好写代码,认真做测试。 通过在线诊断工具发现、定位和解决应用...

    java流程自动化工具

    一、代码生成:快速构建代码生成功能,通过可视化界面,采用拖拽式控件及连接线绘制流程图,自定义实现生成任何想要的代码。 二、环境搭建:以java应用来讲,比如安装jdk,tomcat,zookeeper,mq,hbase,mysql等等...

    从传统的 SSM 项目改造成基于 Spring Boot + Dubbo + Zookeeper 的微服务架构项目

    SSM(Spring + Spring MVC + MyBatis)框架作为Java开发中的黄金组合,为开发者提供了强大的技术支持和丰富的功能。本系列资料将带您从零基础开始,逐步掌握SSM的核心技术和最佳实践,助您在Java Web开发领域更上一...

    Kafka快速实战与基本原理详解:从零到精通

    本文档提供了对Kafka这一分布式消息系统的全面解析,从基本概念到实际应用,涵盖了其在日志收集、消息系统、用户活动跟踪等方面的使用场景。首先介绍了Kafka的核心概念,如Broker、Topic、Producer、Consumer等,...

    consul 中文开发指南

    zookeeper 和 etcd 均不提供多数据中心功能的支持. 支持健康检查. etcd 不提供此功能. 支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议. 官方提供web管理界面, etcd 无此功能. 综合...

Global site tag (gtag.js) - Google Analytics