Zookeeper的安装及共享锁的应用

1.zookeeper的安装

1.1  下载安装包

Wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz

1.2 .解压缩安装包 tar -zxvf zookeeper-3.4.6.tar.gz 这里我们的操作都是在一个新建目录/opt/zookeeper 文件夹下完成的,自己可以根据实际需要创建文件夹

1.3 进入/opt/zookeeper/zookeeper-3.4.6/conf文件夹,将zoo_sample.cfg 文件重命名为 zoo.cfg ,命令:mv  zoo_sample.cfg  zoo.cfg

1.4 修改zoo.cfg配置文件 命令vi zoo.cfg ,将dataDir,dataLogDar参数进行配置,文件夹可以自己定义,在这里我配置成如下:

 dataDir=/opt/zookeeper/dataAndLog

   dataLogDir=/opt/zookeeper/dataAndLog

1.5 进入/opt/zookeeper/zookeeper-3.4.6/bin目录,启动zookeeper,命令为: ./zkServer.sh start

1.6 查看zookeeper 运行状态 ./zkServer.sh status,或者输入ps aux|grep zookeeper ,这里我们发现zookeeper 并没有正常启动,这里我们可以输入cat zookeeper.out 来查看启动信息

这里我们发现没有安装jdk

1.7 安装jdk

通过yum 安装openjdk1.7 yum -y install java-1.7.0-openjdk* ,jdk安装完成后输入 java -version  来查看jdk安装情况

1.8 再次启动zookeeper

输入 ./zkServer.sh start 重新启动zookeeper ,然后再次通过 ./zkServer.sh status  cat zookeeper.out  ps aux|grep zookeeper  来查看启动状态启动完成.

1.9 配置防火墙端口

Zookeeper 需要用到3个端口  2181 ,2888 ,3888 ,第一个是客户端连接的端口,后两个是做zookeeper集群时所用的端口。

修改防火墙配置文件  vi /etc/sysconfig/iptables 加入下面内容

-A INPUT -p tcp -m tcp --dport 2181 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 2888 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 3888 -j ACCEPT

然后 重启防火墙

/etc/init.d/iptables restart

2.0 集群的配置

在生产环境中,要配置成分布式模式,才能发挥威力。

ZooKeeper集群一般被称为ZooKeeper ensemble,或者 quorum.

准备3台机器

假设有三台机器,hostname和ip对应关系是:

192.168.1.101 hadoop101

192.168.1.102 hadoop102

192.168.1.103 hadoop103

ZooKeeper不存在明显的master/slave关系,各个节点都是服务器,leader挂了,会立马从follower中选举一个出来作为leader.

由于没有主从关系,也不用配置SSH无密码登录了,各个zk服务器是自己启动的,互相之间通过TCP端口来交换数据。

修改hadoop101的配置文件conf/zoo.cfg

....

....

clientPort=2181

server.1=hadoop101:2888:3888 /server.1=192.168.1.101:2888:3888

server.2=hadoop102:2888:3888/server.1=192.168.1.102:2888:3888

server.3=hadoop103:2888:3888/server.1=192.168.1.103:2888:3888

修改完后拷贝到 hadoop102,以及 hadoop103上.

然后启动每台机器,因为3个节点的启动是有顺序的,所以在陆续启动三个节点的时候,前面先启动的节点连接未启动的节点的时候会报出一些错误。可以忽略。

可以使用java客户端连接ZooKeeper集群中的任意一台服务器了。

2.分布式共享锁的应用

2.1  这里讲解一下使用java客户端来获取共享锁

这里有一个客户端类 DistributedLock.java 代码如下:

package com.daat.front.activity.web.actions.tools;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import org.apache.log4j.Logger;

import org.apache.zookeeper.CreateMode;

import org.apache.zookeeper.KeeperException;

import org.apache.zookeeper.WatchedEvent;

import org.apache.zookeeper.Watcher;

import org.apache.zookeeper.ZooDefs;

import org.apache.zookeeper.ZooKeeper;

