日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ZooKeeper私人学习笔记

發布時間:2025/7/14 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ZooKeeper私人学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

俗話說“好記性不如爛筆頭”,編程的海洋如此的浩大,養成做筆記的習慣是成功的一步!


此筆記主要是ZooKeeper3.4.9版本的筆記,并且筆記都是博主自己一字一字編寫和記錄,有錯誤的地方歡迎大家指正。




一、基礎知識:
1、ZooKeeper是一個分布式的,開放源碼的分布式應用程序協調服務,它包含一個簡單的原語集,分布式應用程序可以基于它實現同步
? 服務,配置維護和命名服務等。Zookeeper是hadoop的一個子項目,由于功能卓越,現已是apache的一個頂級子項目,應用于各種分布
? 式場景。官方網站:http://zookeeper.apache.org。
??
??
2、在分布式應用中,由于工程師不能很好地使用鎖機制,以及基于消息的協調機制不適合在某些應用中使用,因此需要有一種可靠的、
? 可擴展的、分布式的、可配置的協調機制來統一系統的狀態,Zookeeper的目的就在于此。Zookeeper的節點和數據操作,都能保證
? 在并發情況下的同步性和安全性,因此Zookeeper經常用于分布式鎖的操作,同時也用于集群數據共享的情形。
??
??
3、Zookeeper是通過的連接是長連接的,通過定時的發送心跳來檢測服務器的有效性,當檢測到服務器故障后,會直接操作該服務器
? 在Zookeeper上的節點狀態,當節點發生變化時,會通知對當前節點進行檢測的客戶端(即觀察者模式)。
??
??
??
4、Zookeeper的設計特點:
(1)最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖,這是zookeeper最重要的性能。


(2)可靠性:具有簡單、健壯、良好的性能,如果消息m被到一臺服務器接受,那么它將被所有的服務器接受。


(3)實時性:Zookeeper保證客戶端將在一個時間間隔范圍內獲得服務器的更新信息,或者服務器失效的信息。
但由于網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,
應該在讀數據之前調用sync()接口。


(4)等待無關(wait-free):慢的或者失效的client不得干預快速的client的請求,使得每個client都能有效的等待。


(5)原子性:更新只能成功或者失敗,沒有中間狀態。


(6)順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息b前發布,則在所有Server上消息a
?都將在消息b前被發布;偏序是指如果一個消息b在消息a后被同一個發送者發布,a必將排在b前面。
?
?
?
5、Zookeeper集群的master選舉,必須要要超過半數以上的服務器同意,故Zookeeper集群的服務器初始數量應為2n+1,即為奇數臺。
例如:
如果有2臺服務器A和B,假設A要選舉為master服務器,但此時只有一臺B服務器,即使B服務器同意,也只有1臺服務器,
因為不滿足n/2 + 1的數量,即 1 < 2 沒有超過半數,因此會出現選舉失敗。



6、Zookeeper的使用場景:
(1)統一命名服務。
分布式應用中,通常需要有一套完整的命名規則,既能夠產生唯一的名稱又便于人識別和記住,Name Service 已經是?
Zookeeper 內置的功能,通過調用API的create創建子節點。

(2)配置管理。
配置的管理在分布式應用環境中很常見,例如同一個應用系統需要多臺 PC Server 運行,如果要修改這些相同的配置
項,那么就必須同時修改每臺運行這個應用系統的 PC Server。像這樣的配置信息完全可以交給 Zookeeper 來管理,將配
置信息保存在 Zookeeper 的某個目錄節點中,然后將所有需要修改的應用機器監控配置信息的狀態,一旦配置信息發生變
化,每臺應用機器就會收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應用到系統中。

(3)集群管理。
它們的實現方式都是在 Zookeeper 上創建一個 EPHEMERAL 類型的目錄節點,然后每個 Server 在它們創建目錄節點的
父目錄節點上調用 getChildren(String path, boolean watch) 方法并設置 watch 為 true,由于是 EPHEMERAL 目錄節點,
當創建它的 Server 死去,這個目錄節點也隨之被刪除,所以 Children 將會變化,這時 getChildren上的 Watch 將會被
調用,所以其它 Server 就知道已經有某臺 Server 死去了。新增 Server 也是同樣的原理。

(4)共享鎖。
實現方式也是需要獲得鎖的 Server 創建一個 EPHEMERAL_SEQUENTIAL 目錄節點,然后調用 getChildren方法獲取當前
的目錄節點列表中最小的目錄節點是不是就是自己創建的目錄節點,如果正是自己創建的,那么它就獲得了這個鎖,如果不
是那么它就調用 exists(String path, boolean watch) 方法并監控 Zookeeper 上目錄節點列表的變化,一直到自己創建
的節點是列表中最小編號的目錄節點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創建的目錄節點就行了。

