转自:http://buliedian.javaeye.com/blog/852088
zookeeper
介绍
zookeeper是一个为分布式应用提供一致性服务的软件,它是开源的
Hadoop项目中的一个子项目,并且根据
google发表的
<The Chubby lock service for loosely-coupled distributed systems>论文来实现的,接下来我们首先来安装使用下这个软件,然后再来探索下其中比较重要一致性算法。
zookeeper安装和使用
zookeeper的安装基本上可以按照
http://hadoop.apache.org/zookeeper/docs/current/ zookeeperStarted.html 这个页面上的步骤完成安装,这里主要介绍下部署一个集群的步骤,因为这个官方页面似乎讲得并不是非常详细
(Running Replicated Zookeeper)。
由于手头机器不足,所以在一台机器上部署了
3个
server,如果你手头也比较紧,也可以这么做。那么我建了
3个文件夹,如下
server1 server2 server3
然后每个文件夹里面解压一个
zookeeper的下载包,并且还建了几个文件夹,总体结构如下
,最后那个是下载过来压缩包的解压文件
data dataLog logs zookeeper-3.3.2
那么首先进入
data目录,创建一个
myid的文件,里面写入一个数字,比如我这个是
server1,那么就写一个
1,
server2对应
myid文件就写入
2,
server3对应myid文件就写个
3
然后进入
zookeeper-3.3.2/conf
目录,那么如果是刚下过来,会有
3个文件,
configuration.xml, log4j.properties,zoo_sample.cfg
,这
3个文件我们首先要做的就是在这个目录创建一个
zoo.cfg的配置文件,当然你可以把
zoo_sample.cfg文件改成
zoo.cfg,配置的内容如下所示:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=xxxx/zookeeper/server1/data
dataLogDir=xxx/zookeeper/server1/dataLog
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
标红的几个配置应该官网讲得很清楚了,只是需要注意的是
clientPort这个端口如果你是在
1台机器上部署多个
server,那么每台机器都要不同的
clientPort,比如我
server1是
2181,server2是
2182,
server3是
2183,
dataDir和
dataLogDir也需要区分下。
最后几行唯一需要注意的地方就是
server.X 这个数字就是对应
data/myid中的数字。你在
3个
server的
myid文件中分别写入了
1,
2,
3,那么每个
server中的
zoo.cfg都配
server.1,server.2,server.3就
OK了。因为在同一台机器上,后面连着的
2个端口
3个
server都不要一样,否则端口冲突,其中第一个端口用来集群成员的信息交换,第二个端口是在
leader挂掉时专门用来进行选举
leader所用。
进入
zookeeper-3.3.2/bin 目录中,./
zkServer.sh start
启动一个
server,这时会报大量错误?其实没什么关系,因为现在集群只起了
1台
server,
zookeeper服务器端起来会根据
zoo.cfg的服务器列表发起选举
leader的请求,因为连不上其他机器而报错,那么当我们起第二个
zookeeper实例后,
leader将会被选出,从而一致性服务开始可以使用,这是因为
3台机器只要有
2台可用就可以选出
leader并且对外提供服务
(2n+1台机器,可以容
n台机器挂掉
)。
接下来就可以使用了,我们可以先通过
zookeeper自带的客户端交互程序来简单感受下
zookeeper到底做一些什么事情。进入
zookeeper-3.3.2/bin(
3个
server中任意一个)下,
./zkCli.sh –server 127.0.0.1:2182
,我连的是开着
2182端口的机器。
那么,首先我们随便打个命令,因为
zookeeper不认识,他会给出命令的
help,如下图
ls(查看当前节点数据
),
ls2(查看当前节点数据并能看到更新次数等数据
) ,
create(创建一个节点
) ,
get(得到一个节点,包含数据和更新次数等数据
),
set(修改节点
)
delete(删除一个节点
)
通过上述命令实践,我们可以发现,
zookeeper使用了一个类似文件系统的树结构,数据可以挂在某个节点上,可以对这个节点进行删改。另外我们还发现,当改动一个节点的时候,集群中活着的机器都会更新到一致的数据。
zookeeper
的数据模型
在简单使用了
zookeeper之后,我们发现其数据模型有些像操作系统的文件结构,结构如下图所示
(1)
每个节点在
zookeeper中叫做
znode,并且其有一个唯一的路径标识,如
/SERVER2节点的标识就为
/APP3/SERVER2
(2)
Znode可以有子
znode,并且
znode里可以存数据,但是
EPHEMERAL类型的节点不能有子节点
(3)
Znode中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据就需要带上版本。
(4)
znode 可以是临时节点,一旦创建这个
znode 的客户端与服务器失去联系,这个
znode 也将自动删除,
Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和 服务器通过心跳来保持连接,这个连接状态称为
session,如果
znode 是临时节点,这个
session 失效,
znode 也就删除了
(5)
znode 的目录名可以自动编号,如
App1 已经存在,再创建的话,将会自动命名为
App2
(6)
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是
zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的集中管理,集群管理,分布式锁等等。
通过
java代码使用
zookeeper
Zookeeper
的使用主要是通过创建其
jar
包下的
Zookeeper
实例,并且调用其接口方法进行的,主要的操作就是对
znode
的增删改操作,监听
znode
的变化以及处理。
以下为主要的
API
使用和解释
//
创建一个Zookeeper实例,第一个参数为目标服务器地址和端口,第二个参数为Session超时时间,第三个为节点变化时的回调方法
ZooKeeper zk
=
new
ZooKeeper(
"
127.0.0.1:2181
"
,
500000
,
new
Watcher()
{
//
监控所有被触发的事件
public
void
process(WatchedEvent event)
{
//
dosomething
}
}
);
//
创建一个节点root,数据是mydata,不进行ACL权限控制,节点为永久性的(即客户端shutdown了也不会消失)
zk.create(
"
/root
"
,
"
mydata
"
.getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//
在root下面创建一个childone znode,数据为childone,不进行ACL权限控制,节点为永久性的
zk.create(
"
/root/childone
"
,
"
childone
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
//
取得/root节点下的子节点名称,返回List<String>
zk.getChildren(
"
/root
"
,
true
);
//
取得/root/childone节点下的数据,返回byte[]
zk.getData(
"
/root/childone
"
,
true
,
null
);
//
修改节点/root/childone下的数据,第三个参数为版本,如果是-1,那会无视被修改的数据版本,直接改掉
zk.setData(
"
/root/childone
"
,
"
childonemodify
"
.getBytes(),
-
1
);
//
删除/root/childone这个节点,第二个参数为版本,-1的话直接删除,无视版本
zk.delete(
"
/root/childone
"
,
-
1
);
//
关闭session
zk.close();
Zookeeper
的主流应用场景实现思路(除去官方示例)
(1)
配置管理
集中式的配置管理在应用集群中是非常常见的,一般商业公司内部都会实现一套集中的配置管理中心,应对不同的应用集群对于共享各自配置的需求,并且在配置变更时能够通知到集群中的每一个机器。
Zookeeper
很容易实现这种集中式的配置管理,比如将
APP1
的所有配置配置到
/APP1 znode
下,
APP1
所有机器一启动就对
/APP1
这个节点进行监控
(zk.exist(
"/APP1"
,true)),
并且实现回调方法
Watcher
,那么在
zookeeper
上
/APP1 znode
节点下数据发生变化的时候,每个机器都会收到通知,
Watcher
方法将会被执行,那么应用再取下数据即可
(zk.getData(
"/APP1",false,null
));
以上这个例子只是简单的粗颗粒度配置监控,细颗粒度的数据可以进行分层级监控,这一切都是可以设计和控制的。
(2)
集群管理
应用集群中,我们常常需要让每一个机器知道集群中(或依赖的其他某一个集群)哪些机器是活着的,并且在集群机器因为宕机,网络断链等原因能够不在人工介入的情况下迅速通知到每一个机器。
Zookeeper
同样很容易实现这个功能,比如我在
zookeeper
服务器端有一个
znode
叫
/APP1SERVERS,
那么集群中每一个机器启动的时候都去这个节点下创建一个
EPHEMERAL
类型的节点,比如
server1
创建
/APP1SERVERS/SERVER1(
可以使用
ip,
保证不重复
)
,
server2
创建
/APP1SERVERS/SERVER2
,然后
SERVER1
和
SERVER2
都
watch /APP1SERVERS
这个父节点,那么也就是这个父节点下数据或者子节点变化都会通知对该节点进行
watch
的客户端。因为
EPHEMERAL
类型节点有一个很重要的特性,就是客户端和服务器端连接断掉或者
session
过期就会使节点消失,那么在某一个机器挂掉或者断链的时候,其对应的节点就会消失,然后集群中所有对
/APP1SERVERS
进行
watch
的客户端都会收到通知,然后取得最新列表即可。
另外有一个应用场景就是集群选
master,
一旦
master
挂掉能够马上能从
slave
中选出一个
master,
实现步骤和前者一样,只是机器在启动的时候在
APP1SERVERS
创建的节点类型变为
EPHEMERAL_SEQUENTIAL
类型,这样每个节点会自动被编号,例如
zk.create(
"
/testRootPath/testChildPath1
"
,
"
1
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
zk.create(
"
/testRootPath/testChildPath2
"
,
"
2
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
zk.create(
"
/testRootPath/testChildPath3
"
,
"
3
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
//
创建一个子目录节点
zk.create(
"
/testRootPath/testChildPath4
"
,
"
4
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(zk.getChildren(
"
/testRootPath
"
,
false
));
打印结果:
[testChildPath10000000000, testChildPath20000000001, testChildPath40000000003, testChildPath30000000002]
zk.create(
"
/testRootPath
"
,
"
testRootData
"
.getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//
创建一个子目录节点
zk.create(
"
/testRootPath/testChildPath1
"
,
"
1
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
zk.create(
"
/testRootPath/testChildPath2
"
,
"
2
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
zk.create(
"
/testRootPath/testChildPath3
"
,
"
3
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
//
创建一个子目录节点
zk.create(
"
/testRootPath/testChildPath4
"
,
"
4
"
.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
System.out.println(zk.getChildren(
"
/testRootPath
"
,
false
));
打印结果:
[testChildPath2, testChildPath1, testChildPath4, testChildPath3]
我们默认规定编号最小的为
master,
所以当我们对
/APP1SERVERS
节点做监控的时候,得到服务器列表,只要所有集群机器逻辑认为最小编号节点为
master
,那么
master
就被选出,而这个
master
宕机的时候,相应的
znode
会消失,然后新的服务器列表就被推送到客户端,然后每个节点逻辑认为最小编号节点为
master
,这样就做到动态
master
选举。
总结
我们初步使用了一下
zookeeper并且尝试着描述了几种应用场景的具体实现思路,接下来的文章,我们会尝试着去探究一下
zookeeper的高可用性与
leaderElection算法。
分享到:
相关推荐
Zookeeper测试小程序是一个基于Apache ...总的来说,Zookeeper测试小程序是学习和理解Zookeeper客户端使用的实用工具,通过它,我们可以深入探究分布式协调服务的内在机制,提高在分布式环境中解决问题的能力。
通过对Zookeeper架构、ZAB协议、选举机制、数据模型等核心概念的探究,开发者可以更好地运用Zookeeper解决实际问题,提升系统性能和稳定性。在实际项目中,结合Zookeeper提供的API,我们可以构建出更加健壮、高效的...
Zookeeper是Apache软件基金会的一个...5. 探究Zookeeper的监控和日志系统。 通过以上对Zookeeper-3.4.5的详细解读,开发者可以更好地理解这个版本的特性和实现原理,从而在实际项目中更加得心应手地运用Zookeeper。
在实际应用中,掌握Zookeeper和Kafka的集成使用技巧,可以解决许多分布式系统中的常见问题,如数据一致性、容错性、扩展性和性能优化等。通过不断实践和探索,我们可以将这两个强大的工具灵活应用于各种复杂场景,...
深入研究Zookeeper源码,不仅能帮助我们理解其工作原理,也能提升在分布式系统设计和优化上的能力。通过分析Zookeeper的内部实现,我们可以学习如何构建高可用、高一致性的分布式服务,这对于理解分布式系统的设计...
这是一套超级详细的狂神说内容PDF笔记,从Java基础内容到微服务,分布式相关笔记,docker相关笔记等,包含有:JavaSE基础语法、Java入门、前端、网络编程、SpringBoot入门及技术、Vue精讲、Linux使用、JVM探究等方面...
从简到难,从网络通信探究分布式通信原理 基于消息方式的系统间通信 理解通信协议传输过程中的序列化和反序列化机制 基于框架的RPC通信技术 WebService/ApacheCXF RMI/Spring RMI Hession 传统RPC技术在大型...
- **HDFS底层工作原理**:深入探究HDFS的数据存储机制。 - **HDFSdatanode,namenode详解**:详细讲解Datanode和Namenode的角色及其交互机制。 - **Hdfsshell**:使用HDFS Shell进行文件操作。 - **Hdfsjavaapi**:...
开发者在解压后,可以通过阅读README文件了解如何安装和使用该项目,通过源代码学习其实现原理,通过测试用例检查其功能是否正常,甚至可以根据需求进行二次开发。 总的来说,"pyexplainer-1.0.1.tar.gz"是一个面向...
25、SpringBoot入门及原理 26、SpringBoot操作数据库 27、SpringBoot开发单体应用 28、SpringBootWeb开发提升(Swagger) 29、SpringSecurity权限控制 30、整合Dubbo+Zookeeper 31、Shiro 32、...
数据存储组件的基本操作与原理探究,包含但不限于MySQL、Redis、Kafka、Hive、HBase ; 分布式、微服务时下流行框架及理论,包含但不限于CAP理论及其相关算法、Zookeeper、Spring Cloud Alibaba、Dubbo;
25、SpringBoot入门及原理.pdf 26、SpringBoot操作数据库.pdf 27、SpringBoot开发单体应用.pdf 28、SpringBootWeb开发提升(Swagger).pdf 29、SpringSecurity权限控制.pdf 30、整合Dubbo+Zookeeper.pdf 31、...
1. 类加载机制:探究类的加载、验证、准备、解析和初始化过程。 2. 虚拟机参数调整:学习如何设置堆大小、新生代与老年代的比例、GC策略等参数。 3. 内存泄漏检测:识别内存泄漏的迹象,使用工具进行监控和诊断。 ...
- 探究基于Tag的消费模式,以及如何订阅特定主题下的子集消息。 6. **12.dubbo-admin管理平台搭建.mp4**: - Dubbo-Admin是服务治理的可视化界面,用于监控服务状态、查看调用日志等。 - 搭建和配置Dubbo-Admin...
6. **30、整合Dubbo+Zookeeper.pdf**:这将涉及到分布式服务框架Dubbo的使用,以及服务注册与发现工具Zookeeper的集成。 7. **5、JavaSE:数组.pdf**:对Java中的数组类型、操作和高级用法进行讲解。 8. **29、...
【描述】"dubbon最清晰代码,轻轻松松入门" 表明这个压缩包中的代码示例设计得非常直观,目的是使学习者能够轻松理解Dubbo的核心概念和工作原理。Dubbo是一个高性能、轻量级的Java开源服务框架,由阿里巴巴开发并维护...
通过阅读和修改这些源码,学习者可以深入探究服务调用、数据序列化、服务监控等核心模块,提升自身的代码调试和问题解决能力。 在【分布式系列共10套】的课程体系中,学习者将逐步深入到Dubbo的各个层面,包括但不...
7. **Zookeeper 集成**: Kafka 使用 Zookeeper 进行元数据管理,研究 Kafka 如何与 Zookeeper 协同工作。 通过深入学习 Kafka 的源码,你可以更好地理解其内部工作原理,从而更有效地利用 Kafka 构建实时数据处理...
Hive则提供了SQL-like接口,让分析师可以使用熟悉的查询语法查询HDFS中的数据;Hbase是一个基于列的NoSQL数据库,适合实时查询大规模数据;ZooKeeper作为一个协调服务,为分布式应用程序提供一致性服务;Sqoop则用于...