import org.apache.zookeeper.data.Stat;

import com.daat.front.activity.service.bo.impl.BoActivity;

/**

 * 基于zoopkeeper的分布式共享锁

 * @author yank

 *

 */

public class DistributedLock implements Lock, Watcher {

private ZooKeeper zk;

private String root = "/locks";

private String lockName;

private String waitNode;

private String myZnode;

private CountDownLatch latch;

private int sessionTimeout = ;

private List<Exception> exception = new ArrayList<Exception>();

private static Logger log = Logger.getLogger(DistributedLock.class);

public DistributedLock(String config, String lockName) {

this.lockName = lockName;

try {

zk = new ZooKeeper(config, sessionTimeout, this);

Stat stat = zk.exists(root, false);

if (stat == null) {

zk.create(root, new byte[], ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);

}

} catch (IOException e) {

e.printStackTrace();

exception.add(e);

} catch (KeeperException e) {

e.printStackTrace();

exception.add(e);

} catch (InterruptedException e) {

e.printStackTrace();

exception.add(e);

}

}

public void process(WatchedEvent event) {

if (this.latch != null) {

this.latch.countDown();

}

}

public void lock() {

if (exception.size() > ) {

throw new LockException(exception.get());

}

try {

if (this.tryLock()) {

System.out.println("Thread " + Thread.currentThread().getId()+ " " + myZnode + " get lock true");

return;

} else {

waitForLock(waitNode, sessionTimeout);

}

} catch (KeeperException e) {

e.printStackTrace();

throw new LockException(e);

} catch (InterruptedException e) {

e.printStackTrace();

throw new LockException(e);

}

}

public boolean tryLock() {

try {

String splitStr = "_lock_";

if (lockName.contains(splitStr))

throw new LockException("lockName can not contains \\u000B");

myZnode = zk.create(root + "/" + lockName + splitStr, new byte[],ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);

System.out.println(myZnode + " is created ");

List<String> subNodes = zk.getChildren(root, false);

List<String> lockObjNodes = new ArrayList<String>();

for (String node : subNodes) {

String _node = node.split(splitStr)[];

if (_node.equals(lockName)) {

lockObjNodes.add(node);

}

}

Collections.sort(lockObjNodes);

System.out.println(myZnode + "==" + lockObjNodes.get());

if (myZnode.equals(root + "/" + lockObjNodes.get())) {

return true;

}

String subMyZnode = myZnode.substring(myZnode.lastIndexOf("/") + );

waitNode = lockObjNodes.get(Collections.binarySearch(lockObjNodes,subMyZnode) - );

} catch (KeeperException e) {

e.printStackTrace();

throw new LockException(e);

} catch (InterruptedException e) {

e.printStackTrace();

throw new LockException(e);

}

return false;

}

public boolean tryLock(long time, TimeUnit unit) {

try {

if (this.tryLock()) {

return true;

}

return waitForLock(waitNode, time);

} catch (Exception e) {

e.printStackTrace();

}

return false;

}

private boolean waitForLock(String lower, long waitTime)

throws InterruptedException, KeeperException {

Stat stat = zk.exists(root + "/" + lower, true);

if (stat != null) {

System.out.println("Thread " + Thread.currentThread().getId()+ " waiting for " + root + "/" + lower);

this.latch = new CountDownLatch();

this.latch.await(waitTime, TimeUnit.MILLISECONDS);

this.latch = null;

}

return true;

}

public void unlock() {

try {

System.out.println("unlock " + myZnode);

zk.delete(myZnode, -);

myZnode = null;

zk.close();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (KeeperException e) {

e.printStackTrace();

}

}

public void lockInterruptibly() throws InterruptedException {

this.lock();

}

public Condition newCondition() {

return null;

}

public class LockException extends RuntimeException {

private static final long serialVersionUID = 1L;

public LockException(String e) {

super(e);

}

public LockException(Exception e) {

super(e);

}

}

}

2.2 再写一个测试类 TestLock.java 代码如下:

package com.daat.front.base.web.tools;

import java.util.Date;

public class TestLock  implements Runnable{

public static void main(String[] args) {

for(int i=;i<;i++){

Thread ad=new Thread(new TestLock());

ad.start();

}

}

@Override

public void run() {

DistributedLock lock = null;

try {

System.out.println("线程开启:"+Thread.currentThread().getId());

//多个锁用“,” 分隔开

//lock = new DistributedLock("10.168.128.113:2181,10.168.173.159:2181", "amount");

Thread.sleep();

lock = new DistributedLock("192.168.122.129:2181", "testLock");

lock.lock();

System.out.println("线程:"+Thread.currentThread().getId()+"在"+new Date().getTime()+"时间获得锁");

Thread.sleep();

System.out.println("===Thread "+ Thread.currentThread().getId() + " running");

} catch (Exception e) {

e.printStackTrace();

}finally{

if (lock != null){

System.out.println("线程:"+Thread.currentThread().getId()+"在"+new Date().getTime()+"释放锁");

lock.unlock();

}

}

}

}

测试类是开启10个线程同时去做锁竞争操作,看看是否可以控制

获取锁---->释放锁  的操作,测试结果如下:

第一次测试:

线程开启:9

线程开启:11

线程开启:10

线程开启:12

线程开启:15

线程开启:14

线程开启:13

线程开启:16

线程开启:17

线程开启:18

线程:11在1478591252342时间获得锁

线程:11在1478591257342释放锁

线程:14在1478591257348时间获得锁

线程:14在1478591262349释放锁

线程:15在1478591262352时间获得锁

线程:15在1478591267352释放锁

线程:10在1478591267360时间获得锁

线程:10在1478591272360释放锁

线程:12在1478591272364时间获得锁

线程:12在1478591277364释放锁

线程:16在1478591277367时间获得锁

线程:16在1478591282368释放锁

线程:9在1478591282371时间获得锁

线程:9在1478591287371释放锁

线程:18在1478591285302时间获得锁

线程:18在1478591290302释放锁

线程:13在1478591285302时间获得锁

线程:13在1478591290302释放锁

线程:17在1478591285303时间获得锁

线程:17在1478591290303释放锁

第二次测试:

线程开启:9

线程开启:11

线程开启:12

线程开启:10

线程开启:13

线程开启:14

线程开启:15

线程开启:16

线程开启:18

线程开启:17

线程:17在1478591690760时间获得锁

线程:17在1478591694760释放锁

线程:18在1478591694767时间获得锁

线程:18在1478591698767释放锁

线程:14在1478591698770时间获得锁

线程:14在1478591702771释放锁

线程:15在1478591702775时间获得锁

线程:15在1478591706775释放锁

线程:12在1478591706778时间获得锁

线程:12在1478591710778释放锁

线程:11在1478591710783时间获得锁

线程:11在1478591714783释放锁

线程:9在1478591714786时间获得锁

线程:9在1478591718787释放锁

线程:10在1478591718790时间获得锁

线程:10在1478591722790释放锁

线程:16在1478591720773时间获得锁

线程:16在1478591724773释放锁

线程:13在1478591720774时间获得锁

线程:13在1478591724774释放锁

通过测试。

zookeeper的安装及共享锁的应用的更多相关文章