(5)隊列管理。
形式一:當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,這種是同步隊列。
形式二:隊列按照 FIFO 方式進行入隊和出隊操作,例如實現生產者和消費者模型。


?
7、當客戶端watch某個znode節點的時候,某個節點被改變時(例如數據改變或刪除或子節點有變化等),Zookeeper會自動通知watch
? 的客戶端,然后清空掉此節點下所有的watch的客戶端。因此,客戶端向繼續監聽某個znode節點,則必須重新進行監視watch此節點。
??
? 此模式其實就是觀察者模式,當被觀察的對象發生改變時,通知觀察者。
??




8、Zookeeper服務器的使用需要注意的幾個事項:
(1)watch監視是一次性的,再次監視需要重新設置監視節點。

(2)如果監視znode節點的客戶端失去連接了,那么znode被改變后客戶端是不會收到通知的,
即使后面客戶端重新連接了Zookeeper。
?
(3)在刪除znode節點的時候,只允許在空子節點的情況下刪除,如果當前節點下有子節點,那么是不允許刪除的。

(4)Zookeeper有種臨時節點Ephemeral節點,在此連接斷開后,就會被自動清除。因此臨時節點不允許有子節點。

(5)Zookeeper的節點存儲的數據不能大于1M,本身的設計就不是用來存儲大數據,因此需要避免節點下的數據過大。


(6)相同的路徑下,不允許有相同名稱的節點存在,如果創建相同名字的節點會在創建時報錯。如果基本名稱都一樣的,
可以創建序列節點Sequence節點,Zookeeper會自動在基本名稱后面添加一個按順序的數字標識。
?
?
?

9、每個znode節點的數據結構如下:
czxid:創建此節點時的zxid(Zookeeper Transition ID)
The zxid of the change that caused this znode to be created.

mzxid:最后更改此節點的zxid。
The zxid of the change that last modified this znode.

pzxid:最好更改此節點或子節點時的zxid。
The zxid of the change that last modified children of this znode.

ctime:創建此節點時的時間。
The time in milliseconds from epoch when this znode was created.

mtime:最終修改此節點的時間。
The time in milliseconds from epoch when this znode was last modified.

dataVersion:當前節點數據版本號,數據被修改版本號就會自增1。
The number of changes to the data of this znode.

cversion:當前節點下的子節點被修改時的版本號,子節點新增或刪除時會自增1。
The number of changes to the children of this znode.

aclVersion:當前節點的ACL(訪問控制列表)被修改時的版本號,每次修改會自增1。
The number of changes to the ACL of this znode.

ephemeralOwner:如果當前節點是臨時節點,則存儲session id,如果不是臨時節點則為0.
he session id of the owner of this znode if the znode is an ephemeral node.?
If it is not an ephemeral node, it will be zero.

dataLength:當前節點下保存的數據長度。
The length of the data field of this znode.

numChildren:當前節點下的子節點個數。
The number of children of this znode.
?


10、Zookeeper的watch機制:
(1)服務端維護兩個watch列表,一個是當前節點與數據watch列表,另外一個是子節點watch列表。
注意:
當前節點與數據watch列表:是當節點改變或者節點數據改變時,都會觸發的列表。
子節點watch列表:是當子節點改變時觸發,而子節點的數據改變時是不會觸發的。


(2)設置監聽者,即指定監聽watch的znod節點的方式:
getData()和exists()設置當前節點與數據Watch,getChildren()設置子節點Watch。


(3)觸發機制,即會觸發watch的方式:
setData()觸發內容Watch。即觸發當前節點與數據watch列表。
create()觸發其父節點的子節點Watch。子節點watch列表觸發。
delete()同時觸發父節點的子節點Watch和當前節點與數據Watch。當前節點與數據watch列表和子節點watch列表都有觸發。



11、Zookeeper的ACL(訪問控制列表):
(1)ACL的權限分為五類:
CREATE: 創建權限,允許在該節點下創建子節點。you can create a child node.

READ:讀權限,允許讀取該節點數據和查詢他的所屬子節點。 you can get data from a node and list its children.

WRITE: 寫權限,允許在該節點下修改data數據。you can set data for a node.

DELETE: 刪除權限,允許刪除他的所屬子節點。you can delete a child node.

ADMIN: 管理權限,允許再該節點下設置ACL。you can set permissions.


注意:CREATE和DELETE都是他所屬的子節點進行權限控制的,并不是針對當前節點。
? ? ?即任何人都可以刪除當前節點,如果你知道節點路徑的話。


