一场雨

zookeeper笔记

几个注意点:

Alt text

使用版本来阻止并行操作的不一致性:

1.客户端c1写入了第一个版本的/config。

2.客户端c2读取了/config并写入了第二个版本。

3.客户端c1尝试对/config进行写入,但因版本号不匹配二请求失败。

Alt text

zookeeper架构总览

Alt text

客户端重连 (通过zxid去匹配)

1.客户端连接s1

2.客户端执行创建操作。操作成功并获得服务器分配的zxid 1.

3.客户端与s1断开连接。

4.客户端尝试连接s2,但是服务器有一个较低的zxid 1.

5.客户端尝试连接s3并成功。

znode节点可以是持久节点,还可以是临时节点。持久节点只能通过调用delete来删除。而临时节点不是,当创建该节点的客户端崩溃或者关闭了与zookeeper的连接时,这个节点就会被删除。

znode一共有4种类型:持久的,临时的,持久有序的,临时有序的。

一个监视点(watch)表示一个与之相关联的znode节点和事件类型组成的单次触发器。

客户端设置的每个监视点与会话关联,如果会话过期,等待中的监视点将会被删除。

监视点有两种类型:数据监视点和子节点监视点。创建,删除或设置一个znode节点数据都会触发数据监视点,exists和getData这两个操作可以设置数据监视点。只有getChildren操作可以设置子节点监视点,这种监视点只有在znode子节点创建或删除时才会触发。

对于监视点的一个重要问题是,一旦设置了监视点就无法移除。想要移除一个监视点,只有两种方法,一是触发这个监视点,二是使其会话被关闭或者过期。

ZooKeeper 通过访问列表(ACL)来控制访问权限。

https://github.com/fpj/zookeeper-book-example

主从模式流程:

master – worker – client 顺序

1.master执行
/
/workers
/tasks
/assign
/status

/
    /workers  //添加过 监视节点  workersChangeWatcher
    /tasks  //添加过 监视节点 tasksChangeWatcher
    /assign
    /status
    /master //临时节点

2.worker执行

/
    /workers
            /worker-90504b04 //后   触发监视器,然后执行workersGetChildrenCallback
    /tasks
    /assign
            /worker-90504b04 //先   监视该路径下的 NodeChildrenChanged 有变化就是 getTasks();在执行一遍,获取最新数据
    /status
    /master

在master.java中,因为有监控器,所以

2017-02-08 15:32:29,574 - INFO  - [main-EventThread:Master$7@468] - Succesfully got a list of workers: 1 workers
2017-02-08 15:32:29,574 - INFO  - [main-EventThread:Master@496] - --children.get(0)---worker-90504b04
2017-02-08 15:32:29,574 - INFO  - [main-EventThread:Master@506] - Removing and setting

3.task创建

————————— client.java中—————–

/
    /workers
            /worker-90504b04
    /tasks
            /task-0000000000  //create  先创建任务,然后查看 /status/task-0000000000(1)
            /task-0000000001  //create
    /assign
            /worker-90504b04
    /status
    /master

————————— worker.java中—————–

/
    /workers
            /worker-90504b04
    /tasks
            /task-0000000000  //create
            /task-0000000001  //create
    /assign
            /worker-90504b04
    /status
    /master

————————— master.java中—————–

触发master.java中tasks的监视器tasksChangeWatcher,触发getTasks();同时再次添加监视器。

getTasks();执行

2017-02-08 16:15:00,458 - INFO  - [main-EventThread:Master$14@760] - Assignment path: /assign/worker-90504b04/task-0000000000
2017-02-08 16:15:00,458 - INFO  - [main-EventThread:Master$14@760] - Assignment path: /assign/worker-90504b04/task-0000000001

然后执行createAssignment();//分配任务

/
    /workers
            /worker-90504b04
    /tasks
            /task-0000000000
            /task-0000000001
    /assign
            /worker-90504b04
                            /task-0000000000
                            /task-0000000001
    /status
    /master

任务分配结束之后,就删除tasks下的任务 deleteTask(String name);

/
    /workers
            /worker-90504b04
    /tasks
    /assign
            /worker-90504b04
                            /task-0000000000
                            /task-0000000001
    /status
    /master

————————— worker.java中—————–

在有任务之后,

2017-02-08 16:15:00,467 - INFO  - [pool-1-thread-1:Worker$5$1@304] - Looping into tasks
2017-02-08 16:15:00,471 - INFO  - [pool-1-thread-1:Worker$6$1@349] - Executing your task: Sample task
2017-02-08 16:15:00,473 - INFO  - [pool-1-thread-1:Worker$6$1@349] - Executing your task: Another sample task
2017-02-08 16:15:00,473 - INFO  - [main-EventThread:Worker$7@372] - Created status znode correctly: /status/task-0000000000
2017-02-08 16:15:00,474 - INFO  - [main-EventThread:Worker$8@390] - Task correctly deleted: /assign/worker-90504b04/task-0000000000
2017-02-08 16:15:00,476 - INFO  - [main-EventThread:Worker$7@372] - Created status znode correctly: /status/task-0000000001
2017-02-08 16:15:00,476 - INFO  - [main-EventThread:Worker$8@390] - Task correctly deleted: /assign/worker-90504b04/task-0000000001

&

/
    /workers
            /worker-90504b04
    /tasks
            /task-0000000000 (异步,不知道此时有没有)
            /task-0000000001
    /assign
            /worker-90504b04
                            /task-0000000000   这边一直有监控NodeChildrenChanged,然后执行getTasks();循环子节点列表(什么子节点),获取任务信息并执行
                            /task-0000000001
    /status
    /master

然后,在status下添加数据

/
    /workers
            /worker-90504b04
    /tasks
    /assign
            /worker-90504b04
                            /task-0000000000
                            /task-0000000001
    /status
            /task-0000000000
            /task-0000000001
    /master

接着,删除/assign/worker-90504b04/下数据/assign/worker-90504b04/task-0000000000(1) (worker.java中)

/
    /workers
            /worker-90504b04
    /tasks
    /assign
            /worker-90504b04
    /status
            /task-0000000000
            /task-0000000001
    /master

————————— client.java中—————–

status下有数据之后

获取数据并校验(校验:)

2017-02-08 16:15:00,479 - INFO  - [main-EventThread:Client$4@201] - Task /status/task-0000000000, done
2017-02-08 16:15:00,481 - INFO  - [main-EventThread:Client$4@201] - Task /status/task-0000000001, done

然后将节点删掉

/
    /workers
            /worker-90504b04
    /tasks
    /assign
            /worker-90504b04
    /status
    /master