zookeeper05-使用ZooKeeper

3、开始使用ZooKeeper

3.2、第一个ZooKeeper会话

  • 使用ZooKeeper中bin/目录下的zkServer和zkCi工具进行调试和管理。
  • 使用客户端建立一个会话
]# zkCli.sh    --
...
--客户端启动程序来建立一个会话。
2021-12-22 09:37:37,464 [myid:] - INFO  [main:ZooKeeper@868] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@73a8dfcc
2021-12-22 09:37:37,476 [myid:] - INFO  [main:X509Util@79] - Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation
2021-12-22 09:37:37,492 [myid:] - INFO  [main:ClientCnxnSocket@237] - jute.maxbuffer value is 4194304 Bytes
2021-12-22 09:37:37,505 [myid:] - INFO  [main:ClientCnxn@1653] - zookeeper.request.timeout value is 0. feature enabled=
--客户端尝试连接到localhost/127.0.0.1:2181
2021-12-22 09:37:37,518 [myid:localhost:2181] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1112] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
JLine support is enabled
--客户端连接成功,服务器开始初始化这个新会话。
2021-12-22 09:37:37,675 [myid:localhost:2181] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@959] - Socket connection established, initiating session, client: /127.0.0.1:35332, server: localhost/127.0.0.1:2181
--会话初始化成功完成。会话ID(sessionid)是0x20000103b190002
2021-12-22 09:37:37,710 [myid:localhost:2181] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1394] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x20000103b190002, negotiated timeout = 30000

WATCHER::

----服务器向客户端发送一个SyncConnected事件。
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0] 
  • 简单使用会话
--列出根(root)下的所有znode。此刻出/zookeeper之外,znode树为没有其他znode
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
--创建一个名为/workers的znode
[zk: localhost:2181(CONNECTED) 1] create /workers ""
Created /workers
--查看/workers
[zk: localhost:2181(CONNECTED) 2] ls /
[workers, zookeeper]
[zk: localhost:2181(CONNECTED) 3] ls /workers 
[]
--删除znode
[zk: localhost:2181(CONNECTED) 4] delete /workers 
[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper]
--退出会话
[zk: localhost:2181(CONNECTED) 6] quit

WATCHER::

WatchedEvent state:Closed type:None path:null
2021-12-22 09:56:02,382 [myid:] - INFO  [main:ZooKeeper@1422] - Session: 0x20000103b190002 closed
2021-12-22 09:56:02,390 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@524] - EventThread shut down for session: 0x20000103b190002

4、一个主-从模式例子的实现

  • 本示例仅用于教学目的,我们不建议使用zkCli.sh构建系统。
  • 主-从模型中包括三个角色:
    • Master(主节点):主节点负责监视新的从节点和任务,分配任务给可用的从节点。
    • Worker(从节点):从节点会通过系统注册自己,以确保主节点看到它们可以执行任务,然后开始监视新任务。
    • Client(客户端):客户端创建新任务并等待系统的响应。

4.1、主节点角色

  • 因为只有一个进程会成为master,所以一个进程必须在ZooKeeper中锁定/master才能成为master。为此,进程会创建一个临时的znode,名为/master:
    • 一个临时节点会在会话过期或关闭时自动被删除。
--开启第一个会话(zkCli.sh),将作为主节点会话

--创建名为/master的znode,以便获得管理权。使用-e标志来表示创建的znode为临时性的。  --添加主机信息并不是必需的,这样做仅仅是为了说明我们可以在需要时添加数据。
[zk: localhost:2181(CONNECTED) 0] create -e /master "master1.example.com:2223"
Created /master
--列出ZooKeeper树的根。
[zk: localhost:2181(CONNECTED) 1] ls /
[master, zookeeper]
--获取/master的数据。
[zk: localhost:2181(CONNECTED) 2] get /master
master1.example.com:2223
  • 假如其他进程想成为master,并尝试创建一个/master节点。让我们看看会发生什么:
    • ZooKeeper告诉我们/master已经存在。这样,第二个进程就知道已经有一个master了。