(2)ACL的權限是不遞歸的。例如:假設給一個節點設置了讀權限的控制,一個用戶即使沒有讀取當前節點的權限,
? 但是如果知道當前節點下的子節點路徑,依舊可以讀取子節點的數據,父節點的權限不會遞歸到子節點。
??
??
??
(3)ACL的控制策略有如下幾類:
world: 它下面只有一個id, 叫anyone, world:anyone代表任何人。

auth: 它不需要id, 只要是通過authentication的user都有權限,也就是說默認采用的username:password就是
? ? ?當前用戶認證使用的用戶名和密碼,如果當前用戶沒有認證過,使用auth策略會報錯。

digest: 它對應的id為username:BASE64(SHA1(password)),它需要先通過username:password形式的進行認證。

ip: 它對應的id為客戶機的IP地址,設置的時候可以設置一個ip段,比如ip:192.168.1.0/16, 表示匹配前16個bit的IP段。

x509: 客戶端使用X500的規則來認證。


提示:比較常用的是digest和auth的形式。



?
?
?
二、安裝部署:
1、Zookeeper是用Java語言實現的,因此必須要先安裝JDK。

2、Zookeeper單臺服務器的安裝(基于Linux系統):
步驟一:解壓zookeeper-3.4.9.tar.gz目錄,執行命令 tar -zxvf zookeeper-3.4.9.tar.gz -C /usr/user


步驟二:進入加壓后的目錄/usr/user/zookeeper-3.4.9 ,在該目錄下創建data和log目錄用于存放數據和日志,
執行命令 mkdir data log


步驟三:在當前Zookeeper目錄下,進入conf目錄進行配置。新建zoo.cfg文件(Zookeeper默認會加載此配置),然后輸入如下配置:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/users/zookeeper/data
dataLogDir=/usr/users/zookeeper/log
clientPort=2181


?

步驟四:在當前Zookeeper目錄下,進入bin目錄。執行命令來操作Zookeeper服務。
sh ?zkServer.sh start #啟動Zookeeper服務
sh ?zkServer.sh stop #停止Zookeeper服務
sh ?zkServer.sh status #查看Zookeeper服務的運行狀態。



步驟五:通過Zookeeper自帶的客戶端操作Zookeeper服務。執行命令 ?sh zkCli.sh -server localhost:2181?
如果是連接本地Zookeeper服務,并且使用的是默認的2181端口,則可以簡寫 sh zkCli.sh?





3、Zookeeper的集群安裝(基于Linux系統):
因為Zookeeper本身就是為集群提供服務的,在設計時就考慮Zookeeper的集群,因此Zookeeper的集群非常簡單。基于單臺服務器
的安裝后,增加如下步驟:假設有三臺服務器 192.168.1.2:2181、192.168.1.3:2181、192.168.1.4:2181

續步驟一:在當前Zookeeper目錄下,進入data目錄,創建myid文件(用于給當前Zookeeper服務器添加id標識,范圍為1~255)。
? 此處設置標識如下(myid只需輸入數字)
? 192.168.1.2服務器的id為 1
? 192.168.1.3服務器的id為 2
? 192.168.1.4服務器的id為 3
??
??
??
繼步驟二:在conf/zoo.cfg配置文件下,添加如下配置信息:
server.1=192.168.1.2:2888:3888
server.2=192.168.1.3:2888:3888
server.3= 92.168.1.4:2888:3888

#1,2,3分別是每個服務器的id,后面是對應的ip地址,2888:3888是可以用于Zookeeper服務器之間內部通信使用的端口。



注意:使用Zookeeper集群時,注意防火墻配置,可能會引起Zookeeper無法探測到其他服務器,導致啟動失敗。




三、java 連接Zookeeper的使用筆記:
1、java連接Zookeeper的開源框架有三種:
第一種是Zookeeper官方提供的原生java api。

第二種是由datameer的工程師開發的zkClient,源碼在github上可下載。修復了原生java api的一些bug和簡化api操作。

第三種是curator框架,也是apache開發的。curator的api更簡單,更能更強大,是最受歡迎的java版Zookeeper連接框架。

注意:本筆記默認是使用官方提供的原生api來連接Zookeeper。




2、zookeeper-3.4.9.jar包是java連接Zookeeper服務端的原生jar包,依賴于slfj日志門面框架的jar包,需要同時引入,
? 具體的jar包在lib_jar目錄下。



