zookeeper使用和原理探究

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。

zookeeper介紹
zookeeper是一個為分布式應用提供一致性服務的軟件,它是開源的Hadoop項目中的一個子項目,并且根據google發表的<The Chubby lock service for loosely-coupled distributed systems>論文來實現的,接下來我們首先來安裝使用下這個軟件,然后再來探索下其中比較重要一致性算法。??

zookeeper安裝和使用
zookeeper的安裝基本上可以按照?http://hadoop.apache.org/zookeeper/docs/current/ zookeeperStarted.html?這個頁面上的步驟完成安裝,這里主要介紹下部署一個集群的步驟,因為這個官方頁面似乎講得并不是非常詳細(Running Replicated Zookeeper)。

由于手頭機器不足,所以在一臺機器上部署了3個server,如果你手頭也比較緊,也可以這么做。那么我建了3個文件夾,如下
server1?? server2?? server3

然后每個文件夾里面解壓一個zookeeper的下載包,并且還建了幾個文件夾,總體結構如下,最后那個是下載過來壓縮包的解壓文件
data?dataLog?logs?zookeeper-3.3.2

那么首先進入data目錄,創建一個myid的文件,里面寫入一個數字,比如我這個是server1,那么就寫一個1,server2對應myid文件就寫入2,server3對應myid文件就寫個3

然后進入zookeeper-3.3.2/conf目錄,那么如果是剛下過來,會有3個文件,configuration.xml, log4j.properties,zoo_sample.cfg,這3個文件我們首先要做的就是在這個目錄創建一個zoo.cfg的配置文件,當然你可以把zoo_sample.cfg文件改成zoo.cfg,配置的內容如下所示:?
tickTime=2000
initLimit=5
syncLimit=2
dataDir=xxxx/zookeeper/server1/data
dataLogDir=xxx/zookeeper/server1/dataLog
clientPort=2181

server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

標紅的幾個配置應該官網講得很清楚了,只是需要注意的是clientPort這個端口如果你是在1臺機器上部署多個server,那么每臺機器都要不同的clientPort,比如我server1是2181,server2是2182,server3是2183,dataDir和dataLogDir也需要區分下。?

最后幾行唯一需要注意的地方就是?server.X?這個數字就是對應?data/myid中的數字。你在3個server的myid文件中分別寫入了1,2,3,那么每個server中的zoo.cfg都配server.1,server.2,server.3就OK了。因為在同一臺機器上,后面連著的2個端口3個server都不要一樣,否則端口沖突,其中第一個端口用來集群成員的信息交換,第二個端口是在leader掛掉時專門用來進行選舉leader所用。

進入zookeeper-3.3.2/bin?目錄中,./zkServer.sh start啟動一個server,這時會報大量錯誤?其實沒什么關系,因為現在集群只起了1臺server,zookeeper服務器端起來會根據zoo.cfg的服務器列表發起選舉leader的請求,因為連不上其他機器而報錯,那么當我們起第二個zookeeper實例后,leader將會被選出,從而一致性服務開始可以使用,這是因為3臺機器只要有2臺可用就可以選出leader并且對外提供服務(2n+1臺機器,可以容n臺機器掛掉)。

接下來就可以使用了,我們可以先通過?zookeeper自帶的客戶端交互程序來簡單感受下zookeeper到底做一些什么事情。進入zookeeper-3.3.2/bin(3個server中任意一個)下,./zkCli.sh?–server?127.0.0.1:2182,我連的是開著2182端口的機器。

那么,首先我們隨便打個命令,因為zookeeper不認識,他會給出命令的help,如下圖??
???
ls(查看當前節點數據),
ls2(查看當前節點數據并能看到更新次數等數據) ,
create(創建一個節點) ,
get(得到一個節點,包含數據和更新次數等數據),
set(修改節點)
delete(刪除一個節點)

通過上述命令實踐,我們可以發現,zookeeper使用了一個類似文件系統的樹結構,數據可以掛在某個節點上,可以對這個節點進行刪改。另外我們還發現,當改動一個節點的時候,集群中活著的機器都會更新到一致的數據。?

zookeeper的數據模型
在簡單使用了zookeeper之后,我們發現其數據模型有些像操作系統的文件結構,結構如下圖所示



