客户端向系统中增加任务。在本例中,我们不关心任务的实际组成。现在我们假设客户端需要master-worker系统运行一个命令cmd。要在系统中增加一个任务,客户端执行下面的命令:
[zk: localhost:2181(CONNECTED) 0] create -s /tasks/task- "cmd"
Created /tasks/task-0000000000
为了让新增的任务有顺序,我们让任务节点是顺序性的,自然就形成了一个队列。客户端现在不得不等到任务被执行。一旦任务完成,那个执行任务的worker就会为task创建一个状态节点。当客户端看到任务的状态节点被创建时认为任务已经被执行了。自然,客户端需要监视状态节点的创建:
[zk: localhost:2181(CONNECTED) 1] ls /tasks/task-0000000000 true
[]
[zk: localhost:2181(CONNECTED) 2]
执行任务的worker创建了一个孩子节点\/tasks\/task-0000000000。这就是通过ls命令来监视\/tasks\/task-0000000000孩子节点的原因。
一旦任务节点被创建了,master就会观察到下面的事件:
[zk: localhost:2181(CONNECTED) 6]
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks
master接下来检查新的任务,获取可用的worker列表,并把它指派给worker1.example.com:
[zk: 6] ls /tasks
[task-0000000000]
[zk: 7] ls /workers
[worker1.example.com]
[zk: 8] create /assign/worker1.example.com/task-0000000000 ""
Created /assign/worker1.example.com/task-0000000000
[zk: 9]
worker接着收到一个新任务被分配的通知:
[zk: localhost:2181(CONNECTED) 3]
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged
path:/assign/worker1.example.com
worker然后检查新的任务,看看任务是否被分配给它:
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged
path:/assign/worker1.example.com
[zk: localhost:2181(CONNECTED) 3] ls /assign/worker1.example.com
[task-0000000000]
[zk: localhost:2181(CONNECTED) 4]
一旦worker执行完了任务,它会在\/tasks下增加一个状态节点:
[zk: localhost:2181(CONNECTED) 4] create /tasks/task-0000000000/status "done"
Created /tasks/task-0000000000/status
[zk: localhost:2181(CONNECTED) 5]
然后客户端收到一个通知,检查结果:
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged
path:/tasks/task-0000000000
[zk: localhost:2181(CONNECTED) 2] get /tasks/task-0000000000
"cmd"
cZxid = 0x7c
ctime = Tue Dec 11 10:30:18 CET 2012
mZxid = 0x7c
mtime = Tue Dec 11 10:30:18 CET 2012
pZxid = 0x7e
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 1
[zk: localhost:2181(CONNECTED) 3] get /tasks/task-0000000000/status
"done"
cZxid = 0x7e
ctime = Tue Dec 11 10:42:41 CET 2012
mZxid = 0x7e
mtime = Tue Dec 11 10:42:41 CET 2012
pZxid = 0x7e
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 0
[zk: localhost:2181(CONNECTED) 4]
客户端检查状态节点的内容来判断任务发生了什么。本例中,任务被成功的执行了,结果是“done”。当然,任务可以更加复杂,甚至有另外的分布式系统参与。无论任务实际上是怎么样的,执行的机制和传递结果本质上都是一样的。