  1. Zookeeper的安装的配置

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt192 安装和配置详解 本文介绍的 Zookeeper 是以 3.2.2 这个 ...

  2. zookeeper的安装(图文详解。。。来点击哦!)

    zookeeper的安装(图文详解...来点击哦!) 一.服务器的配置 三台服务器: 192.168.83.133   sunshine 192.168.83.134   sunshineMin 19 ...

  3. (原) 1.1 Zookeeper单机安装

    本文为原创文章,转载请注明出处,谢谢 zookeeper 单机安装配置 1.安装前准备 linux系统(此文环境为Centos6.5) Zookeeper安装包,官网https://zookeeper ...

  4. ZooKeeper的安装、配置、启动和使用(一)——单机模式

    ZooKeeper的安装.配置.启动和使用(一)——单机模式 ZooKeeper的安装非常简单,它的工作模式分为单机模式.集群模式和伪集群模式,本博客旨在总结ZooKeeper单机模式下如何安装.配置 ...

  5. ZooKeeper 的安装和配置---单机和集群

    如题本文介绍的是ZooKeeper 的安装和配置过程,此过程非常简单,关键是如何应用(将放在下节及相关节中介绍). 单机安装.配置: 安装非常简单,只要获取到 Zookeeper 的压缩包并解压到某个 ...

