转自:http://agapple.iteye.com/blog/1111377

背景

前段时间看了S4流计算引擎,里面使用到了zookeeper进行集群管理,所以也就花了点时间研究了下zookeeper,不求看懂所有源码,但求了解其实现机制和原理,清楚其基本使用。这也是为后续hadoop,gridgain的分布式计算的产品。

学习

首先就是收集一些前人的一些学习资料和总结内容,方便自己快速入门。

这里罗列了几篇不错的文章:

看了这两篇文章,基本可以对zookeeper有了一个感性的认识,它是一个什么?
 
zookeeper功能点:
  • 统一命名空间(Name Service)
  • 配置推送 (Watch)
  • 集群管理(Group membership)

统一命名空间

在zookeeper中实现了一个类似file system系统的数据结构,比如/zookeeper/status。 每个节点都对应于一个znode节点。

znode节点的数据结构模型:

znode的数据结构内容:

  • czxid

    The zxid of the change that caused this znode to be created.

  • mzxid

    The zxid of the change that last modified this znode.

  • ctime

    The time in milliseconds from epoch when this znode was created.

  • mtime

    The time in milliseconds from epoch when this znode was last modified.

  • version

    The number of changes to the data of this znode.

  • cversion

    The number of changes to the children of this znode.

  • aversion

    The number of changes to the ACL of this znode.

  • ephemeralOwner

    The session id of the owner of this znode if the znode is an ephemeral node. If it is not an ephemeral node, it will be zero.

  • dataLength

    The length of the data field of this znode.

  • numChildren

    The number of children of this znode.

说明: zxid (ZooKeeper Transaction Id,每次请求对应一个唯一的zxid,如果zxid a < zxid b ,则可以保证a一定发生在b之前)。

针对树状结构的处理,来看一下客户端使用的api :

  1. String create(String path, byte data[], List<ACL> acl, CreateMode createMode)
  2. void   create(String path, byte data[], List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx)
  3. void delete(String path, int version)
  4. void delete(String path, int version, VoidCallback cb, Object ctx)
  5. Stat setData(String path, byte data[], int version)
  6. void setData(String path, byte data[], int version, StatCallback cb, Object ctx)
  7. Stat setACL(String path, List<ACL> acl, int version)
  8. void setACL(String path, List<ACL> acl, int version, StatCallback cb, Object ctx)
  9. Stat exists(String path, Watcher watcher)
  10. Stat exists(String path, boolean watch)
  11. void exists(String path, Watcher watcher, StatCallback cb, Object ctx)
  12. void exists(String path, boolean watch  , StatCallback cb, Object ctx)
  13. byte[] getData(String path, Watcher watcher, Stat stat)
  14. byte[] getData(String path, boolean watch  , Stat stat)
  15. void   getData(String path, Watcher watcher, DataCallback cb, Object ctx)
  16. void   getData(String path, boolean watch  , DataCallback cb, Object ctx)
  17. List<String> getChildren(String path, Watcher watcher)
  18. List<String> getChildren(String path, boolean watch  )
  19. void  getChildren(String path, Watcher watcher, ChildrenCallback cb, Object ctx)
  20. void  getChildren(String path, boolean watch  , ChildrenCallback cb, Object ctx)
  21. List<String> getChildren(String path, Watcher watcher, Stat stat)
  22. List<String> getChildren(String path, boolean watch  , Stat stat)
  23. void getChildren(String path, Watcher watcher, Children2Callback cb, Object ctx)
  24. void getChildren(String path, boolean watch  , Children2Callback cb, Object ctx)

说明:每一种按同步还是异步,添加指定watcher还是默认watcher又分为4种。默认watcher可以在ZooKeeper zk = new ZooKeeper(serverList, sessionTimeout, watcher)中进行指定。如果包含boolean watch的读方法传入true则将默认watcher注册为所关注事件的watch。如果传入false则不注册任何watch

CreateMode主要有几种:

  • PERSISTENT (持续的,相比于EPHEMERAL,不会随着client session的close/expire而消失)
  • PERSISTENT_SEQUENTIAL
  • EPHEMERAL (短暂的,生命周期依赖于client session,对应session close/expire后其znode也会消失)
  • EPHEMERAL_SEQUENTIAL  (SEQUENTIAL意为顺序的)
AsyncCallback异步callback,根据操作类型的不同,也分几类:
  • StringCallback
  • VoidCallback
  • StatCallback
  • DataCallback  (getData请求)
  • ChildrenCallback
  • Children2Callback
对应的ACL这里有篇不错的文章介绍,http://rdc.taobao.com/team/jm/archives/947

配置推送(Watcher)

zookeeper为解决数据的一致性,使用了Watcher的异步回调接口,将服务端znode的变化以事件的形式通知给客户端,主要是一种反向推送的机制,让客户端可以做出及时响应。比如及时更新后端的可用集群服务列表。

这里有篇文章介绍Watcher/Callback比较详细,可以参考下:

如果想更好的理解Watcher的使用场景,可以了解下使用Watcher机制实现分布式的Barrier , Queue , Lock同步。

Barrier例子:

  1. public class Barrier implements Watcher {
  2. private static final String addr = "10.20.156.49:2181";
  3. private ZooKeeper           zk   = null;
  4. private Integer             mutex;
  5. private int                 size = 0;
  6. private String              root;
  7. public Barrier(String root, int size){
  8. this.root = root;
  9. this.size = size;
  10. try {
  11. zk = new ZooKeeper(addr, 10 * 1000, this);
  12. mutex = new Integer(-1);
  13. Stat s = zk.exists(root, false);
  14. if (s == null) {
  15. zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  16. }
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. public synchronized void process(WatchedEvent event) {
  22. synchronized (mutex) {
  23. mutex.notify();
  24. }
  25. }
  26. public boolean enter(String name) throws Exception {
  27. zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  28. while (true) {
  29. synchronized (mutex) {
  30. List<String> list = zk.getChildren(root, true);
  31. if (list.size() < size) {
  32. mutex.wait();
  33. } else {
  34. return true;
  35. }
  36. }
  37. }
  38. }
  39. public boolean leave(String name) throws KeeperException, InterruptedException {
  40. zk.delete(root + "/" + name, 0);
  41. while (true) {
  42. synchronized (mutex) {
  43. List<String> list = zk.getChildren(root, true);
  44. if (list.size() > 0) {
  45. mutex.wait();
  46. } else {
  47. return true;
  48. }
  49. }
  50. }
  51. }
  52. }

测试代码:

  1. public class BarrierTest {
  2. public static void main(String args[]) throws Exception {
  3. for (int i = 0; i < 3; i++) {
  4. Process p = new Process("Thread-" + i, new Barrier("/test/barrier", 3));
  5. p.start();
  6. }
  7. }
  8. }
  9. class Process extends Thread {
  10. private String  name;
  11. private Barrier barrier;
  12. public Process(String name, Barrier barrier){
  13. this.name = name;
  14. this.barrier = barrier;
  15. }
  16. @Override
  17. public void run() {
  18. try {
  19. barrier.enter(name);
  20. System.out.println(name + " enter");
  21. Thread.sleep(1000 + new Random().nextInt(2000));
  22. barrier.leave(name);
  23. System.out.println(name + " leave");
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. }

通过该Barrier,可以协调不同任务之间的同步处理,这里主要还是利用了Watcher机制的反向推送,避免客户端的循环polling动作,只要针对有事件的变化做一次响应。

集群管理

我不罗嗦,taobao有几篇文章已经介绍的很详细。

zookeeper集群对server进行了归类,可分为:
  • Leader
  • Follower
  • Obserer
说明:
1. Leader/Follower会通过选举算法进行选择,可以看一下http://zookeeper.apache.org/doc/r3.3.2/recipes.html 里的Leader Election章节。
2. Observer主要是为提升zookeeper的性能,observer和follower的主要区别就是observer不参与Leader agreement vote处理。只提供读节点的处理,类似于master/slave的读请求。 (http://zookeeper.apache.org/doc/r3.3.2/zookeeperObservers.html)

  1. server.1:localhost:2181:3181:observer

3. 可通过命令行,查看当前server所处的状态

  1. [ljh@ccbu-156-49 bin]$ echo stat | nc localhost 2181
  2. Zookeeper version: 3.3.3--1, built on 06/24/2011 13:12 GMT
  3. Clients:
  4. /10.16.4.30:34760[1](queued=0,recved=632,sent=632)
  5. /127.0.0.1:43626[0](queued=0,recved=1,sent=0)
  6. /10.16.4.30:34797[1](queued=0,recved=2917,sent=2917)
  7. Latency min/avg/max: 0/0/33
  8. Received: 3552
  9. Sent: 3551
  10. Outstanding: 0
  11. Zxid: 0x200000003
  12. Mode: follower  ##当前模式
  13. Node count: 8

使用zookeeper,我们能干些什么?

官方文档中,有举了几个应用场景,就是使用zookeeper提供分布式锁机制,从而实现分布式的一致性处理。

典型的几个场景:

  • Barrier
  • Queue
  • Lock
  • 2PC
 

其他

zookeeper基本是基于API和console进行znode的操作,并没有一个比较方便的操作界面,这里也发现了taobao 伯岩写的一个工具,可以比较方便的查询zookeeper信息。

工具的开发语言主要是node.js(最近比较火),其标榜的是无阻塞的api使用。其原理主要是基于google的V8(chrome的javascript的解析器,C语言编写),node.js本身是基于js语法进行开发,通过V8解析为C语言的执行代码

其标榜的无阻塞I/O实现,那可想而知就是linux系统下的select/poll的I/O模型。有兴趣的可以看下node.js的官网,下载一个玩玩。

文档地址: http://www.blogjava.net/killme2008/archive/2011/06/06/351793.html

代码地址:  https://github.com/killme2008/node-zk-browser

通过git下载源码后,需要安装下node.js的几个模块express, express-namespace, zookeeper。 node.js下有个比较方便的模块管理器npm,类似于redhat的rpm,ubuntu的apt-get。

安装模块:

  1. npm install -g express

几个界面:

(转)zookeeper学习记录--附browser的更多相关文章

  1. Zookeeper学习记录(一):设计与实现

    概述 Zookeeper是一个分布式的.开源的分布式应用协调服务.它暴露了一组简单的基础原件,分布式应用可以在这些原件之上实现更高级别的服务,如同步.配置维护.群组.和命名.它被设计成容易编程实现的, ...

  2. zookeeper学习记录第二篇-----安装、配置、启动

    搭建zk集群,起码保证3台虚拟机的配置,本人使用的虚拟机环境为wm14+centos7+jdk1.8 下载地址 zk的tar包下载地址:http://mirror.bit.edu.cn/apache/ ...

  3. zookeeper学习记录

    ZooKeeper:是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.他主要用来解决分布式应用中的数据管理的一致性问题 ...

  4. Zookeeper学习记录(二):使用以及配置

    zookeeper已经介绍了它的原理设计以及实现方式,我们接下来介绍zookeeper的使用方法以及简单配置. 下载 获取Zookeeper的发布包,从Apache下载映像中下载一个最新稳定版本. 单 ...

  5. Zookeeper学习记录及Java客户端连接示例

    1. Zookeeper 1.1 简介 ZooKeeper is a centralized service for maintaining configuration information, na ...

  6. SpringBoot的旅游项目——day01(学习记录附赠源码)

    前言 学完SpringBoot的项目,Github地址,欢迎start,一起学习! 第一天 一.技术选型 基于SpringBoot+VUE的前后端分离的仿照马蜂窝的项目. 后端选用的技术为: Spri ...

  7. MongoDB实战开发 【零基础学习,附完整Asp.net示例】

    MongoDB实战开发 [零基础学习,附完整Asp.net示例] 阅读目录 开始 下载MongoDB,并启动它 在C#使用MongoDB 重构(简化)代码 使用MongoDB的客户端查看数据 使用Mo ...

  8. mono for android 学习记录

    C#开发Android应用实战(全 扫描 中文版) 学习记录: 拖完控件后,不要急着按F5,需要重新生成,才能自动修改 Resource.Designer.cs 文件 1. Activity 是基于a ...

  9. ZooKeeper 学习笔记

    ZooKeeper学习笔记 1.   zookeeper基本概念 zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是hadoop和Habase的重要组件,是为分布式应用提供一致性服 ...

随机推荐

  1. Caffe-windows上训练自己的数据

    1.数据获取 在网上选择特定类别,下载相应的若干张图片.可以网页另存或者图片下载器.本例中保存了小狗.菊花.梅花三类各两百多张. 2.重命名 import os import os.path root ...

  2. 用js实现导航菜单点击切换选中时高亮状态

    随着用户点击导航或菜单上不同的页面,出现此选项高亮显示或变为一个新的样式是经常用到的.实现它所用的原理就是通过js中的location.href得到当前页面的地址,然后在与导航上的链接地址匹对,相同的 ...

  3. WCF入门教程一[什么是WCF]

    一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...

  4. Jmeter使用

    好久没有试过Jmeter了,下载个新版本试试,顺便温习一下. 1. 如何修改JMeter语言环境 在菜单栏中通过“选项”–“选择语言”选了英文后,下次登录JMeter,还是显示的中文,修改语言无效.关 ...

  5. Oracle 支持正则表达式的函数

    内容提要 oracle 10g 增加的正则表达式函数有以下四种: regexp_like() --返回满足条件的字段 regexp_instr() --返回满足条件的字符或字符串的位置 regexp_ ...

  6. Spring入门学习(一)

    SpringMVC基础平台补充(2016.03.03) 如果想要开发SpringMVC,那么前期依次安装好:JDK(jdk-8u74-windows-x64,安装后配置环境变量JAVA_HOME和CL ...

  7. 在mui中遇到的内容覆盖导航栏的问题

    一.问题描述: 公司项目中为了让内容以页面的形式显示,并要格式化页面内容,采用了百度的UEditor编辑器来显示内容,但是遇到了一个问题就是当下拉页面到一定距离之后,页面上方的导航栏会被内容遮盖. 二 ...

  8. 【VNC】Ubuntu14.04LTS下安装VNC View

    # apt-get install tightvncserver vnc4server gnome-panel gnome-settings-daemon metacity nautilus gnom ...

  9. IntelliJ IDEA优化总结

    1.修改JVM参数 (IntelliJ IDEA 10.0.1包含以上版本不需要设置)修改idea.exe.vmoptions配置文件调整以下内容:-Xms256m-Xmx384m-XX:MaxPer ...

  10. phpinfo详解

    php的很多信息都可以从phpinfo中获取,下面就详细了解下phpinfo的输出内容 1 php版本信息 第一行显示当前php版本 PHP Version 5.5.12 2 php.ini文件的位置 ...