3、原生api使用了java的非阻塞NIO來連接,并且是開啟新的線程來去連接服務端的。因此,主線程必須要監控連接成功事件,
? 在連接成功后才開始操作Zookeeper,以免拋出異常。
??
? 提示:可以借助JDK并發庫的CountDownLatch 對象來實現主線程的阻塞,直到連接成功。
??
? 代碼示例:
final CountDownLatch countDownLatch = new CountDownLatch(1);
//創建Zookeeper的核心對象,此對象在創建時就開啟新的線程去連接服務端。
ZooKeeper zk = new ZooKeeper("10.17.2.7:2181", 3000, new Watcher() {
@Override
public void process(WatchedEvent event) {
//連接成功的狀態,進行通知。
if (event.getType() == EventType.None && event.getState() == KeeperState.SyncConnected) {
countDownLatch.countDown();
}
}
});
//等待連接成功。
countDownLatch.await();
//連接成功,開始執行對zk操作的業務邏輯。
System.out.println("ZooKeeper 連接成功!");
??
??
??
??
4、原生api可以定制默認的watcher監視者,就是在創建核心操作類ZooKeeper的時候,在構造方法中指定默認的watcher,
? 此方法的所有api中凡是通過boolean值來指定是否監視的,如果為true則都是使用默認的watcher進行監視。如果為false,
? 則不進行監視。
??
? 例如:zk.getData()、zk.getChildren()等方法。



5、Zookeeper服務器是支持事務的,因此java版的原生api也支持事務的操作。實例代碼如下:
//創建連接
ZooKeeper zk = new ZooKeeper("10.17.2.7:2181", 3000, null);
//獲得事務對象
Transaction ts = zk.transaction();
//通過事務對象來操作數據。如果是用zk對象來操作數據,那么是不在此事務范圍內的。如zk.create()操作是不受事務影響的。
ts.create("/java/a7", "節點a".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//必須提交事務,否則數據修改無效。
ts.commit();
zk.close();





6、使用Zookeeper獲得分布式鎖的基本思想:
? 先創建好一個獲得鎖的父節點,然后每個線程在該父節點下創建自己的EPHEMERAL_SEQUENTIAL節點(臨時隊列節點),然后獲取
該父節點下的所有子節點,使用TreeSet進行自然排序,然后獲取首個元素(即序列最小的元素),判斷最小元素的名稱是否是當前
創建的最小元素名稱,如果是則表名當前線程獲取了鎖,可以執行業務邏輯。如果不是,則獲取此元素前面的一個元素,然后進行
watch監視,當監視節點被刪除或,獲取獲取所有的節點進行判斷,重復執行此邏輯,直到當前最小元素為當前線程創建的最小元素。

注意:當獲取鎖的線程操作完成后,必須刪除當前節點,以便讓后續監視者執行監視邏輯的方法,從而讓監視者得到鎖。
??
說明:每個線程創建的節點必須是EPHEMERAL_SEQUENTIAL節點。因為臨時節點會在當前連接斷開后會自動刪除,這樣可以在當前線程
?的客戶端宕機后,及時的處理掉他所擁有的節點,避免線程死鎖。同時,創建隊列類型的節點,在創建時服務端會按創建順序
?在節點名稱后面加一串序列數字,可以通過此數字來確定獲取鎖的節點是哪個。
?
?
?
附加:除了使用Zookeeper獲取分布式鎖以外,還可以使用redis來獲取,但Zookeeper獲取分布式鎖更方便。
?redis獲取分布式鎖的基本思想:借助setnx和getset命令來實現。首先通過setnx存儲一個時間戳值,此時間戳表示鎖的有效
?時間。如果設置成功,則表名是獲取鎖,當前線程可獲得鎖。如果設置失敗,則開始每隔一段時間循環讀取。使用get讀取當
?前key的value值,value值存的是鎖的有效時間,判斷value值是否小于當前時間,如果是,則說明鎖已經失效,則根據當前時
?間計算出鎖的有效時間,然后使用getset方法,更新舊的鎖時間,如果返回的舊值與之前get讀取的值一致,則說明獲取鎖成
?功。如果不一致,則說明被其他線程先執行getset操作了,則獲取循環嘗試獲取鎖。
?
?
?setnx命令:是當key不存在時才會設置成功并返回1,否則設置失敗并返回0。
?getset命令:更新當前key的value值,并返回舊的value值,如果當前沒有舊值,則返回nil。
?get命令:根據key讀取value值,如果沒有則返回nil。





/***************************************************************附加**********************************************************/
附加1、使用zkCli.sh 腳本進入Zookeeper的客戶端,可以使用的命令有:
[zkshell: 0] help
ZooKeeper host:port cmd args
get path [watch]
ls path [watch]
set path data [version]
delquota [-n|-b] path
quit
printwatches on|off
create path data acl
stat path [watch]
listquota path
history
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
deleteall path
setquota -n|-b val path













??



轉載于:https://www.cnblogs.com/catgwj/p/7492824.html

總結

以上是生活随笔為你收集整理的ZooKeeper私人学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。