1. 程式人生 > >答應我,不會這些概念,簡歷不要寫 “熟悉” zookeeper

答應我,不會這些概念,簡歷不要寫 “熟悉” zookeeper

> 整理了一些Java方面的架構、面試資料(微服務、叢集、分散式、中介軟體等),有需要的小夥伴可以關注公眾號【程式設計師內點事】,無套路自行領取 - [一口氣說出 9種 分散式ID生成方式,面試官有點懵了](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483785&idx=1&sn=8b828a8ae1701b810fe3969be536cb14&chksm=9b859174acf21862f0b95e0502a1a441c496a5488f5466b2e147d7bb9de072bde37c4db25d7a&token=745402269&lang=zh_CN#rd) - [面試總被問分庫分表怎麼辦?你可以這樣懟他](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483882&idx=1&sn=9e0901dd19e3e06a135fe96780c43477&chksm=9b859117acf218017d9273d4328258c01f6a105180ae8534dc0aaa362cc0c3020dd55de3a95e&token=361009039&lang=zh_CN#rd) - [一口氣說出 6種 @Transactional 註解失效場景](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483977&idx=1&sn=7d8d3c89bfe2261f6422572dca405990&chksm=9b8592b4acf21ba2a8368bb0cf7fff4d3832ce87da33674372a852034186e2966f27fafde66f&token=1082808293&lang=zh_CN#rd) - [基於 Java 實現的人臉識別功能(附原始碼) ](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483925&idx=1&sn=c83bf51f3c67ce7ea65c3ac7b200a852&chksm=9b8592e8acf21bfe26ab0852aa1028f87fbde355ca3e43186a0be08f223bb25e8e00e91d6ee0&token=285522223&lang=zh_CN#rd) - [9種分散式ID生成之美團(Leaf)實戰](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483889&idx=1&sn=35b0eb32de3e63c013585ef1db5d3076&chksm=9b85910cacf2181a23bdc1344a1984e3fa7613cc8dd9e28f3b10196fc73b9022d735f4031e88&token=662935248&lang=zh_CN#rd) #### 嘮嘮叨叨 本文主要分享一下`zookeeper`的一些基本概念,在正式進入正題前,和大家聊一聊剛入行時我的面試經驗,可以說是耿直的有些可愛。 **面試官**:用過`zookeeper` 嗎? **我**:用過啊,給`dubbo`提供服務的註冊與發現嘛 **面試官**:知道 `zookeeper` 是什麼嗎? **我**:知道啊,註冊中心嘛 **面試官**:那你們專案中都是怎麼用 `zookeeper` 的? **我**:就在 `springboot` 的 `application.properties` 配置檔案裡新增一個 `zookeeper` 服務地址就行了。。。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200330171333682.gif#pic_center) . 上邊的對話好像也沒什麼毛病,但似乎又感覺哪裡有點不太對,結果就是每次我如此回答面試都被pass。 為什麼會被問zookeeper?因為我的簡歷專案上寫著熟練使用zookeeper,可面試官理解的 “熟練” 使用可不是會配置,工程啟動不報錯那麼簡單。所以還是有必要全面瞭解一下zookeeper的相關知識。 --- #### 一、zookeeper初識? `Zookeeper` 它作為`Hadoop`專案中的一個開源子專案,是一個經典的分散式資料一致性解決方案,致力於為分散式應用提供一個高效能、高可用,且具有嚴格順序訪問控制能力的分散式協調服務。 ##### 1、zookeeper資料模型 `zookeeper` 維護了一個類似檔案系統的資料結構,每個子目錄(/微信、/微信/公眾號)都被稱作為 `znode` 即節點。和檔案系統一樣,我們可以很輕鬆的對 `znode` 節點進行增加、刪除等操作,而且還可以在一個`znode`下增加、刪除`子znode`,區別在於檔案系統的是,`znode`可以儲存資料(嚴格說是必須存放資料,預設是個空字元)。 由於`zookeeper`是目錄節點結構,在獲取和建立節點時,必須要以`“/”` 開頭,否則在獲取節點時會報錯 `Path must start with / character`。 ```javascript [zk: localhost:2181(CONNECTED) 13] get test Command failed: java.lang.IllegalArgumentException: Path must start with / character ``` 根節點名必須為`“/XXX”`,建立子節點時必須要帶上根節點目錄`“/XXX/CCC”`、`“/XXX/AAA”`。 例如:想要獲取下圖 `程式設計師內點事` 節點必須拼接完整的路徑 `get /微信/公眾號/程式設計師內點事` ```javascript get /微信/公眾號/程式設計師內點事 ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200330163601701.png?#pic_center) `znode`被用來儲存 `byte級` 或 `kb級` 的資料,可儲存的最大資料量是`1MB`(**請注意**:一個節點的資料量不僅包含它自身儲存資料,它的所有子節點的名字也要折算成Byte數計入,因此`znode`的子節點數也不是無限的)雖然可以手動的修改節點儲存量大小,但一般情況下並不推薦這樣做。 --- ##### 2、znode節點屬性 一個`znode`節點不僅可以儲存資料,還有一些其他特別的屬性。接下來我們建立一個`/test`節點分析一下它各個屬性的含義。 ```javascript [zk: localhost:2181(CONNECTED) 6] get /test 456 cZxid = 0x59ac // ctime = Mon Mar 30 15:20:08 CST 2020 mZxid = 0x59ad mtime = Mon Mar 30 15:22:25 CST 2020 pZxid = 0x59ac cversion = 0 dataVersion = 2 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 3 numChildren = 0 ``` 節點屬性 | 註解 -------- | ----- cZxid | 該資料節點被建立時的事務Id mZxid | 該資料節點被修改時最新的事物Id pZxid | 當前節點的父級節點事務Id ctime | 該資料節點建立時間 mtime | 該資料節點最後修改時間 dataVersion | 當前節點版本號(每修改一次值+1遞增) cversion | 子節點版本號(子節點修改次數,每修改一次值+1遞增) aclVersion | 當前節點acl版本號(節點被修改acl許可權,每修改一次值+1遞增) ephemeralOwner | 臨時節點標示,當前節點如果是臨時節點,則儲存的建立者的會話id(sessionId),如果不是,那麼值=0 dataLength | 當前節點所儲存的資料長度 numChildren | 當前節點下子節點的個數 我們看到一個`znode`節點的屬性比較多,但比較主要的屬性還是`zxid`、`version`、`acl` 這三個。 --- **Zxid:** `znode`節點狀態改變會導致該節點收到一個`zxid`格式的時間戳,這個時間戳是全域性有序的,znode節點的建立或者更新都會產生一個新的。如果`zxid1`的值 < `zxid2`的值,那麼說明`zxid2`發生的改變在`zxid1`之後。每個znode節點都有3個`zxid`屬性,`cZxid`(節點建立時間)、`mZxid`(該節點修改時間,與子節點無關)、`pZxid`(該節點或者該節點的子節點的最後一次建立或者修改時間,孫子節點無關)。 `zxid`屬性主要應用於`zookeeper`的叢集,這個後邊介紹叢集時詳細說。 **Version:** `znode`屬性中一共有三個版本號`dataversion`(資料版本號)、`cversion`(子節點版本號)、`aclversion`(節點所擁有的ACL許可權版本號)。 `znode`中的資料可以有多個版本,如果某一個節點下存有多個數據版本,那麼查詢這個節點資料就需要帶上版本號。每當我們對`znode`節點資料修改後,該節點的`dataversion`版本號會遞增。當客戶端請求該`znode`節點時,會同時返回節點資料和版本號。另外當`dataversion`為 `-1`的時候可以忽略版本進行操作。對一個節點設定許可權時`aclVersion`版本號會遞增,下邊會詳細說ACL許可權控制。 驗證一下,我們修改`/test`節點的資料看看`dataVersion `有什麼變化,發現`dataVersion `屬性變成了 3,版本號遞增了。 ```javascript [zk: localhost:2181(CONNECTED) 10] set /test 8888 cZxid = 0x59ac ctime = Mon Mar 30 15:20:08 CST 2020 mZxid = 0x59b6 mtime = Mon Mar 30 16:58:08 CST 2020 pZxid = 0x59ac cversion = 0 dataVersion = 3 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 4 numChildren = 0 ``` ##### 3、znode的型別 `zookeeper` 有四種類型的`znode`,在用客戶端 `client` 建立節點的時候需要指定型別。 ```javascript zookeeper.create("/公眾號/程式設計師內點事", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); ``` - `PERSISTENT`-持久化目錄節點 :client建立節點後,與zookeeper斷開連線該節點將被持久化,當client再次連線後節點依舊存在。 - `PERSISTENT_SEQUENTIAL`-持久化順序節點 :client建立節點後,與zookeeper斷開連線該節點將被持久化,再次連線節點還存在,zookeeper會給該節點名稱進行順序編號,例如:/lock/0000000001、/lock/0000000002、/lock/0000000003。 - `EPHEMERAL`-臨時目錄節點 : client與zookeeper斷開連線後,該節點即會被刪除 - `EPHEMERAL_SEQUENTIAL`-臨時順序節點 : client與zookeeper斷開連線後,該節點被刪除,會給該節點名稱進行順序編號,例如:/lock/0000000001、/lock/0000000002、/lock/0000000003。 #### 二、節點的ACL許可權控制 `ACL`:即 `Access Control List` (節點的許可權控制),通過`ACL`機制來解決`znode`節點的訪問許可權問題,要注意的是`zookeeper`對許可權的控制是基於`znode`級別的,也就說節點之間的許可權不具有繼承性,即子節點不繼承父節點的許可權。 `zookeeper`中設定ACL許可權的