赞
踩
1、zookeeper简介
zookeeper(以下简称ZK)是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop、Hbase、Kafka、Jstorm等开源软件的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。ZK的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
2、zk集群安装(集群安装是奇数台)
ZK既可单节点运行,也可以多节点集群运行。生产环境都采用集群的方式,避免单节点故障。ZK需要java环境,要确保系统有jdk 1.7或更高版本。安装JDK这里就不演示了,我自己在虚拟机上安装,就安装了3个节点
https://zookeeper.apache.org/releases.html
我安装的版本是zookeeper-3.4.10,我解压到/app/soft目录下了
3、配置
zookeeper conf目录下有zoo_sample.cfg实例配置文件,复制这个文件,重命名为zoo.cfg,开始配置zoo.cfg的内容:
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg
- tickTime=2000 ##Client-Server通信心跳时间,单位是毫秒
- initLimit=10 ##集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数
- syncLimit=5 ##集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数
- clientPort=2181 ## 监听端口
- maxClientCnxns=100 ## 最大连接数
- dataDir=/app/soft/zookeeper-3.4.10/data ## 数据目录
- dataLogDir=/app/soft/zookeeper-3.4.10/log ## 日志目录
- server.1=192.168.34.128:2888:3888 ## zk节点1
- server.2=192.168.34.129:2888:3888 ## zk节点2
- server.3=192.168.34.130:2888:3888 ## zk节点3
在/app/soft/zookeeper-3.4.10/下创建两个文件夹,分别是data和log
然后分别在zk节点,/app/soft/zookeeper-3.4.10/data目录下,创建文本myid,内容分别是1、2、3序号
192.168.34.128 对应的是1
192.168.34.129 对应的是2
192.168.34.130 对应的是3
4、启动zk
启动之前,jdk7以上的版本一定要安装合适,然后在环境变量里配置ZK_HOME
然后在SecureCRT里同时打开三个节点
执行命令:zkServer.sh start,这里的zkServer.sh是zookeeper bin目录下的脚本
看到这个结果不一定启动成功了,然后执行zkServer.sh status 查看各个zk节点的状态,如果看到一个leader,其它两个节点都是follower说明启动成功了。
还可以通过查看jps命令去查看是否启动了zk
zkServer.sh stop是停掉zk节点服务的,到这里zk的启动就没有问题了!!!
5、zk选举leader
前面说到搭建zk集群节点是奇数台,因为只有是奇数它,它才能选举出谁是leader,谁是follwer,是通过前面配置的myid决定的,三个节点依次配置了1、2、3,服务器1启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是等待状态, 服务器2启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它,所以服务器1,2还是继续保持等待状态,服务器3启动,根据前面的理论分析,服务器3成为服务器1,2,3中的老大,而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的leader。
6、zk使用
启动zk之后,在任意一台服务上,运行:zkCli.sh进入zk的命令行模式
zk创建的节点叫znode,znode四种节点类型:持久节点、持久序列节点、暂时节点、暂时序列节点。
create -e /app 111 创建一个暂时的znode节点
create -s /app/test1 222 创建一个持久的,带有序列号的znode节点
get /app/test 得到创建的节点中的数据
执行ls /可以看到根节点下面所有子节点
ls /app/test watch 监听这个节点下的变化,我在另一个服务器下也打开了zk的命令行,
然后我在其它服务上,在这个节点下做创建节点的操作
会发现监听的服务器上会弹出下面消息,是对这个节点做出改变的通知
7、通过java代码来创建节点、修改节点内容、监听等
创建一个maven项目
pom.xml引入zk的jar包
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>zookeeperDemo</groupId>
- <artifactId>zookeeperDemo</artifactId>
- <version>1.0</version>
- <dependencies>
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>3.4.10</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- </dependency>
- </dependencies>
-
- </project>
然后创建一个类
- package cn.dl.zookeeper;
-
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.ZooKeeper;
-
- import java.util.ArrayList;
- import java.util.List;
-
- /**
- * Created by Tiger on 2018/7/5.
- */
- public class ZookeeperClient {
-
- //连接的zk服务
- private static final String CONNECTION_HOSTS = "192.168.34.128:2181,192.168.34.128:2181,192.168.34.128:2181";
- //超时连接的时间
- private static final int SESSION_TIMEOUT = 2000;
-
- private static ZooKeeper zooKeeper = null;
- //servers根目录
- private volatile static String serviceRootNode = "/services";
- //服务器列表
- /**使用volatile的意义
- * 1、通过在总线加LOCK#锁的方式
- * 2、通过缓存一致性协议
- * 1.volatile关键字的两层语义
- 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
- 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
- 2)禁止进行指令重排序。
- * */
- private static volatile List<String> serviceList = new ArrayList<String>();
- static {
- try {
- zooKeeper = new ZooKeeper(CONNECTION_HOSTS, SESSION_TIMEOUT, new Watcher() {
-
- /**
- * 监听服务器列表的变化
- * */
- public void process(WatchedEvent watchedEvent) {
- try {
- getServerList();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 获取服务器列表
- * */
- public static void getServerList() throws Exception {
- List<String> nodes = zooKeeper.getChildren(serviceRootNode,true);
- //清空服务器列表信息list集合
- serviceList.clear();
- for(String node : nodes){
- /**
- * 这里的第二个参数:false,意思是已经获到了连接,不需要重新获取连接
- * */
- byte[] data = zooKeeper.getData(serviceRootNode + "/"+ node,false,null);
- serviceList.add(new String(data));
- }
- System.out.println(serviceList);
- }
- public static void main(String[] args) throws Exception {
- ZookeeperClient zookeeperClient = new ZookeeperClient();
- zookeeperClient.getServerList();
- Thread.sleep(Long.MAX_VALUE);
- }
- }
- package cn.dl.zookeeper;
-
-
- import org.apache.zookeeper.*;
- import org.apache.zookeeper.data.ACL;
- import org.apache.zookeeper.data.Stat;
- import org.junit.Test;
-
- import java.util.ArrayList;
- import java.util.List;
-
- /**
- * Created by Tiger on 2018/6/30.
- */
- public class ZookeeperDemo {
-
- //连接的zk服务
- private static final String CONNECTION_HOSTS = "192.168.34.128:2181,192.168.34.128:2181,192.168.34.128:2181";
- //超时连接的时间
- private static final int SESSION_TIMEOUT = 2000;
-
- private static ZooKeeper zooKeeper = null;
- static {
- try {
- zooKeeper = new ZooKeeper(CONNECTION_HOSTS, SESSION_TIMEOUT, new Watcher() {
- public void process(WatchedEvent watchedEvent) {
- System.out.println(watchedEvent.getPath()+";"+watchedEvent.getState());
- try {
- //获取对根目录节点数据的监控
- zooKeeper.getChildren("/",true);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /*
- 判断当前节点是否存在
- */
- public Stat isExistZnode(String path) throws Exception{
- Stat stat = zooKeeper.exists(path,true);
- return stat;
- }
- /*
- 创建节点
- */
- @Test
- public String createZnode(String path, Object object, ArrayList<ACL> zooDefs, CreateMode createMode) throws Exception {
- return zooKeeper.create(path,object.toString().getBytes(),zooDefs,createMode);
- }
- /*
- 修改节点
- */
- @Test
- public Stat updateZnode(String path, Object object, int version) throws Exception {
- return zooKeeper.setData(path,object.toString().getBytes(),version);
- }
- /*
- 删除节点
- */
- @Test
- public void deleteZnode(String path,int version) throws Exception {
- zooKeeper.delete(path,version);
- }
- @Test
- public static void main(String[] args) throws Exception{
- ZookeeperDemo zookeeperDemo = new ZookeeperDemo();
- //创建节点
- if(zookeeperDemo.isExistZnode("/Tiger") == null){
- zookeeperDemo.createZnode("/Tiger","oh,my sky", ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
- }else {
- System.out.println("znode exist!!!");
- }
- //更新节点内容
- Stat stat = zookeeperDemo.isExistZnode("/Tiger");
- if(stat != null){
- System.out.println(stat.getVersion());
- zookeeperDemo.updateZnode("/Tiger","oh,my sky",stat.getVersion());
- }else{
- System.out.println("znode not exist !!!");
- }
- //删除节点
- Stat deleteStat = zookeeperDemo.isExistZnode("/Tiger1");
- if(deleteStat != null){
- zookeeperDemo.deleteZnode("/Tiger1",deleteStat.getVersion());
- }
- //获取根节点下所有子节点,遍历获取对应节点的数据
- List<String> znodes = zooKeeper.getChildren("/",true);
- for(String path : znodes){
- System.out.println(path+">>>"+new String(zooKeeper.getData("/"+path,true,new Stat())));
- }
- }
- }
zk的安装、简单使用就这些了,这是本人自己的理解,有什么不对的地方欢迎来吐槽!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。