什么是ZooKeeper 

ZooKeeper作为一个分布式的服务框架(与Google Chubby类似),主要用于解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储,但 ZK并不是用来专门存储数据的,它的作用主要是用来维护和监控系统存储的数据的状态变化。通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。

Client在ZooKeeper里添加一个节点意味着在一棵类似文件树的结构上添加节点,每一个节点有着唯一的路径(/mutex-lock/uuid-lock-sn),称之为ZNode;每一个ZNode上可以存储少量的数据(缺省为1M),根据创建类型的不同有四种ZNode类型,persisten,persisten_sequential,ephemeral,ephemeral_sequential;persisten的ZNode为永久性数据需要显示删除,ephemeral的ZNode在创建的session会话结束后会被自动删除,sequential的ZNode会在节点名后自动生成唯一的SN号。

ZooKeeper是以Fast Paxos (Leslie Lamport)算法为基础,经过Leader Election 和Data Sync之后,多台ZooKeeper Server就组成了分布式的ZooKeeper service group;每一台ZooKeeper Server上都保存了完整的ZNode Tree信息,因此每一台ZooKeeper Server都可以提供读写操作,从而极大提升了集群的性能;对于写操作而言,ZooKeeper采用的策略是Write Ahead Log,先写日志再进行更新的方式极大保证了服务的可靠性。

一个简单的ZooKeeper内部操作流如下:(侵删)

ZooKeeper安装配置和简单操作

将ZooKeeper(3.4.12)包解压到指定目录,在$ZK_HOME/conf目录下添加zoo.cfg的文件,里面可配置ZooKeeper的运行参数;如果是集群(Quorum)的话需要多配置两个地方,一个是在zoo.cfg文件里添加带有编号的server list,另外一个是在dataDir/目录下创建文件myid并且写入与server list的编号一致的数字 ,表示当前的ZooKeeper实例对应的是server list中的哪个server。zoo.cfg示例如下

 # 一次tick的毫秒数
tickTime=2000
# initial sync的最大tick数
initLimit=10
# 日常通信的最大tick数
syncLimit=5
# snapshot存储文件的目录
dataDir=~/active/zookeeper-0/snapshot
dataLogDir=~/active/zookeeper-0/log
# client与当前zk实例连接的端口
clientPort=2180
# 集群内所有zk实例的编号,IP,在与leader通信时使用的端口,在leader election时使用端口
server.0=127.0.0.1:8880:7880
server.1=127.0.0.1:8881:7881
server.2=127.0.0.1:8882:7882
server.3=127.0.0.1:8883:7883
server.4=127.0.0.1:8884:7884

执行命令$ZK_HOME/bin/zkServer.sh start,启动ZooKeeper的实例,如果是n个server的集群的话需要启动至少n/2个server,否则ZooKeeper会认为当前的集群不可用,比如上述配置中有5个server,则需要至少启动3个server后集群才可用。执行命令$ZK_HOME/bin/zkCli.sh -server 127.0.0.1:2180,连接并访问对应的ZooKeeper实例(by TCP);连接到集群之后可以查看、创建和修改指定ZNode的数据。

其他命令:$ZK_HOME/bin/zkCleanup.sh表示清理当前zk实例的dataDir和dataLogDir目录;$ZK_HOME/bin/zkEnv.sh表示动态设置当前zk实例的运行变量。

利用Apache Curator集成使用ZooKeeper

由于ZooKeeper仅提供最原始的分布式一致性功能,如果需要实现分布式锁等功能需要再次进行封装,Apache Curator提供了一套成熟的框架对ZooKeeper的功能进行了封装;基于maven的依赖如下。

 <dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>2.9.1</version>
</dependency>