--开启第二个会话(zkCli.sh),将作为从节点会话
[zk: localhost:2181(CONNECTED) 0] create -e /master "master2.example.com:2223"
Node already exists: /master
  • 主节点可能会崩溃,而从节点可能需要接替主节点的角色。为了检测到这一点,从节点需要在/master上设置一个监视点:
    • stat命令可以得到znode节点的属性,并可以在已经存在的znode节点上设置监视点。-w选项表示添加监视点。
--第二个会话(目前是从节点会话)
[zk: localhost:2181(CONNECTED) 1] stat -w /master
cZxid = 0x100000028
ctime = Wed Dec 22 23:06:11 CST 2021
mZxid = 0x100000028
mtime = Wed Dec 22 23:06:11 CST 2021
pZxid = 0x100000028
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x100004099d30008
dataLength = 24
numChildren = 0
  • 在主节点崩溃的情况下,我们观察到以下情况:
    • NodeDeleted事件指出主节点的会话已经关闭或过期。
--关闭第一会话,观察第二个会话
[zk: localhost:2181(CONNECTED) 2] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeDeleted path:/master
  • 主节点已经不存在了,现在从节点可以通过创建/master来成为主节点。 
--第二个会话(将成为主节点会话)
[zk: localhost:2181(CONNECTED) 2] create -e /master "master2.example.com:2223"
Created /master

4.2、从节点,任务和任务分配

  • 在讨论从节点和客户端所采取的步骤之前,先创建三个重要的父znode:/workers、/tasks和/assign。
  • 这三个新的znode是持久的znode,不包含任何数据。在这个例子中,使用这些znode可以告诉我们哪些从节点是可用的,告诉我们什么时候有任务要分配,并向从节点分配任务。
--开启一个会话创建持久znode,创建后关闭该会话
[zk: localhost:2181(CONNECTED) 0] create /workers ""
Created /workers
[zk: localhost:2181(CONNECTED) 1] create /tasks ""
Created /tesks
[zk: localhost:2181(CONNECTED) 2] create /assign ""
Created /assign
  • 在实际的应用程序中,这三个znode需要由主进程在开始分配任务之前创建,或者由某个引导过程创建。无论它们是如何创建的,一旦它们存在,主节点需要监视/workers和/tasks的子znode的变化。
    • ls命令使用-w选项表示在相应znode上设置监视点。
--第二个会话(目前是主节点会话)

--监控/workers的变化
[zk: localhost:2181(CONNECTED) 3] ls -w /workers 
[]
--监控/tesks的变化
[zk: localhost:2181(CONNECTED) 4] ls -w /tasks
[]

4.3、从节点角色 

  • 从节点第一步是通知主节点它可以执行任务了。它通过在/workers下创建一个临时的znode来表示它。从节点使用主机名来标识自己。
--重新开启第一个会话(zkCli.sh),将作为从节点会话
[zk: localhost:2181(CONNECTED) 0] create -e /workers/worker1.example.com "worker1.example.com:2223"
Created /workers/worker1.example.com
  • 之前主节点已经监视了/workers的子节点变化情况。一旦从节点在/workers下创建了一个znode,主节点就会观察到以下通知信息。
--第二个会话(目前是主节点会话)
[zk: localhost:2181(CONNECTED) 5] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/workers
  • 接下来,从节点需要创建一个父znode(/assing/worker1.example.com)来接收分配的任务。并通过ls命令的-w选项来监视这个节点的变化,以便等待新的任务。
--第一个会话(目前是从节点会话)
[zk: localhost:2181(CONNECTED) 1] create /assign/worker1.example.com ""
Created /assign/worker1.example.com
[zk: localhost:2181(CONNECTED) 2] ls -w /assign/worker1.example.com
[]
  • 从节点现在已经准备就绪,可以接收分配的任务了

4.4、客户端角色

  • 客户端向系统添加任务。就本例而言,任务是什么并不重要。这里我们假设客户端要求主从系统运行cmd命令。要向系统中添加任务,客户端需要执行以下操作:
--开启第三个会话(zkCli.sh),将作为客户端会话
[zk: localhost:2181(CONNECTED) 0] create -s /tasks/task- "cmd"
Created /tasks/task-0000000000
  • 我们需要按照任务添加的顺序来添加znode,其本质上是一个队列。客户端现在必须等待任务执行完毕。执行任务的从节点将任务执行完毕后,会在“/tasks/task-”下创建一个子znode来表示任务状态。客户端通过查看这个子znode是否创建来确定任务是否执行完毕,因此客户端需要监视“/tasks/task-”的创建事件。
--第三个会话(目前是客户端会话)
[zk: localhost:2181(CONNECTED) 1] ls -w /tasks/task-0000000000
[]
  • 之前主节点已经监视了/tasks的子znode。一旦客户端在/tasks下创建了一个znode,主节点就会观察到以下通知信息。
--第二个会话(目前是主节点会话)
[zk: localhost:2181(CONNECTED) 5] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks
  • 主节点之后会检查这个新的任务,然后获取可用的从节点列表,并任务分配给可用的从节点。
--第二个会话(目前是主节点会话)
[zk: localhost:2181(CONNECTED) 5] ls /tasks 
[task-0000000000]
[zk: localhost:2181(CONNECTED) 6] ls /workers 
[worker1.example.com]
[zk: localhost:2181(CONNECTED) 7] create /assign/worker1.example.com/task-0000000000 ""
Created /assign/worker1.example.com/task-0000000000
  • 从节点接收到分配任务的通知(之前从节点已经监视了/assign/worker1.example.com):
--第一个会话(目前是从节点会话)
[zk: localhost:2181(CONNECTED) 3] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/assign/worker1.example.com
  • 从节点检查新任务,并确认该任务是否分配给自己:
--第一个会话(目前是从节点会话)
[zk: localhost:2181(CONNECTED) 3] ls /assign/worker1.example.com
[task-0000000000]
  • 一旦从节点完成任务的执行,它就会在“/tasks/task-”中添加一个表示状态的znode:
--第一个会话(目前是从节点会话)
[zk: localhost:2181(CONNECTED) 4] create /tasks/task-0000000000/status "done"
Created /tasks/task-0000000000/status
  • 客户端接收到任务执行完成的通知,并检查执行结果:
--第三个会话(目前是客户端会话)
[zk: localhost:2181(CONNECTED) 2] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks/task-0000000000

[zk: localhost:2181(CONNECTED) 2] get /tasks/task-0000000000
cmd
[zk: localhost:2181(CONNECTED) 3] get /tasks/task-0000000000/status 
done
  • 客户端检查状态znode的内容,并确认任务的执行结果。在本例中,它已经成功执行,结果是“done”。当然任务也可能非常复杂,甚至涉及另一个分布式系统。最终不管是什么样的任务,执行任务和通过Zookeeper传递结果的机制,本质上都是一样的。

4.5、三个会话

4.5.3、第一个会话

--第一个会话(目前是主节点会话)
[zk: localhost:2181(CONNECTED) 0] create -e /master "master1.example.com:2223"
Created /master
[zk: localhost:2181(CONNECTED) 1] ls /
[master, zookeeper]
[zk: localhost:2181(CONNECTED) 2] get /master
master1.example.com:2223

--第一个会话(目前是从节点会话)
[zk: localhost:2181(CONNECTED) 0] create -e /workers/worker1.example.com "worker1.example.com:2223"
Created /workers/worker1.example.com
[zk: localhost:2181(CONNECTED) 1] create /assign/worker1.example.com ""
Created /assign/worker1.example.com
[zk: localhost:2181(CONNECTED) 2] ls -w /assign/worker1.example.com
[]
[zk: localhost:2181(CONNECTED) 3] 
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] create /tasks/task-0000000000/status "done"
Created /tasks/task-0000000000/status

4.5.2、第二个会话

--第二个会话(目前是从节点会话)
[zk: localhost:2181(CONNECTED) 0] create -e /master "master2.example.com:2223"
Node already exists: /master
[zk: localhost:2181(CONNECTED) 1] stat -w /master
cZxid = 0x100000004
ctime = Thu Dec 23 10:51:28 CST 2021
mZxid = 0x100000004
mtime = Thu Dec 23 10:51:28 CST 2021
pZxid = 0x100000004
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x1000011abdf0000
dataLength = 24
numChildren = 0

