客户端向系统中增加任务。在本例中,我们不关心任务的实际组成。现在我们假设客户端需要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”。当然,任务可以更加复杂,甚至有另外的分布式系统参与。无论任务实际上是怎么样的,执行的机制和传递结果本质上都是一样的。