(1)?????每個節點在zookeeper中叫做znode,并且其有一個唯一的路徑標識,如/SERVER2節點的標識就為/APP3/SERVER2
(2)?????Znode可以有子znode,并且znode里可以存數據,但是EPHEMERAL類型的節點不能有子節點
(3)?????Znode中的數據可以有多個版本,比如某一個路徑下存有多個數據版本,那么查詢這個路徑下的數據就需要帶上版本。
(4)?????znode?可以是臨時節點,一旦創建這個?znode?的客戶端與服務器失去聯系,這個?znode?也將自動刪除,Zookeeper?的客戶端和服務器通信采用長連接方式,每個客戶端和? 服務器通過心跳來保持連接,這個連接狀態稱為?session,如果?znode?是臨時節點,這個?session?失效,znode?也就刪除了
(5)?????znode?的目錄名可以自動編號,如?App1?已經存在,再創建的話,將會自動命名為?App2?
(6)?????znode?可以被監控,包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化可以通知設置監控的客戶端,這個功能是zookeeper對于應用最重要的特性,通過這個特性可以實現的功能包括配置的集中管理,集群管理,分布式鎖等等。??

通過java代碼使用zookeeper?
Zookeeper的使用主要是通過創建其jar包下的Zookeeper實例,并且調用其接口方法進行的,主要的操作就是對znode的增刪改操作,監聽znode的變化以及處理。?

以下為主要的API使用和解釋

//創建一個Zookeeper實例,第一個參數為目標服務器地址和端口,第二個參數為Session超時時間,第三個為節點變化時的回調方法
ZooKeeper?zk?=?new?ZooKeeper("127.0.0.1:2181",?500000,new?Watcher()?{
???????????
//?監控所有被觸發的事件
?????????????public?void?process(WatchedEvent?event)?{
???????????
//dosomething
???????????}
??????});
//創建一個節點root,數據是mydata,不進行ACL權限控制,節點為永久性的(即客戶端shutdown了也不會消失)
zk.create("/root",?"mydata".getBytes(),Ids.OPEN_ACL_UNSAFE,?CreateMode.PERSISTENT);

//在root下面創建一個childone?znode,數據為childone,不進行ACL權限控制,節點為永久性的
zk.create("/root/childone","childone".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);

//取得/root節點下的子節點名稱,返回List<String>
zk.getChildren("/root",true);

//取得/root/childone節點下的數據,返回byte[]
zk.getData("/root/childone",?true,?null);

//修改節點/root/childone下的數據,第三個參數為版本,如果是-1,那會無視被修改的數據版本,直接改掉
zk.setData("/root/childone","childonemodify".getBytes(),?-1);

//刪除/root/childone這個節點,第二個參數為版本,-1的話直接刪除,無視版本
zk.delete("/root/childone",?-1);
??????
//關閉session
zk.close();

?
Zookeeper的主流應用場景實現思路(除去官方示例)?

(1)配置管理
集中式的配置管理在應用集群中是非常常見的,一般商業公司內部都會實現一套集中的配置管理中心,應對不同的應用集群對于共享各自配置的需求,并且在配置變更時能夠通知到集群中的每一個機器。

Zookeeper很容易實現這種集中式的配置管理,比如將APP1的所有配置配置到/APP1 znode下,APP1所有機器一啟動就對/APP1這個節點進行監控(zk.exist("/APP1",true)),并且實現回調方法Watcher,那么在zookeeper/APP1 znode節點下數據發生變化的時候,每個機器都會收到通知,Watcher方法將會被執行,那么應用再取下數據即可(zk.getData("/APP1",false,null));

以上這個例子只是簡單的粗顆粒度配置監控,細顆粒度的數據可以進行分層級監控,這一切都是可以設計和控制的。?????
(2)集群管理?
應用集群中,我們常常需要讓每一個機器知道集群中(或依賴的其他某一個集群)哪些機器是活著的,并且在集群機器因為宕機,網絡斷鏈等原因能夠不在人工介入的情況下迅速通知到每一個機器。

Zookeeper同樣很容易實現這個功能,比如我在zookeeper服務器端有一個znode/APP1SERVERS,那么集群中每一個機器啟動的時候都去這個節點下創建一個EPHEMERAL類型的節點,比如server1創建/APP1SERVERS/SERVER1(可以使用ip,保證不重復)server2創建/APP1SERVERS/SERVER2,然后SERVER1SERVER2watch /APP1SERVERS這個父節點,那么也就是這個父節點下數據或者子節點變化都會通知對該節點進行watch的客戶端。因為EPHEMERAL類型節點有一個很重要的特性,就是客戶端和服務器端連接斷掉或者session過期就會使節點消失,那么在某一個機器掛掉或者斷鏈的時候,其對應的節點就會消失,然后集群中所有對/APP1SERVERS進行watch的客戶端都會收到通知,然后取得最新列表即可。