--第二个会话(目前是主节点会话)
[zk: localhost:2181(CONNECTED) 2] create -e /master "master2.example.com:2223"
Created /master
[zk: localhost:2181(CONNECTED) 3] ls -w /workers 
[]
[zk: localhost:2181(CONNECTED) 4] ls -w /tasks
[]
[zk: localhost:2181(CONNECTED) 5] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/workers

[zk: localhost:2181(CONNECTED) 5] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks

[zk: localhost:2181(CONNECTED) 5] ls /tasks 
[task-0000000000]
[zk: localhost:2181(CONNECTED) 6] ls /workers 
[worker1.example.com]
[zk: localhost:2181(CONNECTED) 7] create /assign/worker1.example.com/task-0000000000 ""
Created /assign/worker1.example.com/task-0000000000

4.5.3、第三个会话

--第三个会话(目前是客户端会话)
[zk: localhost:2181(CONNECTED) 0] create -s /tasks/task- "cmd"
Created /tasks/task-0000000000
[zk: localhost:2181(CONNECTED) 1] ls -w /tasks/task-0000000000
[]
[zk: localhost:2181(CONNECTED) 2] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks/task-0000000000

[zk: localhost:2181(CONNECTED) 2] get /tasks/task-0000000000
cmd
[zk: localhost:2181(CONNECTED) 3] get /tasks/task-0000000000/status 
done

1

3、开始使用ZooKeeper

3.2、第一个ZooKeeper会话

  • 使用ZooKeeper中bin/目录下的zkServer和zkCi工具进行调试和管理。
  • 使用客户端建立一个会话
]# zkCli.sh    --
...
--客户端启动程序来建立一个会话。
2021-12-22 09:37:37,464 [myid:] - INFO  [main:ZooKeeper@868] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@73a8dfcc
2021-12-22 09:37:37,476 [myid:] - INFO  [main:X509Util@79] - Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation
2021-12-22 09:37:37,492 [myid:] - INFO  [main:ClientCnxnSocket@237] - jute.maxbuffer value is 4194304 Bytes
2021-12-22 09:37:37,505 [myid:] - INFO  [main:ClientCnxn@1653] - zookeeper.request.timeout value is 0. feature enabled=
--客户端尝试连接到localhost/127.0.0.1:2181
2021-12-22 09:37:37,518 [myid:localhost:2181] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1112] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
JLine support is enabled
--客户端连接成功,服务器开始初始化这个新会话。
2021-12-22 09:37:37,675 [myid:localhost:2181] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@959] - Socket connection established, initiating session, client: /127.0.0.1:35332, server: localhost/127.0.0.1:2181
--会话初始化成功完成。会话ID(sessionid)是0x20000103b190002
2021-12-22 09:37:37,710 [myid:localhost:2181] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1394] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x20000103b190002, negotiated timeout = 30000

WATCHER::

----服务器向客户端发送一个SyncConnected事件。
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0] 
  • 简单使用会话
--列出根(root)下的所有znode。此刻出/zookeeper之外,znode树为没有其他znode
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
--创建一个名为/workers的znode
[zk: localhost:2181(CONNECTED) 1] create /workers ""
Created /workers
--查看/workers
[zk: localhost:2181(CONNECTED) 2] ls /
[workers, zookeeper]
[zk: localhost:2181(CONNECTED) 3] ls /workers 
[]
--删除znode
[zk: localhost:2181(CONNECTED) 4] delete /workers 
[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper]
--退出会话
[zk: localhost:2181(CONNECTED) 6] quit

WATCHER::

WatchedEvent state:Closed type:None path:null
2021-12-22 09:56:02,382 [myid:] - INFO  [main:ZooKeeper@1422] - Session: 0x20000103b190002 closed
2021-12-22 09:56:02,390 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@524] - EventThread shut down for session: 0x20000103b190002

 

上一篇:Linux基础知识汇总与实践 —— Linux篇


下一篇:Rasa课程、Rasa培训、Rasa面试系列之: Rasa 3.x rasa test等运行命令学习