Kazoo入门

文章目录

  • 1. 简介
  • 2. 安装
    • 2.1 JRE
    • 2.2 ZooKeeper
    • 2.3 ZooInspector
    • 2.4 Kazoo
  • 3. 建立连接
  • 4. 增删改查
    • 4.1 创建节点
    • 4.2 读
    • 4.3 更新
    • 4.4 删除节点
  • 5. 会话状态
  • 6. 监听器
    • 6.1 状态监听
    • 6.2 监听只读连接
  • 参考文献

1. 简介

Kazoo是一个Python库,旨在轻松简单地使用Zookeeper。

ZooKeeper是一款分布式协调服务中间件,是Apache Hadoop的一个子项目,用于构建健壮的分布式系统,提供一组API实现通用的协作任务,包括选举主节点、管理组内成员关系、管理元数据等。

ZooKeeper关注协同数据(元数据)。比如,网络邮箱用户对自己邮箱内容感兴趣,对哪台服务器处理请求不关心。那么邮箱内容就是应用数据,邮箱到某一台服务器之间的映射关系就是协同数据(原数据)。

ZooKeeper不适合作海量数据存储。

2. 安装

2.1 JRE

运行ZooKeeper的机器需要安装JRE

2.2 ZooKeeper

ZooKeeper官方下载

建议下载ZooKeeper 3.4.14

  1. 解压后,新建文件夹datalog
  2. 复制粘贴conf文件夹下的zoo_sample.cfg,重命名为zoo.cfg
  3. 打开zoo.cfg,修改dataDir=C:\\zookeeper-3.4.14\\data,添加dataLogDir=C:\\zookeeper-3.4.14\\log
  4. Windows运行bin目录下的zkServer.cmd启动服务

Kazoo入门_第1张图片
类似这样就启动成功了

cmd下输入jps命令可以查看Java进程的PID

2.3 ZooInspector

ZooInspector为ZooKeeper的可视化工具,选装

下载地址

解压后运行build文件夹中的zookeeper-dev-ZooInspector.jar

Kazoo入门_第2张图片

2.4 Kazoo

pip install kazoo

3. 建立连接

运行ZooKeeper启动服务

使用kazoo需要实例化一个KazooClient对象并建立连接

from kazoo.client import KazooClient

zk = KazooClient(hosts='127.0.0.1:2181') # 默认连接本地zookeeper服务,端口号为2181
zk.start()

KazooClient默认连接本地zookeeper服务,端口为2181

当ZooKeeper服务异常时,zk.start()会不断重连直到超时。

连接一旦建立,若发生间歇性连接丢失或ZooKeeper会话过期,KazooClient会不断重连。

中断连接使用stop命令

zk.stop()

只读连接

from kazoo.client import KazooClient

zk = KazooClient(hosts='127.0.0.1:2181', read_only=True)
zk.start()

4. 增删改查

4.1 创建节点

ensure_path():递归创建节点路径,只能设置权限,不能添加数据。
create():创建节点,可添加数据和监听事件。需要父节点存在,不能递归创建。

from kazoo.client import KazooClient

zk = KazooClient()
zk.start()

zk.ensure_path("/my/favorite")  # 确保路径存在
zk.create("/my/favorite/node", b"Hello World!")  # 创建带数据的节点node

运行ZooInspector可看到已添加进一个新节点

Kazoo入门_第3张图片

!!!注意写上那个b!!!

4.2 读

exists():检查节点是否存在,存在则返回节点的ZnodeStat,不存在则返回None
get():获取节点数据和详细节点状态(ZnodeStat)
get_children():获取节点的所有子节点

from kazoo.client import KazooClient

zk = KazooClient()
zk.start()

if zk.exists("/my/favorite"):  # 检查节点是否存在
    data, stat = zk.get("/my/favorite/node")
    print("Version: %s, data: %s" % (stat.version, data.decode("utf-8")))  # 输出节点版本和数据

    children = zk.get_children("/my/favorite")
    print("There are %s children with names %s" % (len(children), children))  # 列出子节点
Version: 0, data: Hello World!
There are 1 children with names ['node']

4.3 更新

set():更新指定节点的数据

from kazoo.client import KazooClient

zk = KazooClient()
zk.start()

zk.set("/my/favorite", b"some data")

data, stat = zk.get("/my/favorite/")
print("Version: %s, data: %s" % (stat.version, data.decode("utf-8")))
Version: 1, data: some data

Kazoo入门_第4张图片

4.4 删除节点

delete():删除指定节点

可选择递归删除节点及其子节点,默认不递归

from kazoo.client import KazooClient

zk = KazooClient()
zk.start()

zk.delete("/my/favorite", recursive=True)  # 递归删除

if zk.exists("/my/favorite/node") == None:
    print('不存在node节点')
