Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ zookeeper

分布式系统服务ZooKeeper的学习历程

####一.入门
#### 一.入门

[ZooKeeper Overview](https://github.com/llohellohe/zookeeper/blob/master/docs/overview.md)

[Watcher的简单例子](https://github.com/llohellohe/zookeeper/blob/master/docs/java-example.md)

[Watcher例子的类图](https://raw.github.com/llohellohe/zookeeper/master/docs/class-java-example.png)

####二.O'Reilly.ZooKeeper.Distributed process coordination.2013笔记
#### 二.O'Reilly.ZooKeeper.Distributed process coordination.2013笔记

[按章节笔记](https://github.com/llohellohe/llohellohe.github.com/tree/master/readers/ZooKeeper)

####三.深入
#### 三.深入

[分布式一致性算法Paxos](https://github.com/llohellohe/llohellohe.github.com/blob/master/_posts/2014-01-04-paxos.md)

[源代码解读之ZooKeeper](https://github.com/llohellohe/llohellohe.github.com/blob/master/_posts/2014-01-04-read-zookeeper-source-code-zookeeper.md)
Expand All @@ -23,5 +26,3 @@ zookeeper
[源代码解读之ClientCnxnSocketNIO](https://github.com/llohellohe/llohellohe.github.com/blob/master/_posts/2014-02-02-read-zookeeper-source-code-nio-socket.md)

[源代码解读之Jute生成传输协议消息体](https://github.com/llohellohe/llohellohe.github.com/tree/master/readers/ZooKeeper/11-传输协议.md)


58 changes: 31 additions & 27 deletions docs/java-api-basic.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,59 @@
###创建ZooKeeper Session
### 创建ZooKeeper Session

可以通过两种方式,创建ZooKeeper的Session,不带sessionId和带sessionId(需要提供密码)

1. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
2. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,boolean canBeReadOnly)
3. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,long sessionId, byte[] sessionPasswd)
4. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
1. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
2. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,boolean canBeReadOnly)
3. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,long sessionId, byte[] sessionPasswd)
4. ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,long sessionId, byte[] sessionPasswd, boolean
canBeReadOnly)

其中`Wather`接口定义了处理ZooKeeper事件的方法:

abstract public void process(WatchedEvent event)

connectString类似:127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a

###ZooKeeper Session初始化过程
1. 设置默认的Watcher
2. 通过ConnectStringParser将connectString解析成服务器列表,并根据列表创建HostProvider。
3. 创建ClientCnxn
4. 调用ClientCnxn的start()方法,启动SendThread和EventThread。
connectString类似:127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a

### ZooKeeper Session初始化过程

1. 设置默认的Watcher
2. 通过ConnectStringParser将connectString解析成服务器列表,并根据列表创建HostProvider。
3. 创建ClientCnxn
4. 调用ClientCnxn的start()方法,启动SendThread和EventThread。

创建SendThread和EventThread的时候,会设置`UncaughtExceptionHandler`,用于处理线程内的异常处理。

并且这两个线程会被设置为守护线程。

### ClientCnxn创建过程

1. ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,ClientWatchManager
watcher, ClientCnxnSocket clientCnxnSocket, boolean canBeReadOnly)
2. ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,ClientWatchManager
watcher, ClientCnxnSocket clientCnxnSocket,long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)

###ClientCnxn创建过程
1. ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket, boolean canBeReadOnly)
2. ClientCnxn(String chrootPath, HostProvider hostProvider, int sessionTimeout, ZooKeeper zooKeeper,ClientWatchManager watcher, ClientCnxnSocket clientCnxnSocket,long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)


其中chrootPath为相对路径,如`127.0.0.1:3002/app/a`的相对路径为/app/a

HostProvider为zk服务器提供者。

ClientCnxnSocket是为了完成底层的数据通信(通过Socket)实现。

#####ClientCnxnSocket
##### ClientCnxnSocket

可以通过设置`zookeeper.clientCnxnSocket`变量,设置ClientCnxnSocket的实现,默认为`ClientCnxnSocketNIO`,也可以选择Apache Netty的Client实现。


###SendThread
SendThread负责底层的通信,同时它将解析出Event信息,然后交给EventThread处理。
###EventThread

