使用kazoo连接zookeeper并监听节点数量以及值变化

本文介绍了如何使用kazoo库连接Zookeeper并进行节点监控。通过监控节点数量的变化,可以实现服务发现、主备切换、独占锁和分布式锁等功能。同时,文章讲解了两种类型的Watcher:监听子节点变化和节点数据变化,并提供了一个同时监听子节点和当前节点数据变化的watcher类的封装示例,适用于集中配置管理和消息队列等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  目前kazoo是连接zk的最新第三方库,最新更新时间为2019年1月,其他第三方连接zk的库都长时间未更新,所以推荐使用kazoo。前面有几篇文章都已经详细给出了zk的部署,接下来是zk最核心的地方,将zk的数据结构特性跟业务场景相结合,实现复杂需求,本文给出基本demo用法介绍。

1、监控节点数量的变化

  基本操作,创建、更新、删除,kazoo接口已经足够简单,入参类型如果不懂,可以直接看源码,同时也有助于深入了解别人是如何构思python“中间件”

from kazoo import exceptions
from kazoo.client import KazooClient
from kazoo.client import ChildrenWatch
from kazoo.client import DataWatch

def normal_test(zk_path,host,port,node_list):
    zk=KazooClient(hosts=host+':'+port,timeout=5)
    zk.start(timeout=5)

    if not zk.exists(zk_path):
        print("node:{} does't exists".format(zk_path))
        # 创建当前节点,持久性节点,值需要设为byte类型
        zk.create(path=zk_path,value=b'bar')

    # 这里是获取当前节点的子节点列表,可以设定watch以及是否返回节点数据
    child_node_list=zk.get_children(zk_path,watch=None,include_data=False)
    # 创建多个子节点,值可以设为一样,因为这里关注子节点是否存在,不关心其值
    if not child_node_list:
        for sub_node in node_list:
            zk.create(zk_path + '/' + sub_node,b'1')
    else:
        print('subnode list:{}'.format(child_node_list))

    # 获取当前节点的znode对象:含data和ZnodeStat对象
    data,stat=zk.get(zk_path)
    print('current node data:{}'.format(data))
    print('data version:{}'.format(stat.version))
    print('data length:{}'.format(stat.data_length))
    print('children node numbers:{}'.format(stat.numChildren))

    # 更新节点数据,可以指定值和版本,成功更新则ZnodeStat 对象
    stat_new=zk.set(zk_path,value=b'foo')
    print('node {0} is updated:{1}'.format(zk_path,stat_new))

    # 删除当前节点,若当前节点有子节点,则提示无法删除,需要使用递归删除
    zk.delete(zk_path,recursive=True)
    try:
        last=zk.get_children(zk_path)
        print('children nodes :{}'.format(last))
    except exceptions.NoNodeError
### Zookeeper 节点类型 ZooKeeper 支持多种类型的节点,每种节点具有不同的特性和用途: - **持久节点 (Persistent Node)**:一旦创建就不会自动消失,除非显式删除[^3]。 - **临时节点 (Ephemeral Node)**:仅在其创建会话有效期内存在。当该会话结束时,此节点会被自动移除。这有助于构建诸如领导者选举的服务发现模式[^5]。 - **顺序节点 (Sequential Node)**:无论是持久还是临时节点都可以附加一个按时间戳排序的序列号作为路径的一部分,在创建时自动生成。这对于实现唯一命名或排队非常有用。 - **临时顺序节点 (Ephemeral Sequential Node)**:结合了上述两种属性,既会在会话终止时被清除又带有唯一的序号标签。这种组合特别适用于像分布式锁这样的场景。 ```python from kazoo.client import KazooClient zk = KazooClient(hosts='127.0.0.1:2181') zk.start() # 创建不同类型的节点示例 path_persistent = zk.create("/persistent_node", b"data", makepath=True) path_ephemeral = zk.create("/ephemeral_node", b"data", ephemeral=True, makepath=True) path_sequential = zk.create("/sequential_node-", b"data", sequence=True, makepath=True) print(f"PERSISTENT NODE PATH: {path_persistent}") print(f"EPHEMERAL NODE PATH: {path_ephemeral}") print(f"SEQUENTIAL NODE PATH: {path_sequential}") zk.stop() ``` ### 监听机制 ZooKeeper 提供了一套基于观察者的监听机制——Watcher 来监控节点变化情况。每当指定条件满足时(比如某个节点的内容更新),就会触发相应的回调函数执行预定义的操作[^4]。 具体来说,监听过程涉及以下几个方面: - **注册 Watcher**:客户端可以在读取操作的同时设定希望监视的目标资源,指明感兴趣的变更种类。 - **接收通知**:一旦目标发生了预期之外的状态转换,服务器端即刻向对应的客户发送一次性的异步消息告知变动详情。 - **单次触发特性**:得注意的是每次接收到的通知都是独立的一次性事件,意味着如果想要持续跟踪后续更改则需重新建立新的 watcher 实例[^2]。 ```python def watch_callback(event): print("Event triggered:", event.type, "for path:", event.path) @zk.DataWatch('/some/path') # 假设已经启动了一个连接zookeeper 的 client 'zk' def watch_data(data, stat, event=None): if data is None: print('Data deleted!') elif not hasattr(watch_data, 'previous'): print('Initial Data:', repr(data)) setattr(watch_data, 'previous', True) else: print('Updated Data:', repr(data)) # 设置子节点变化监听 children = zk.get_children('/another_path', watch=watch_callback) ``` ### 使用场景 利用 ZooKeeper 及其核心组件可以解决许多复杂的分布式计算难题,以下是几个典型的应用实例: - **配置管理**:集中存储应用程序全局参数通过监听机制确保所有成员同步最新的设置版本[^1]。 - **集群协调与领导选举**:借助短暂存活期的节点配合有序编号支持多进程间公平竞争成为群组首领的角色分配方案。 - **服务发现**:提供统一入口让新加入网络环境下的参与者快速定位可用的服务接口地址列表。 - **分布式队列/屏障控制结构**:依靠先后顺序排列好的实体完成任务分发或者同步障碍解除等功能需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值