另外有一個應用場景就是集群選master,一旦master掛掉能夠馬上能從slave中選出一個master,實現步驟和前者一樣,只是機器在啟動的時候在APP1SERVERS創建的節點類型變為EPHEMERAL_SEQUENTIAL類型,這樣每個節點會自動被編號,例如??????????

zk.create("/testRootPath/testChildPath1","1".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
????????
zk.create(
"/testRootPath/testChildPath2","2".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
????????
zk.create(
"/testRootPath/testChildPath3","3".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
????????
//?創建一個子目錄節點
zk.create("/testRootPath/testChildPath4","4".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);

System.out.println(zk.getChildren(
"/testRootPath",?false));

?打印結果:[testChildPath10000000000, testChildPath20000000001, testChildPath40000000003, testChildPath30000000002]

?

?

zk.create("/testRootPath",?"testRootData".getBytes(),Ids.OPEN_ACL_UNSAFE,?CreateMode.PERSISTENT);

//?創建一個子目錄節點
zk.create("/testRootPath/testChildPath1","1".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
????????
zk.create("/testRootPath/testChildPath2","2".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
????????
zk.create("/testRootPath/testChildPath3","3".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
????????
//?創建一個子目錄節點
zk.create("/testRootPath/testChildPath4","4".getBytes(),?Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);

System.out.println(zk.getChildren("/testRootPath",?false));

打印結果:[testChildPath2, testChildPath1, testChildPath4, testChildPath3]

我們默認規定編號最小的為master,所以當我們對/APP1SERVERS節點做監控的時候,得到服務器列表,只要所有集群機器邏輯認為最小編號節點為master,那么master就被選出,而這個master宕機的時候,相應的znode會消失,然后新的服務器列表就被推送到客戶端,然后每個節點邏輯認為最小編號節點為master,這樣就做到動態master選舉。


總結?

?

?

我們初步使用了一下zookeeper并且嘗試著描述了幾種應用場景的具體實現思路,接下來的文章,我們會嘗試著去探究一下zookeeper的高可用性與leaderElection算法。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450633.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450633.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450633.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

thinkphp如何部署到寶塔面板nginx服務器

原理&#xff1a;一般本地都會使用apache服務器&#xff0c;這個對pathinfo&#xff08;兩個&#xff0c;一個是環境變量$_SERVER[PATH_INFO]&#xff0c;另一個是pathinfo函數&#xff09;路由解析非常支持的&#xff0c;不需要部署什么&#xff0c; 但是nginx是對pathinfo函…

Android獲取所有應用的資源id和對應的uri

背景在某些應用中&#xff0c;為了實現應用apk資源放入重復利用&#xff0c;或者使用反射得到本應用的資源&#xff0c;需要使用反射方式獲得&#xff0c;但Resources類中也自帶了這種獲取方式&#xff0c;并且功能更加強大你可以獲取string,color,drawable,raw,xml等文件&…

nginx的腳本引擎(一)

nginx的腳本的語法和shell是很像的&#xff0c;我大致看了一下覺得挺有意思的&#xff0c;就想寫寫記錄一下。我沒看過shell腳本的引擎&#xff0c;不知道nginx腳本引擎和shell腳本引擎像不像&#xff0c;但是我覺得nginx的腳本引擎有點像C和匯編。 ngx_http_script_engine_t這…

一個待辦事列表todolist

最近有位老師讓我做的&#xff0c;圖片在下面&#xff0c;做了4個多小時&#xff0c;ui有的簡陋&#xff0c;可以再美化一下&#xff0c;這個會更好看&#xff0c;畢竟我也不是專業前端&#xff0c;測試網站http://todolist.sshouxin.top/使用的是thinkphp5.1的框架&#xff0c…

詳細說明 SourceTree 免登錄,跳過初始設置的方法(Windows 版 )

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 首先&#xff0c;安裝完 SourceTree 以后先運行一次&#xff0c;彈出初始化登錄頁面后退出。 2. 進入這個文件夾&#xff1a;C:\Users…

什么是好的API設計?

摘要&#xff1a;有人言&#xff0c;API設計是編程工作中最難的事情。甚至有人認為至少要有10年的工作經驗才能接觸它。不過這里提出了一個引人思考的問題&#xff1a;究竟是構建什么樣的庫需要花費10年的時間去學習&#xff1f; 有人言&#xff0c;API設計是編程工作中最難的事…

Linux學習記錄-文件、目錄與磁盤

用戶和群組 用戶和群組主要是為了區分用戶對文件的操作權限。 賬號在/etc/passwd個人密碼在/etc/shadow組信息在/etc/group 不要亂動這3個文件文件權限和目錄配置 文件屬性 文件前綴解釋&#xff0c;例如&#xff1a; 第一個字符代表這個文件是『目錄、文件或鏈接文件等等』&am…

php curl模擬https請求

https請求(支持GET和POST) function http_request($url,$data null){$curl curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);if(!empty($data)){curl_setopt($cur…

springboot集成環信sdk報錯

import io.swagger.client.ApiException; import io.swagger.client.api.MessagesApi; import io.swagger.client.model.Msg 這個是因為少兩個包&#xff0c;只需要把在你的pom.xml添加以下代碼即可&#xff0c;不要忘記點贊哈只需要添加兩個包即可&#xff0c;你可以自行網上下…

解決 error: Your local changes to the following files would be overwritten by merge:XXXX

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 idea 上將本地代碼推送到 git后 , 報錯如下圖 error: Your local changes to the following files would be overwritten by merge:src/…

深度有趣 | 30 快速圖像風格遷移

簡介 使用TensorFlow實現快速圖像風格遷移&#xff08;Fast Neural Style Transfer&#xff09; 原理 在之前介紹的圖像風格遷移中&#xff0c;我們根據內容圖片和風格圖片優化輸入圖片&#xff0c;使得內容損失函數和風格損失函數盡可能小 和DeepDream一樣&#xff0c;屬于網絡…

轉型從思維習慣的轉變開始

摘要&#xff1a;首先建議大家不要輕易轉向管理崗位&#xff0c;要認清自己是否適合做管理。轉型過程中應把握好幾點&#xff1a;良好的技術基礎&#xff0c;它是贏得團隊信任的前提&#xff0c;是把握團隊整體方向的關鍵&#xff1b;培養大局觀&#xff0c;只有站得高才能看得…

數據庫小知識點(一直更新)

一、mysql查詢是否含有某字段&#xff1a; mysql數據庫查詢帶有某個字段的所有表名 SELECT * FROM information_schema.columns WHERE column_namecolumn_name; oracle數據庫查詢帶有某個字段的所有表名 select column_name,table_name,from user_tab_columns where column_n…

其他運算符

原文地址&#xff1a;https://wangdoc.com/javascript/ void運算符 void運算符的作用是執行一個表達式&#xff0c;然后不返回任何值&#xff0c;或者說返回undefined。 void 0 // undefined void(0) // undefined 上面是void運算符的兩種寫法&#xff0c;都正確。建議采用后一…

git pull --rebase 做了什么? 以及 Cannot rebase: You have unstaged changes 解決辦法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 最近剛學 git rebase&#xff0c;覺得很牛逼的樣子&#xff0c; 結果今天就被打臉了。 git pull --rebase 1 報錯&#xff1a; Cann…

vue如何實現單頁緩存方案分析

實現全站的頁面緩存&#xff0c;前進刷新&#xff0c;返回走緩存&#xff0c;并且能記住上一頁的滾動位置&#xff0c;參考了很多技術實現&#xff0c;github上的導航組件實現的原理要么使用的keep-alive&#xff0c;要么參考了keep-alive的源碼&#xff0c;但是只用keep-alive…

C語言常用函數簡介

一、字符測試函數 isupper()測試字符是否為大寫英文字ispunct()測試字符是否為標點符號或特殊符號isspace()測試字符是否為空格字符isprint()測試字符是否為可打印字符islower()測試字符是否為小寫字母isgraphis()測試字符是否為可打印字符isdigit()測試字符是否為阿拉伯數字i…

thinkphp如何增加session的過期時間

原理&#xff1a;我們都知道session是建立在cookie的基礎上的&#xff0c;如果瀏覽器cookie清楚了&#xff0c;則tp就會重新建立一個session。 操作&#xff1a;直接增加瀏覽器的cookie的到期時間&#xff0c;就可以使tp的session增加。

需求心得

電路圖是人們為研究、工程規劃的需要。我們組項目需要設計實現一個矢量圖編輯器。在通過對變電站的電路圖進行矢量繪圖后&#xff0c;就可以通過矢量圖的縮放詳細信息。在分析需求后&#xff0c;寫下心得&#xff01; 分析需求主要有一下幾個步驟&#xff1a; 1. 獲取和引導需求…

IT部門不應該是一個后勤部門

管理上最大的問題在于不重視預算與核算的管理。從管理層到員工&#xff0c;很少有經營的念頭&#xff0c;只是一味地埋頭做事。西方企業總結了當今幾百年的經營理念&#xff0c;最終把企業一切活動的評價都歸結到唯一的、可度量的標準上&#xff1a;錢來度量。 by——華為 作為…