### SendThread

SendThread负责底层的通信,同时它将解析出Event信息,然后交给EventThread处理。

### EventThread

EventThread是个守护线程,它使用`LinkedBlockingQueue`来保存等待处理的Events。

通过循环调用LinkedBlockingQueue的take()方法,或者Event。

如果获得的Event是eventOfDeath的话,则结束进程。

否则则处理该事件,并调用CallBack。
##EventThread和SendThread上面部分(**需要补充完善**)


## EventThread和SendThread上面部分(**需要补充完善**)
79 changes: 40 additions & 39 deletions docs/java-example.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
###ZooKeeper Watcher代码实例
### ZooKeeper Watcher代码实例

##### 主要的相关类和接口

#####主要的相关类和接口
`Executor` 实现了`Wathcer`接口、`Runnable`接口、`DataMonitorListener`接口。

通过connectString 监视ZooKeeper的一个ZNode。
Expand All @@ -11,36 +12,38 @@

DataMonitor处理ZNode发生变化时的process,以及处理StatCallback的回调方法。

#####Watcher接口
##### Watcher接口

Watcher接口定义了process(WatchedEvent event) 方法,以及定义了接口Event。

接口Event中定义了KeeperState和EventType。

#####WatchedEvent
##### WatchedEvent

WatchedEvent由KeeperState、EventType和path组成。

它代表当前ZooKepper的连接状态,并且提供发生事件的znode路径以及时间类型。

其中KeeperState代表ZooKeeper的连接状态,分别为:

1. Disconnected
2. NoSyncConnected
3. SyncConnected
4. AuthFailed
5. ConnectedReadOnly
6. SaslAuthenticated
7. Expired

1. Disconnected
2. NoSyncConnected
3. SyncConnected
4. AuthFailed
5. ConnectedReadOnly
6. SaslAuthenticated
7. Expired

EventType代表node的状态变更,分别为:

1. None
2. NodeCreated
3. NodeDeleted
4. NodeDataChanged,就算设置重复的数据也会有该事件
5. NodeChildrenChanged
1. None
2. NodeCreated
3. NodeDeleted
4. NodeDataChanged,就算设置重复的数据也会有该事件
5. NodeChildrenChanged

##### AsyncCallback接口

#####AsyncCallback接口
StatCallback接口是AsyncCallback的一种。

AsyncCallback一共定义了如下几个CallBack
Expand All @@ -53,61 +56,59 @@ AsyncCallback一共定义了如下几个CallBack
6. VoidCallback
7. Children2Callback

###创建ZooKeeper Session
### 创建ZooKeeper Session

通过

ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)

就可以创建Zookeeper的一个Session。

#### A Simple Watch Client 代码实例

####A Simple Watch Client 代码实例
##### 过程和原理

#####过程和原理
1. 初始化连接到ZooKeeper,并且注册一个监视器W
2. W在接收到事件后,执行process()方法,根据事件的state()关闭或者重新启动额外的任务进程。
3. 如果发生事件的znode和注册的znode路径一致,则调用ZooKeeper的exist()方法,然后执行StatCallback这个回调方法。
4. 在StatCallback的回调方法中,获得znode对应的数据
5. 如果数据存在,则执行打印出响应的结果

1. 初始化连接到ZooKeeper,并且注册一个监视器W
2. W在接收到事件后,执行process()方法,根据事件的state()关闭或者重新启动额外的任务进程。
3. 如果发生事件的znode和注册的znode路径一致,则调用ZooKeeper的exist()方法,然后执行StatCallback这个回调方法。
4. 在StatCallback的回调方法中,获得znode对应的数据
5. 如果数据存在,则执行打印出响应的结果
###### 连接到客户端

######连接到客户端
sh zkCli.sh -server 127.0.0.1:2181

运行后`Executor.main`后,

会得到一个WatchEvent,它的state为SyncConnected,type为null。


如果此时set znode 结点的数据,比如:

set /yangqi_test new-data

会得到一个WatchEvent,它的state为SyncConnected,type为NodeDataChanged 。

相应的,删除结点的时候,将获得类型为NodeDeleted 的Event。创建结点的时候为NodeCreated 。

#### ZooKeeper.exists()

