天天看點

使用Kazoo去增删改查zookeeper

每一次新版本開發,都會有開發頻繁的要求檢視以前版本裡zookeeper的内部配置,由于我公司規定zookeeper的密鑰是不能輕易給開發人員的,是以每次開發找過來運維就要停下手裡工作去幫忙看一下,這樣一來二去就搞得運維很煩。于是就萌生一個念頭,通過一個工具去查詢zookeeper的節點情況,然後再将這個工具嵌入到django裡做成web界面,讓開發苦逼直接去django裡查。

由于django是python語言寫的,為了代碼統一不至于看瘋一個人,是以這個工具也要選擇python系,那麼就要使用Kazoo,因為它比較專業而且成熟。這裡實驗使用的python版本是2.7.5。

進入python後,基本操作如下:

1

2

3

4

5

6

7

8

9

<code>&gt;&gt;&gt; from kazoo.client </code><code>import</code> <code>KazooClient</code>

<code>&gt;&gt;&gt; zk = KazooClient(hosts=</code><code>'Zookeeper的位址:2181'</code><code>)    </code><code>#如果是本地那就寫127.0.0.1</code>

<code>#zk = KazooClient(hosts='Zookeeper 1的位址:2181,Zookeeper 2的位址:2181,Zookeeper 3的位址:2181')    #如果是zookeeper叢集就這麼寫</code>

<code>&gt;&gt;&gt; zk.start()    </code><code>#與zookeeper連接配接,如果是zk.start(timeout=15),就規定了逾時時間</code>

<code>&gt;&gt;&gt; zk.state </code>

<code>'CONNECTED'</code>        <code>#已經連接配接成功,如果是LOST就是連接配接失敗</code>

<code>&gt;&gt;&gt; zk.connected </code>

<code>True                </code><code>#确認已經連接配接</code>

<code>&gt;&gt;&gt; zk.stop()    </code><code>#與zookeeper斷開</code>

如果出現了“kazoo.handlers.threading.KazooTimeoutError: Connection time-out”這個錯誤,請檢查zookeeper的程序是否已經啟動。這裡補充一句,zk.start()是以同步的形式連接配接服務叢集。

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

<code>zk.create(</code><code>'/abc/JQK/XYZ/0001'</code><code>,b</code><code>'this is my house'</code><code>,makepath=True)    </code>

<code>#makepath=True是遞歸建立,如果不加上中間那一段,就是建立一個空的節點</code>

<code>zk.ensure_path(</code><code>'/abc/JQK/XYZ/0001'</code><code>)        </code><code>#這樣寫是建立空的node</code>

效果如圖:

如果要删除這個/abc/JQK/XYZ/0001的子node,但是想要上一級XYZ這個node還是存在的,語句如下:

<code>zk.delete(</code><code>'/abc/JQK/XYZ/0001'</code><code>,recursive=True)    </code>

<code>#recursive=True是遞歸删除,就是無視下面的節點是否是空,都幹掉,不加上的話,會提示子節點非空,删除失敗</code>

現在假如要在0001這個node裡更改value,比如改成:“this is my horse!”,語句如下:

<code>&gt;&gt;&gt; zk.</code><code>set</code><code>(</code><code>'/abc/JQK/XYZ/0001'</code><code>,</code><code>"this is my horse!"</code><code>)</code>

<code>ZnodeStat(czxid=80, mzxid=84, ctime=1513913337850, mtime=1513913601610, version=3, cversion=0, aversion=0, ephemeralOwner=0, dataLength=17, numChildren=0, pzxid=80)</code>

注意!set這種增加節點内容的方式是覆寫式增加,并不是在原有基礎上增添。而且添加中文的話可能在ZooInspecter裡出現的是亂碼,現在我們來到ZooInspecter看一下效果:

我現在在'/ps/spider/dlb-receiver/'下建立兩個node,一個叫0001,另一個叫0002,現在若要檢視“/ps/spider/dlb-receiver/“下面有多少個子節點,語句是:

<code>&gt;&gt;&gt; zk.get_children(</code><code>'/ps/spider/dlb-receiver'</code><code>)</code>

<code>[u</code><code>'0001'</code><code>, u</code><code>'0002'</code><code>]      </code><code>#可見目前隻有兩個子節點</code>

<code>&gt;&gt;&gt; children = zk.get_children(</code><code>"/ps/spider/dlb-receiver"</code><code>)    </code>

<code>&gt;&gt;&gt; print(</code><code>"There are %s children with names %s"</code> <code>% (len(children), children)) </code>

<code>There are 2 children with names [u</code><code>'0001'</code><code>, u</code><code>'0002'</code><code>]</code>

假設“/ps/spider/dlb-receiver/0001”它裡面的value如圖:

要檢視這個“/ps/spider/dlb-receiver/0001”的value,語句是:

<code>&gt;&gt;&gt; zk.get(</code><code>'/ps/spider/dlb-receiver/0001'</code><code>)    </code><code>#獲得的type是tuple(元組)</code>

<code>(</code><code>'-- 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}'</code><code>, ZnodeStat(czxid=47, mzxid=110, ctime=1513863785337, mtime=1513924538981, version=6, cversion=0, aversion=0, ephemeralOwner=0, dataLength=255, numChildren=0, pzxid=47))</code>

<code>&gt;&gt;&gt; print(zk.get(</code><code>'/ps/spider/dlb-receiver/0001'</code><code>))    </code><code>#前面加上print也是可以的</code>

上面這一大坨tuple看起來很頭疼,那麼就精簡一下:

10

11

12

13

14

15

16

17

<code>&gt;&gt;&gt; print(zk.get(</code><code>'/ps/spider/dlb-receiver/0001'</code><code>)[0])    </code><code>#後面添加一個[0]即可</code>

<code>-- this is mysql</code>

<code>mysql = {</code>

<code>host = </code><code>"rm-bp116dn17141tx72j.mysql.rds.aliyuncs.com"</code><code>,</code>

<code>port = 3306,</code>

<code>database = </code><code>"lcyy123ht"</code><code>,</code>

<code>username = </code><code>"lcyyoalalht"</code><code>,</code>

<code>password = </code><code>"dvlSdJyuw2ad43fg09"</code><code>,</code>

<code>}</code>

<code>-- this is redis</code>

<code>redis = {</code>

<code>host = </code><code>"127.0.0.1"</code><code>,</code>

<code>port = 6379,</code>

<code>&gt;&gt;&gt; print(zk.get(</code><code>'/ps/spider/dlb-receiver/0001'</code><code>)[1])    </code><code>#這裡是stat</code>

<code>ZnodeStat(czxid=47, mzxid=118, ctime=1513863785337, mtime=1513926132280, version=8, cversion=2, aversion=0, ephemeralOwner=0, dataLength=261, numChildren=0, pzxid=120)</code>

或者是

<code>&gt;&gt;&gt; data,stat = zk.get(</code><code>'/ps/spider/dlb-receiver/0001'</code><code>)</code>

<code>&gt;&gt;&gt; print (data)</code>

但是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