  6. JDK+Tomcat+Zookeeper+DubboAdmin安装教程

    JDK+Tomcat+Zookeeper+DubboAdmin安装教程 1. 安装内容: JDK 1.8.131 Tomcat 7.0.77 Zookeeper 3.4.9 Dubbo admin 2 ...

  7. Zookeeper的安装部署

    1.Zookeeper的安装部署 7.1 Zookeeper工作机制 7.1.1.Zookeeper集群角色 Zookeeper集群的角色:  Leader 和  follower (Observer ...

  8. Zookeeper的安装配置及基本开发

    一.简介 Zookeeper 是分布式服务框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置项的管理等等. ZooKeeper的目标就 ...

  9. ZooKeeper的安装

    一.准备 需要提前安装好Java 准备好zookeeper的软件包:软件包地址   二.部署 解压zookeeper压缩包到指定目录 执行如下命令: .tar.gz -C /opt/   三.修改配置 ...

随机推荐

  1. 占位符golang

    定义示例类型和变量 type Human struct { Name string } var people = Human{Name:"zhangsan"} 普通占位符 占位符 ...

  2. Java 内存模型_2

    title: Java 内存模型_2 date: 2017-01-28 02:04:06 tags: [JMM] categories: [Programming,Java] --- Why 理解 J ...

  3. Google hack语法

    基础语法: 1.语法说明: inurl: 在url地址栏中显示的信息页面 intext: 显示在正文信息中的内容页面 site: 限制显示你某个域名的所有页面 filetype: 搜索文件的后缀或者扩 ...

  4. Django_rest_framework_渲染器/解析器/路由控制/分页

    目录 渲染器 解析器 路由控制 分页 渲染器 简介 什么是渲染器 根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件. 渲染器的作用 序列化.友好的展示数据 渲染器配置 首先要在set ...

  5. 探路者-Beta发布中间产物

    版本控制 版本控制报告:http://www.cnblogs.com/linym762/p/7881047.html git地址:https://git.coding.net/clairewyd/to ...

  6. 第一个scrim任务分布

    一.项目经理:郭健豪 二.scrim分工 杨广鑫.郭健豪:制作第一个精选页面布局,和代码实现.如:实现图书推荐布局中图书的排布,搜索框代码的实现,消息提示的跳转 李明.郑涛:实现第一个精选页面数据库的 ...

  7. java8之重新认识HashMap(转自美团技术团队)

    java8之重新认识HashMap 摘要 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型.随着JDK(JavaDevelopmet Kit)版本的更新,JDK1.8对Ha ...

  8. 更新ubuntu的源

    什么是Ubuntu的软件源? 我们在使用Debian或者Ubuntu的apt-get工具来安装需要的软件时,其实就是从服务器获取需要安装的软件并把它安装在本地计算机的过程.所谓的软件源,就是我们获取软 ...

  9. 评论alpha发布以及PSP

    讲解顺序: 1.  俄罗斯方块   武志远 俄罗斯方块有自己新颖的玩法加在里面 ,可以进行游戏,界面友好但不美观,与传统玩法相比增加了经验值,这是一个很好的创意,游戏运行也很流畅,并找到两名同学现场体 ...

  10. Delphi控件-复合控件【转】

    复合控件复合控件是Delphi控件中非常重要的一种控件,复合控件就是将两个或两个以上的控件重新组合成一个新的控件.例如TspinEdit.TlabeledEdit.TDBNavigator等就是复合控 ...