通过ZooKeeper实现分布式锁:racing process在指定节点/mutex-lock下创建ephemeral_sequential类型的ZNode,xxx-lock-SN,ZooKeeper可以保证SN的唯一性和顺次递增性;racing process创建好自己的ZNode之后判断自己的SN 是否是/mutex-lock节点下最小的,如果是最小的则表示获取到了锁,如果不是最小的,则在比自己次小的ZNode上设置watcher并等待锁;当前获取到锁的racing process在处理完事务之后释放锁,也就是删除/mutex-lock下对应的ZNode,这样ZooKeeper的watcher机制给下一个racing process发起通知。Java示例代码如下

 public class App {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
ClientJob cj = new ClientJob(i);
new Thread(cj).start();
Thread.sleep(500);
}
}
public static class ClientJob implements Runnable {
private int num;
public ClientJob(int num) {
this.num = num;
}
public void run() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client =
CuratorFrameworkFactory.newClient("127.0.0.1:2180", retryPolicy);
client.start(); InterProcessMutex lock = new InterProcessMutex(client, "/mutex-lock");
try {
System.out.println("## " + num + " ##, try fetching lock.");
lock.acquire();
System.out.println("## " + num + " ##, has fetched lock.");
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
lock.release();
System.out.println("## " + num + " ##, has released lock.");
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

通过ZooKeeper实现读写锁:读锁表示允许其他racing process读,但禁止写;写锁表示禁止其他racing process读和写。写锁的实现与常规分布式锁的实现一致,读锁的实现可以判断排在自己之前的racing process的所有ZNode信息,如果存在WRITE racing process则不能获取锁,否则可以获取到锁。Curator还实现了包含Leader Election,Barrier,Counter,Queue等在内的分布式系统内需要的协调服务。

ZooKeeper运行原理和基本编程接口的更多相关文章

  1. 初级游戏外挂编程详解 windows运行原理+游戏辅助编程 游戏外挂编程

    详解游戏辅助编程 [目录] 1-什么是Windows API 2-Windows进程 3-Windows 的内存的运行原理 4-windows 中句柄的概念 5-Windows的变量类型 6-辅助实现 ...

  2. Dubbo&Zookeeper运行原理

    Dubbo是一个分布式服务框架,Dubbo的架构如图所示: 节点角色说明: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发 ...

  3. (转载)Linux系统调用及用户编程接口(API)

    (转载)http://www.farsight.com.cn/news/emb167.htm 1 Linux系统调用 所谓系统调用是指操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组 ...

  4. 【Java编程实战】Metasploit_Java后门运行原理分析以及实现源码级免杀与JRE精简化

    QQ:3496925334 文章作者:MG1937 CNBLOG博客ID:ALDYS4 未经许可,禁止转载 某日午睡,迷迷糊糊梦到Metasploit里有个Java平台的远控载荷,梦醒后,打开虚拟机, ...

  5. [PHP] 通用网关接口CGI 的运行原理

    CGI 的运行原理:1.客户端访问某个 URL 地址之后,通过 GET/POST/PUT 等方式提交数据,并通过 HTTP 协议向 Web 服务器发出请求.2.服务器端的 HTTP Daemon(守护 ...

  6. Dubbo(一):Dubbo运行原理

    前言: 在开始入门Javaweb时,学的基本都是MVC开发模式,一个项目基本上就是model,view,controller三层.但是随着系统的服务逐渐加多,SOA模式更加适合目前项目开发.而SOA模 ...

  7. .NET/ASP.NET MVC Controller 控制器(深入解析控制器运行原理)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...

  8. 网络层、传输层、应用层、端口通信协议编程接口 - http,socket,tcp/ip 网络传输与通讯知识总结

    引: http://coach.iteye.com/blog/2024511 什么是TCP和UDP,以及二者区别是什么? TCP的全称为传输控制协议.这种协议可以提供面向连接的.可靠的.点到点的通信. ...

  9. ZooKeeper学习第七期--ZooKeeper一致性原理

    一.ZooKeeper 的实现 1.1 ZooKeeper处理单点故障 我们知道可以通过ZooKeeper对分布式系统进行Master选举,来解决分布式系统的单点故障,如图所示. 图 1.1 ZooK ...

随机推荐

  1. Codeforces 711B 【模拟】

    比赛的时候绝壁打麻烦了... 考虑的好麻烦...wa7...还要判断出来的是不是positive的... 好吧..认了.. #include<cstdio> #include <ma ...

  2. hdoj5387【模拟】

    题意: 略: 思路: 把所有的角度按照分母的形式写,中间不要约,不要除...(然后我就wa了),本来是想保证结果的正确性,最后会造成约好以后分子很大..>360°: /* 这个案例不错,妈的,随 ...

  3. hdoj1272【并查集】

    因为是第二遍,所以题目也没怎么看,然后一开始的思路就是如果每次输入两个点的时候判断是不是同一个集合,如果同一个就是No,然后就wa了,想想也是,然后瞄了一下题解,还要判连通-真是蠢死了-多个集合都想不 ...

  4. WPF DataGrid foreground 绑定问题

    初学WPF ,  希望对DataGrid 中所属的一个Column名下的值的颜色动态修改 <DataGridTextColumn Header="隐含回购利率(%)" Bin ...

  5. poj 3207 Ikki's Story IV - Panda's Trick【2-SAT+tarjan】

    注意到相交的点对一定要一里一外,这样就变成了2-SAT模型 然后我建边的时候石乐志,实际上不需要考虑这个点对的边是正着连还是反着连,因为不管怎么连,能相交的总会相交,所以直接判相交即可 然后tarja ...

  6. P5165 xtq的棋盘

    传送门 设\(f[i]\)为\(i\)位置向左走一步的期望时间,那么答案就是\(\sum_{i=1}^mf[i]\) 首先\(f[n]=1\),设\(p\)为向左的概率,对于\(i<n\)的位置 ...

  7. 笔记:重新认识CSS3

    1.CSS3边框 border-radius box-shadow border-image 2.CSS3背景 background-image background-size background- ...

  8. Ubuntu开机之后报错结局方法

    sudo gedit /etc/default/apport 把里面的enabled=1改成enabled=,保存 201. 就是下雨也去.202. 我马上拿来.203. 孙英开飞机.204. 国华来 ...

  9. 布线问题 最小生成树 prim + kruskal

    1 : 第一种 prime     首先确定一个点 作为已经确定的集合 , 然后以这个点为中心 , 向没有被收录的点 , 找最短距离( 到已经确定的点 ) , 找一个已知长度的最小长度的 边 加到 s ...

  10. Could not open logfile" occurred when run "datapatch -verbose"

    CAUSE Due to Bug 25459405 - DATAPATCH FAILS WITH SP2-0768 IF NLS_LANGUAGE IS NOT SET TO AMERICANwhic ...