使用Kazoo去增删改查zookeeper

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:

每一次新版本开发,都会有开发频繁的要求查看以前版本里zookeeper的内部配置,由于我公司规定zookeeper的密钥是不能轻易给开发人员的,所以每次开发找过来运维就要停下手里工作去帮忙看一下,这样一来二去就搞得运维很烦。于是就萌生一个念头,通过一个工具去查询zookeeper的节点情况,然后再将这个工具嵌入到django里做成web界面,让开发苦逼直接去django里查。


由于django是python语言写的,为了代码统一不至于看疯一个人,所以这个工具也要选择python系,那么就要使用Kazoo,因为它比较专业而且成熟。这里实验使用的python版本是2.7.5。


安装Kazoo的方法很简单,#pip install kazoo。然后启动zookeeper的服务端,安装zookeeper的方法去看:http://blog.51cto.com/chenx1242/1889715 。


进入python后,基本操作如下:

1
2
3
4
5
6
7
8
9
>>> from kazoo.client  import  KazooClient
>>> zk = KazooClient(hosts= 'Zookeeper的地址:2181' )     #如果是本地那就写127.0.0.1
#zk = KazooClient(hosts='Zookeeper 1的地址:2181,Zookeeper 2的地址:2181,Zookeeper 3的地址:2181')    #如果是zookeeper集群就这么写
>>> zk.start()     #与zookeeper连接,如果是zk.start(timeout=15),就规定了超时时间
>>> zk.state 
'CONNECTED'         #已经连接成功,如果是LOST就是连接失败
>>> zk.connected 
True                 #确认已经连接
>>> zk.stop()     #与zookeeper断开


如果出现了“kazoo.handlers.threading.KazooTimeoutError: Connection time-out”这个错误,请检查zookeeper的进程是否已经启动。这里补充一句,zk.start()是以同步的形式连接服务集群。


如果要建立一个叫/abc/JQK/XYZ/0001的node,node里面的value是"this is my house" ,语句如下:

1
2
3
zk.create( '/abc/JQK/XYZ/0001' ,b 'this is my house' ,makepath=True)    
#makepath=True是递归创建,如果不加上中间那一段,就是建立一个空的节点
zk.ensure_path( '/abc/JQK/XYZ/0001' )         #这样写是创建空的node


效果如图:

image.png


如果要删除这个/abc/JQK/XYZ/0001的子node,但是想要上一级XYZ这个node还是存在的,语句如下:

1
2
zk.delete( '/abc/JQK/XYZ/0001' ,recursive=True)    
#recursive=True是递归删除,就是无视下面的节点是否是空,都干掉,不加上的话,会提示子节点非空,删除失败



现在假如要在0001这个node里更改value,比如改成:“this is my horse!”,语句如下:

1
2
>>> zk. set ( '/abc/JQK/XYZ/0001' , "this is my horse!" )
ZnodeStat(czxid=80, mzxid=84, ctime=1513913337850, mtime=1513913601610, version=3, cversion=0, aversion=0, ephemeralOwner=0, dataLength=17, numChildren=0, pzxid=80)


注意!set这种增加节点内容的方式是覆盖式增加,并不是在原有基础上增添。而且添加中文的话可能在ZooInspecter里出现的是乱码,现在我们来到ZooInspecter看一下效果:

image.png


我现在在'/ps/spider/dlb-receiver/'下建立两个node,一个叫0001,另一个叫0002,现在若要查看“/ps/spider/dlb-receiver/“下面有多少个子节点,语句是:

1
2
3
4
5
6
>>> zk.get_children( '/ps/spider/dlb-receiver' )
[u '0001' , u '0002' ]       #可见目前只有两个子节点
 
>>> children = zk.get_children( "/ps/spider/dlb-receiver" )    
>>> print( "There are %s children with names %s"  % (len(children), children)) 
There are 2 children with names [u '0001' , u '0002' ]


假设“/ps/spider/dlb-receiver/0001”它里面的value如图:

 image.png


要查看这个“/ps/spider/dlb-receiver/0001”的value,语句是:

1
2
3
4
>>> zk.get( '/ps/spider/dlb-receiver/0001' )     #获得的type是tuple(元组)
( '-- this is mysql\r\nmysql = {\r\n\thost = "rm-bp116dn17141tx72j.mysql.rds.aliyuncs.com",\r\n\tport = 3306,\r\n\tdatabase = "lcyy123ht",\r\n\tusername = "lcyyoalalht",\r\n\tpassword = "dvlSdJyuw2ad43fg09",\r\n}\r\n\r\n-- this is redis\r\nredis = {\r\n\thost = "127.0.0.1",\r\n\tport = 6379,\r\n}' , ZnodeStat(czxid=47, mzxid=110, ctime=1513863785337, mtime=1513924538981, version=6, cversion=0, aversion=0, ephemeralOwner=0, dataLength=255, numChildren=0, pzxid=47))
>>> print(zk.get( '/ps/spider/dlb-receiver/0001' ))     #前面加上print也是可以的
( '-- this is mysql\r\nmysql = {\r\n\thost = "rm-bp116dn17141tx72j.mysql.rds.aliyuncs.com",\r\n\tport = 3306,\r\n\tdatabase = "lcyy123ht",\r\n\tusername = "lcyyoalalht",\r\n\tpassword = "dvlSdJyuw2ad43fg09",\r\n}\r\n\r\n-- this is redis\r\nredis = {\r\n\thost = "127.0.0.1",\r\n\tport = 6379,\r\n}' , ZnodeStat(czxid=47, mzxid=110, ctime=1513863785337, mtime=1513924538981, version=6, cversion=0, aversion=0, ephemeralOwner=0, dataLength=255, numChildren=0, pzxid=47))


上面这一大坨tuple看起来很头疼,那么就精简一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> print(zk.get( '/ps/spider/dlb-receiver/0001' )[0])     #后面添加一个[0]即可
-- this is mysql
mysql = {
host =  "rm-bp116dn17141tx72j.mysql.rds.aliyuncs.com" ,
port = 3306,
database =  "lcyy123ht" ,
username =  "lcyyoalalht" ,
password =  "dvlSdJyuw2ad43fg09" ,
}
-- this is redis
redis = {
host =  "127.0.0.1" ,
port = 6379,
}
 
>>> print(zk.get( '/ps/spider/dlb-receiver/0001' )[1])     #这里是stat
ZnodeStat(czxid=47, mzxid=118, ctime=1513863785337, mtime=1513926132280, version=8, cversion=2, aversion=0, ephemeralOwner=0, dataLength=261, numChildren=0, pzxid=120)


或者是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> data,stat = zk.get( '/ps/spider/dlb-receiver/0001' )
 
>>> print (data)
-- this is mysql
mysql = {
host =  "rm-bp116dn17141tx72j.mysql.rds.aliyuncs.com" ,
port = 3306,
database =  "lcyy123ht" ,
username =  "lcyyoalalht" ,
password =  "dvlSdJyuw2ad43fg09" ,
}
-- this is redis
redis = {
host =  "127.0.0.1" ,
port = 6379,
}



但是Kazoo也有非常蛋疼的一面,就比如上面的例子,我只想要redis而不想显示mysql的话,kazoo自带的函数是无法做到的,这就必须要自己写python,通过正则表达式来获取了。


参考文章:https://kazoo.readthedocs.io/en/latest/index.html

参考文章:http://izualzhy.cn/c/cpp/2016/10/05/zookeeper-python-kazoo-introduction




 本文转自 苏幕遮618 51CTO博客,原文链接:http://blog.51cto.com/chenx1242/2053627

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
Python
Python:kazoo模块与Zookeeper交互
Python:kazoo模块与Zookeeper交互
92 0
|
Python
Python:kazoo模块与Zookeeper交互
Python:kazoo模块与Zookeeper交互
|
Python
Python:kazoo模块与Zookeeper交互
Python:kazoo模块与Zookeeper交互
141 0
|
11天前
|
监控 负载均衡 Cloud Native
ZooKeeper分布式协调服务详解:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析ZooKeeper分布式协调服务原理,涵盖核心概念如Server、Client、ZNode、ACL、Watcher,以及ZAB协议在一致性、会话管理、Leader选举中的作用。讨论ZooKeeper数据模型、操作、会话管理、集群部署与管理、性能调优和监控。同时,文章探讨了ZooKeeper在分布式锁、队列、服务注册与发现等场景的应用,并在面试方面分析了与其它服务的区别、实战挑战及解决方案。附带Java客户端实现分布式锁的代码示例,助力提升面试表现。
290 2
|
11天前
|
监控 Dubbo 前端开发
快速入门分布式系统与Dubbo+zookeeper Demo
快速入门分布式系统与Dubbo+zookeeper Demo
201 0
|
11天前
|
消息中间件 Java 网络安全
JAVAEE分布式技术之Zookeeper的第一次课
JAVAEE分布式技术之Zookeeper的第一次课
274 0
|
11天前
|
监控 NoSQL Java
Zookeeper分布式锁
Zookeeper分布式锁
289 1
|
11天前
|
监控 Dubbo Java
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
68 0
|
8天前
|
前端开发 JavaScript 算法
分布式系统的一致性级别划分及Zookeeper一致性级别分析
分布式系统的一致性级别划分及Zookeeper一致性级别分析
|
11天前
|
NoSQL 中间件 API
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)(下)
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)
93 2