####ZooKeeper.exists()
public void exists(final String path, Watcher watcher,
StatCallback cb, Object ctx)

其中:

interface StatCallback extends AsyncCallback {
public void processResult(int rc, String path, Object ctx, Stat stat);
}



StatCallback 中只有一个方法processResult(),用于处理exits()方法后的回调。

####ZooKeeper.getData()
#### ZooKeeper.getData()

public byte[] getData(String path, boolean watch, Stat stat)
用于获得指定路径的数据。

用于获得指定路径的数据。

#####引用资料
1. http://zookeeper.apache.org/doc/r3.1.2/javaExample.html#sc_design
##### 引用资料

1. http://zookeeper.apache.org/doc/r3.1.2/javaExample.html#sc_design
57 changes: 30 additions & 27 deletions docs/overview.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,52 @@
####ZooKeeper简介
#### ZooKeeper简介

ZooKeeper的目的,为分布式应用提供分布式的协同服务。

zk提供了一组原语,分布式系统可以根据这组原语构建更高级别的服务:比如同步、配置维护、组和命名。

#####文件系统和通知机制
##### 文件系统和通知机制

ZooKeeper的ZNode类似于文件系统,只不过每个节点还可以额外存放数据。

当节点发生变化时(创建、删除、数据变更),可以通知各个客户端。

因此ZooKeeper可以应用的场景有:

1. 统一配置:把配置放在ZooKeeper的节点中维护,当配置变更时,客户端可以收到变更的通知,并应用最新的配置。
2. 集群管理:集群中的节点,创建ephemeral的节点,一旦断开连接,ephemeral的节点会消失,其它的集群机器可以收到消息。
3. 分布式锁:多个客户端发起节点创建操作,只有一个客户端创建成功,从而获得锁。
1. 统一配置:把配置放在ZooKeeper的节点中维护,当配置变更时,客户端可以收到变更的通知,并应用最新的配置。
2. 集群管理:集群中的节点,创建ephemeral的节点,一旦断开连接,ephemeral的节点会消失,其它的集群机器可以收到消息。
3. 分布式锁:多个客户端发起节点创建操作,只有一个客户端创建成功,从而获得锁。

构建正确的协同服务非常的困难,特别是那些资源竞争、死锁等情况,通过zk,分布式系统不需要从新开始构建协同服务。

zk提供的原语包含:

1. create
2. delete
3. exists
4. get data
5. set data
6. get chiledren
7. sync
1. create
2. delete
3. exists
4. get data
5. set data
6. get chiledren
7. sync

#### 设计目标

####设计目标
1. 足够简单:结构类似文件系统的(结点可以带数据,但是不能太大)
2. 冗余:保证可靠性
3. 顺序
4. 快:基于内存的操作
1. 足够简单:结构类似文件系统的(结点可以带数据,但是不能太大)
2. 冗余:保证可靠性
3. 顺序
4. 快:基于内存的操作

####保证
#### 保证

ZooKeeper保证了:

1. 顺序一致性:客户端的操作会被按照顺序执行
2. 原子性:操作要不失败要不成功
3. 可靠性:一旦写入成功,数据就会被保持,直到下次覆盖。
4. 实时性
5. 单一系统镜像(single system image):不管连接到zk集群的那台机器,客户端看到的视图都是一致的
1. 顺序一致性:客户端的操作会被按照顺序执行
2. 原子性:操作要不失败要不成功
3. 可靠性:一旦写入成功,数据就会被保持,直到下次覆盖。
4. 实时性
5. 单一系统镜像(single system image):不管连接到zk集群的那台机器,客户端看到的视图都是一致的

#### 实现

####实现
ZooKeeper的组件包含:

![image](http://zookeeper.apache.org/doc/trunk/images/zkcomponents.jpg)
Expand All @@ -53,7 +57,6 @@ ZooKeeper的组件包含:

读的时候,会从各自server的内存数据库中读数据,写则是通过一致性协议完成(leader/follwer)的。

####参考资料:

1. [Zookeeper的应用场景](http://ronghao.iteye.com/blog/1461798)
#### 参考资料:

1. [Zookeeper的应用场景](http://ronghao.iteye.com/blog/1461798)