本文已参与「新人创作礼」活动,一起开启掘金创作之路。
引言
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务。
具体的安装可以参考我另一篇文章
这里讲解一下zookeeper的python相关操作
1·python操作ZK——kazoo包
python操作zk需要kazoo
pip install kazoo
下面是python的操作方法函数,挑一些最常用的详细解释
| 方法 | 说明 |
| start | 连接zookeeper |
| create | 创建节点 |
| get | 获取节点的值 |
| get_children | 获取子节点列表 |
| get_acls | 获取节点ACL列表 |
| add_auth | 向服务器发送凭证 |
| ensure_path | 递归创建路径 |
| set | 设置节点的值 |
| set_acls | 设置节点ACL |
| delete | 删除节点 |
| set_hosts | 设置客户端主机列表 |
| sync | 同步数据 |
| exists | 检查节点是否存在 |
| reconfig | 重置集群配置 |
| command | 向服务器发送四字命令 |
| add_listener | 添加监听方法 |
| remove_listener | 删除监听方法 |
| stop | 停止zookeeper会话 |
| restart | 重启zookeeper会话 |
| close | 释放客户端持有的资源 |
| server_version | 获取连接的zookeeper版本 |
| unchroot | 去除路径中的根目录 |
| transaction | 创建事务对象 |
1.1·初始化zk连接客户端——KazooClient
class KazooClient(object):
def __init__(self, hosts='127.0.0.1:2181',
timeout=10.0, client_id=None, handler=None,
default_acl=None, auth_data=None, sasl_options=None,
read_only=None, randomize_hosts=True, connection_retry=None,
command_retry=None, logger=None, keyfile=None,
keyfile_password=None, certfile=None, ca=None,
use_ssl=False, verify_certs=True, **kwargs):
参数说明:
| hosts | 逗号分隔的要连接的主机列表,默认为本机。 |
| timeout | 连接zookeeper的超时时间,单位为秒,默认为10。 |
| client_id | zookeeper客户端id,用于重新建立以前的会话连接,默认为None。 |
| handler | 实现回调处理接口IHandler的类实例,默认为None。 |
| default_acl | 用于创建节点的默认ACL,默认为None。 |
| auth_data | 用于连接的身份验证凭据列表,参数值为add_auth方法接受的scheme, credential元组列表。默认为None。 |
| read_only | Kazoo 0.6新增参数,需要zookeeper版本为3.4+。允许连接只读服务器,默认为None。 |
| randomize_hosts | Kazoo 0.6新增参数,随机选择主机,默认为True。 |
| connection_retry | Kazoo 1.2新增参数,用于与zookeeper重连的KazooRetry对象,也可以是用于创建KazooRetry对象的选项字典,默认为None。 |
| command_retry | Kazoo 1.2新增参数,用于执行retry方法的KazooRetry对象,也可以是用于创建KazooRetry对象的选项字典,默认为None。 |
| logger | Kazoo 1.2新增参数,用于代替模块全局日志实例的自定义日志记录程序,默认为None。 |
| keyfile | 用于身份验证的SSL密钥文件,默认为None。 |
| keyfile_password | SSL密钥文件密码,默认为None。 |
| certfile | 用于身份验证的SSL证书文件,默认为None。 |
| ca | 用于身份验证的SSL CA文件,默认为None。 |
| use_ssl | 是否使用SSL,默认为False。 |
| verify_certs | 当使用SSL时,参数绕过certs验证,默认为True。 |
1.2·连接zk——start()
start(self, timeout=15)
连接zookeeper。timeout为等待连接成功的时间,单位为秒。如果在指定的时间内没有成功连接,则产生timeout_exception异常。
1.3·创建节点——create()
create(self, path, value=b"", acl=None, ephemeral=False,sequence=False, makepath=False, include_data=False)
参数说明:
| path | 创建的节点路径 |
| value | 节点值,必须是byte |
| acl | ACL列表 |
| ephemeral | 表示节点是否为临时节点 |
| sequence | 表示节点为顺序节点 |
| include_data | 表示是否返回节点的ZnodeStat信息 |
| makepath | 表示当路径不存在时是否创建路径,如果为true,创建的节点路径中间不存在的节点一并创建空值的节点,如果为false,如果路径中间有节点不存在,则报错 |
1.4·获取路径的子节点列表——get_children()
get_children(self, path, watch=None, include_data=False)
参数说明:
| path | 节点路径 |
| watch | 监听回调函数,如果设置watch,则在删除节点或者在该节点下创建/删除子节点操作成功时触发。 |
| include_data | 表示是否返回节点的ZnodeStat信息 |
1.5·获取节点的值——get()
get(self, path, watch=None)
参数说明:
| path | 节点路径 |
| watch | 监听回调函数,如果设置watch,则在删除节点或者在该节点下创建/删除子节点操作成功时触发。 |
1.6·修改节点的值——set()
set(self, path, value, version=-1)
参数说明:
| path | 节点路径 |
| value | 新的节点值 |
| version | 期望的要更新的节点版本,如果为-1则表示匹配任何版本 |
1.7·判断节点是否存在——exists()
exists(self, path, watch=None)
参数说明:
| path | 节点路径 |
| watch | 监听回调函数,如果设置watch,则在删除节点或者在该节点下创建/删除子节点操作成功时触发。 |
1.8·删除节点——delete()
delete(self, path, version=-1, recursive=False)
参数说明:
| path | 节点路径 |
| recursive | 表示是否递归的删除指定节点及其子节点,默认为False |
| version | 期望的要删除的节点版本,如果为-1则表示匹配任何版本 |
1.9·关闭连接——stop()
stop()
停止zookeeper会话。在尝试重新连接时,调用此方法重连将中止。当连接关闭时,会话失效,zookeeper上与会话关联的临时节点会被删除,会触发这些节点以及它们的父节点的监听事件。
2·案例代码
2.1·简单操作增删改查
from kazoo.client import KazooClient
zk = KazooClient(hosts='192.168.30.135:2181')
zk.start() #与zookeeper连接
# 获取对应节点下的子节点
node = zk.get_children('/')
print("------输出1,查看根目录下的子节点:")
print(node)
# 创建节点,makepath=True是递归创建,如果不加上中间那一段,就是建立一个空的节点
zk.create('/zkFirst/zk2020/11/08/1',b'python make 1',makepath=True)
node = zk.get_children('/zkFirst/zk2020/11/08')
print("------输出2,查看/zkFirst/zk2020/11/08目录的子节点:")
print(node)
# 获取节点的值
node_v = zk.get('/zkFirst/zk2020/11/08/1')
print("------输出3,查看/zkFirst/zk2020/11/08/1的值:")
print(node_v)
# 修改节点的值
zk.set('/zkFirst/zk2020/11/08/1',b"python make 1 change")
node_v = zk.get('/zkFirst/zk2020/11/08/1')
print("------输出4,查看/zkFirst/zk2020/11/08/1修改后的值:")
print(node_v)
# 删除节点,recursive=True是递归删除,就是无视要删除的节点下面的节点是否是空,都干掉,不加上的话,会提示子节点非空,删除失败
zk.delete('/zkFirst/zk2020/11/08/1',recursive=True)
node = zk.get_children('/zkFirst/zk2020/11/08')
print("------输出5,查看删除之后/zkFirst/zk2020/11/08目录的子节点:")
print(node)
zk.stop() #与zookeeper断开
脚本输出结果:
------输出1,查看根目录的子节点:
['zookeeper', 'zkFirst']
------输出2,查看/zkFirst/zk2020/11/08目录的子节点:
['1']
------输出3,查看/zkFirst/zk2020/11/08/1的值:
(b'python make 1', ZnodeStat(czxid=25769803839, mzxid=25769803839, ctime=1604827574007, mtime=1604827574007, version=0, cversion=0, aversion=0, ephemeralOwner=0, dataLength=13, numChildren=0, pzxid=25769803839))
------输出4,查看/zkFirst/zk2020/11/08/1修改后的值:
(b'python make 1 change', ZnodeStat(czxid=25769803839, mzxid=25769803840, ctime=1604827574007, mtime=1604827574014, version=1, cversion=0, aversion=0, ephemeralOwner=0, dataLength=20, numChildren=0, pzxid=25769803839))
------输出5,查看删除之后/zkFirst/zk2020/11/08目录的子节点:
[]
2.2·监听节点-watch
监听是很有用的,例如可以作为配置修改的时候,服务立刻就可以知道,并获取最新配置等等
脚本1-持续监听一个节点
from kazoo.client import KazooClient
zk = KazooClient(hosts='192.168.30.135:2181')
zk.start() #与zookeeper连接
def test(event):
print('触发监听事件')
while True:
zk.get('/zkFirst/zk2020/11/08/1', watch=test)
脚本2-修改脚本1监听的节点
from kazoo.client import KazooClient
zk = KazooClient(hosts='192.168.30.135:2181')
zk.start()
zk.set('/zkFirst/zk2020/11/08/1',b"python make 1 change2")
zk.stop()
输出结果:执行一次脚本2,脚本一就会触发一次test函数输出内容(任何渠道修改了这个节点,都会触发)
E:\0------files\2-python\env\3.6.5\python.exe E:/1------project/test/20201108-zookeeper2.py
触发监听事件
触发监听事件