if zk.exists("/my/favorite") == None:
    print('不存在favorite节点')
if zk.exists("/my") != None:
    print('存在my节点')
不存在node节点
不存在favorite节点
存在my节点

5. 会话状态

Kazoo会话状态有三种:CONNECTEDSUSPENDEDLOST

  • CONNECTED:连接
  • SUSPENDED:暂停
  • LOST:丢失

刚创建KazooClient实例时,状态为LOST
一旦连接成功,状态切换为CONNECTED
发生网络闪断、服务异常等导致客户端与服务端出现断开,状态切换为SUSPENDED,此时KazooClient会不断尝试重连

有效状态转换

  • LOST→CONNECTED
    新连接,或之前丢失的重连
  • CONNECTED→SUSPENDED
    连接出现断开
  • CONNECTED→LOST
    只发生在建立连接后,提供的身份凭证无效的情况下
  • SUSPENDED→LOST
    重连会话过期
  • SUSPENDED→CONNECTED
    重连成功

6. 监听器

Kazoo可以在节点上设置监听器,在节点或子节点变化时触发。

Kazoo有两种方式设置监听器,第一种是Zookeeper默认支持的一次性监听事件,当节点被改或子节点被删时触发

from kazoo.client import KazooClient

zk = KazooClient()
zk.start()

zk.ensure_path("/my/favorite")  # 确保路径存在
zk.create("/my/favorite/node", b"Hello World!")  # 子节点node


def watch_data(event):
    print(event)


node = zk.get("/my/favorite", watch=watch_data)  # 当节点被改时,调用watch_data
children = zk.get_children("/my/favorite/", watch=watch_data)  # 当子节点被删,调用watch_data
zk.set("/my/favorite", b"some data")  # 修改节点触发
print(1)
zk.set("/my/favorite/node", b"Hi!")  # 修改子节点不触发
print(2)
zk.delete("/my/favorite/node")  # 删除子节点触发
print(3)
zk.delete("/my/favorite")  # 删除节点不触发
print(4)
WatchedEvent(type='CHANGED', state='CONNECTED', path='/my/favorite')
1
2
WatchedEvent(type='CHILD', state='CONNECTED', path='/my/favorite')
3
4

★第二种设置监听器的方式是利用Python修饰器,监听数据和子节点的修改

  • ChildrenWatch:子节点变化时触发
  • DataWatch:节点数据变化时触发
from kazoo.client import KazooClient

zk = KazooClient()
zk.start()

zk.ensure_path("/my/favorite")  # 确保路径存在


@zk.ChildrenWatch("/my/favorite")
def watch_children(children):
    """监听子节点"""
    print("Children are now: %s" % children)


@zk.DataWatch("/my/favorite")
def watch_node(data, stat, event=None):
    """监听节点数据"""
    if event==None:
        print("Version: %s, data: %s" % (stat.version, data.decode("utf-8")))
    else:
        print(event)

print(0)
zk.create("/my/favorite/node")  # 创建子节点,触发ChildrenWatch和DataWatch
print(1)
zk.set("/my/favorite/node", b"Hello World!")  # 修改子节点,触发ChildrenWatch
print(2)
zk.delete("/my/favorite/node")  # 删除子节点,触发ChildrenWatch
print(3)
zk.set("/my/favorite", b"some data")  # 修改节点,触发DataWatch
print(4)
zk.delete("/my/favorite")  # 删除节点,触发DataWatch
print(5)
Children are now: []
Version: 0, data: 
0
1
Children are now: ['node']
2
3
Children are now: []
4
WatchedEvent(type='CHANGED', state='CONNECTED', path='/my/favorite')
5
WatchedEvent(type='DELETED', state='CONNECTED', path='/my/favorite')

6.1 状态监听

from kazoo.client import KazooState

def my_listener(state):
    if state == KazooState.LOST:
        # 会话丢失
        print("LOST")
    elif state == KazooState.SUSPENDED:
        # 会话断开
        print("SUSPENDED")
    else:
        # 会话连接
        print("CONNECTED")

zk.add_listener(my_listener)

使用kazoo.recipe.lock.Lock和创建临时节点时,建议添加状态监听来处理连接中断和会话丢失

6.2 监听只读连接

from kazoo.client import KazooState
from kazoo.client import KeeperState

@zk.add_listener
def watch_for_ro(state):
    if state == KazooState.CONNECTED:
        if zk.client_state == KeeperState.CONNECTED_RO:
            print("Read only mode!")
        else:
            print("Read/Write mode!")





参考文献

  1. ZooKeeper:分布式过程协同技术详解(强烈建议读一读,对理解和使用大有裨益)
  2. ZooKeeper的安装与部署
  3. kazoo使用教程
  4. kazoo文档
  5. Zookeeper接口kazoo实例解析

你可能感兴趣的:(Python)