ZooKeeper实战(一):ZooKeeper原理,详细安装步骤,基本命令,节点间通信原理
回顧Redis
用redis實現(xiàn)分布式鎖比較復(fù)雜,使用zookeeper會比較簡單。
一、ZooKeeper介紹
官網(wǎng)
https://zookeeper.apache.org/
概覽文檔
https://zookeeper.apache.org/doc/current/zookeeperOver.html
1、什么是ZooKeeper?
ZooKeeper:分布式應(yīng)用程序的分布式協(xié)調(diào)服務(wù)
- ZooKeeper使用了按照文件系統(tǒng)熟悉的目錄樹結(jié)構(gòu)命名的數(shù)據(jù)模型。
- ZooKeeper提供的名稱空間與標準文件系統(tǒng)的名稱空間非常相似。名稱是由斜杠(/)分隔的一系列路徑元素。ZooKeeper命名空間中的每個節(jié)點都由路徑標識。
- 名稱空間由數(shù)據(jù)寄存器(稱為znode)組成,它們類似于文件和目錄。與設(shè)計用于存儲的典型文件系統(tǒng)不同,ZooKeeper數(shù)據(jù)保留在內(nèi)存中,這意味著ZooKeeper可以實現(xiàn)高吞吐量和低延遲數(shù)。
- 像它協(xié)調(diào)的分布式進程一樣,ZooKeeper本身也可以在稱為集合的一組主機上進行復(fù)制。
- 眾所周知,協(xié)調(diào)服務(wù)很難做到。它們特別容易出現(xiàn)諸如比賽條件和死鎖之類的錯誤。ZooKeeper背后的動機是減輕分布式應(yīng)用程序從頭開始實施協(xié)調(diào)服務(wù)的責任。
zk集群
每個節(jié)點的數(shù)據(jù)都一樣。有一個leader,其他都是follower,是一個主從集群。寫操作只能發(fā)生在leader身上。
主掛了怎么辦?zk可以快速自我修復(fù)。
下圖左側(cè):可用狀態(tài)
下圖右側(cè):不可用狀態(tài)(leader掛掉了)
不可用狀態(tài)恢復(fù)到可用狀態(tài),應(yīng)該越快越好!
官方壓測:
存在錯誤中的可靠性表明部署如何響應(yīng)各種故障。圖中標記的事件如下:
1、追隨者的失敗和恢復(fù)
2、其他追隨者的失敗和恢復(fù)
3、領(lǐng)導(dǎo)者的失敗
4、兩個追隨者的失敗和恢復(fù)
5、另一個領(lǐng)導(dǎo)者的失敗
官方壓測結(jié)果:ZooKeeper只需不到200毫秒即可選出新的領(lǐng)導(dǎo)者。
不要把zk當數(shù)據(jù)庫用
redis可以作為數(shù)據(jù)庫使用,但zk不應(yīng)該作為數(shù)據(jù)庫。zk每個node只能存1M,是為了保證對外提供分布式協(xié)調(diào)時的速度。
臨時節(jié)點
每個客戶端連接到zk之后,一定會有一個session來代表這個客戶端,用來表示當前的會話。
依托session,我們有了臨時節(jié)點的概念,可以用來解決之前redis加鎖時需要設(shè)置過期時間的問題:
客戶端在,session就在,鎖就在。
客戶端不在了,session就不在了,鎖就釋放了。
序列節(jié)點
持久節(jié)點 和臨時節(jié)點都可以作為序列節(jié)點。
2、ZooKeeper 的特點
- 順序一致性:來自客戶端的更新將按照發(fā)送的順序應(yīng)用。
- 原子性:數(shù)據(jù)更新的成功或失敗,要么全部節(jié)點都成功,要么全部節(jié)點都失敗(最終一致性)
- 統(tǒng)一視圖:無論客戶端連接到哪個服務(wù)器,客戶端都將看到相同的服務(wù)視圖。即使客戶端故障轉(zhuǎn)移到具有相同會話的其他服務(wù)器,客戶端也永遠不會看到系統(tǒng)的較舊視圖。
- 可靠性:一旦應(yīng)用了更新,該更新將一直持續(xù)到客戶端覆蓋更新為止。
- 及時性:確保系統(tǒng)的客戶視圖在特定時間范圍內(nèi)是最新的(很短的時間內(nèi)內(nèi)達成最終一致性)。
二、ZooKeeper 安裝
一個小技巧:xshell可以同時向多個會話發(fā)送命令,在 查看->撰寫欄 選中即可,先來看一下四個節(jié)點的ip:
1、準備
四臺虛擬機,裝了 jdk1.8
最好不要用yum安裝jdk,因為yum不是oracle的hotspotjvm,是openjdk。搞過大數(shù)據(jù)的都清楚,很多開源社區(qū)曾經(jīng)的時候是openjdk hotspot都測試,后來它們只對oracle的測試,可能對openjdk不兼容
2、下載好ZK的tar壓縮包
https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz
注意大坑:在版本的更新記錄中記載,從版本3.5.5開始,帶有bin名稱的包才是我們想要的下載可以直接使用的里面有編譯后的二進制的包,而之前的普通的tar.gz的包里面是只是源碼的包,無法直接使用!!
所以同學們,如果下載3.5.5以后的版本的Zookeeper安裝包,我們乖乖的下載帶有bin標識的包就不會有問題了
在node01上準備好安裝包就好,另外三臺后面我們直接拷貝
3、tar xf 解壓
tar -xf apache-zookeeper-3.6.1-bin.tar.gz4、創(chuàng)建目錄
先在node01配置好,然后將這個配置目錄向node02,node03,node04分發(fā)就可以了。
mkdir /opt/mashibing mv apache-zookeeper-3.6.1-bin /opt/mashibingcd /opt/mashibing/apache-zookeeper-3.6.1-bin && cd conf cp zoo_sample.cfg zoo.cfg # zk 默認配置文件名稱為zoo.cfg# 未來持久化數(shù)據(jù)的目錄,里面創(chuàng)建 myid 文件,內(nèi)容為1,代表配置文件里面對應(yīng)的,這臺機器的id號 mkdir -p /var/mashibing/zk && echo 1 > /var/mashibing/zk/myid && cat /var/mashibing/zk/myidcd /var/mashibing/zk vi zoo.cfg# 數(shù)據(jù)最好不要放在tmp目錄下,所以我們將存放數(shù)據(jù)的目錄修改成: dataDir=/var/mashibing/zk# 配置文件最后面添加: # 注意要提前配好IP地址與主機名映射的/etc/hosts文件,否則計算機怎么知道node01是誰?或者你不配的話,直接用ip地址代替nodexx也可以 server.1=node01:2888:3888 server.2=node02:2888:3888 server.3=node03:2888:3888 server.4=node04:2888:3888 # 含義:沒有l(wèi)eader的時候,節(jié)點之間通過3888端口通信,投票選出leader之后,leader使用2888端口 # 如何快速選出leader?通過謙讓,誰的id最大就用誰。過半通過即可(3臺通過即可)。5、準備遠程拷貝目錄
關(guān)于IP地址與主機名映射的/etc/hosts文件配置:
https://blog.csdn.net/weixin_43716338/article/details/103572507
四臺機器配置相同
6、添加完成之后,可以開始遠程拷貝到另外三個節(jié)點上了
# 將當前目錄下的mashibing拷貝到遠程的與當前pwd相同的目錄下,需要輸入一下密碼就ok # 以下三行全部在node01上操作 scp -r ./mashibing/ node02:`pwd` # node02 scp -r ./mashibing/ node03:`pwd` # node03 scp -r ./mashibing/ node04:`pwd` # node04# 或者,如果你沒有添加IP地址與主機名映射的話,直接使用ip地址拷貝也行 # 以下三行全部在node01上操作 # scp -r ./mashibing/ 10.0.0.132:/opt # node02 # scp -r ./mashibing/ 10.0.0.133:/opt # node03 # scp -r ./mashibing/ 10.0.0.134:/opt # node04# 像node01那樣,分別配置另外三個node的myid,并cat輸出驗證 mkdir -p /var/mashibing/zk && echo 2 > /var/mashibing/zk/myid && cat /var/mashibing/zk/myid # 在node02上操作 mkdir -p /var/mashibing/zk && echo 3 > /var/mashibing/zk/myid && cat /var/mashibing/zk/myid # 在node03上操作 mkdir -p /var/mashibing/zk && echo 4 > /var/mashibing/zk/myid && cat /var/mashibing/zk/myid # 在node04上操作7、檢查四臺機器的時間是否一致
檢查一下date
8、配置ZK的環(huán)境變量
# 在 /etc/profile 最后面追加 ZOOKEEPER 的環(huán)境變量 vi /etc/profile# 之前配的java environment export JAVA_HOME=/usr/java/jdk1.8.0_251 export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar #export PATH=$PATH:${JAVA_HOME}/bin#zookeeper 注意CentOS7要加花括號,像下面這樣 export ZOOKEEPER_HOME=/opt/mashibing/apache-zookeeper-3.6.1-bin export PATH=$PATH:${JAVA_HOME}/bin:${ZOOKEEPER_HOME}/bin# 重新加載配置文件 source /etc/profile配置好之后,你在任何地方使用:
zk+tab鍵,就可以自動補全zk的指令了
同樣的,把每個節(jié)點的環(huán)境變量遠程同步一下
# 以下三行全部在node01上操作 scp -r /etc/profile node02:/etc # node02 scp -r /etc/profile node03:/etc # node03 scp -r /etc/profile node04:/etc # node04然后在4臺機器上都執(zhí)行一下source /etc/profile,讓環(huán)境變量生效
9、啟動ZK
zkServer.sh start-foregroundzkServer.sh status查看當前機器上zk的狀態(tài)(leader或者follower)
啟動起來了,我們看到node01是leader,另外三臺是follower
10、使用客戶端連接
# 使用客戶端連接,默認連接的是本機的zk zkCli.sh(1) create創(chuàng)建節(jié)點
參數(shù):create [-s] [-e] [-c] [-t ttl] path [data] [acl]
創(chuàng)建節(jié)點,-s表示順序,-e表示臨時,默認是持久節(jié)點,acl缺省表示不做任何權(quán)限限制
zk的增刪改寫操作都是交給leader,leader單機維護一個單調(diào)遞增的計數(shù)器,你會看到64字節(jié)的一個事務(wù)id:cZxid,前面32位全是0的時候省略不寫,用于標識leader的紀元。如果leader更新?lián)Q代,新的leader會自動將事務(wù)id重新開始,并且修改事務(wù)id的前綴。
(2)創(chuàng)建臨時節(jié)點 示例:create -e /ephemeraltest ephemeraltestdata
臨時節(jié)點是和session綁定的,session也是實現(xiàn)了統(tǒng)一視圖,是要消耗事務(wù)id的。
create /abc
“統(tǒng)一視圖”不僅是針對節(jié)點,而且針對sessionid。每一個客戶端連接進服務(wù)端之后,都會給它分配一個sessionid,而這個sessionid與臨時節(jié)點是綁定的:session退出之后,臨時節(jié)點也就不再保留了。那么問題來了,如果客戶端連接的這個服務(wù)端掛了,那么客戶端fail over重新連接到其他的服務(wù)端之后,之前創(chuàng)建的臨時節(jié)點還存在嗎?
答案是存在。因為“統(tǒng)一視圖”不僅是針對節(jié)點,而且針對sessionid。
客戶端連接進來之后,自動給它創(chuàng)建的sessionid:
這個sessionid也會消耗一個事務(wù)id、使事務(wù)id遞增,由leader將這個sessionid同步到每一個節(jié)點上。
客戶端斷開的時候,也需要同步一下數(shù)據(jù),所以也會消耗一個事務(wù)id。
(3)創(chuàng)建順序節(jié)點 示例create /student/age 會返回給你 Created /abc/age0000000001
使用create -s,zk自動幫你保證節(jié)點之間的區(qū)分,可以讓每一個客戶端拿到的節(jié)點名稱不會重復(fù)。
類似于分布式id,節(jié)點名稱是全局唯一的。
你只需要拿到返回值,記住你自己的節(jié)點名稱就可以了。
可以做隔離,統(tǒng)一命名。
附:簡版簡單筆記
節(jié)點間通信原理
任意兩個節(jié)點之間,只要有一個(socket)連接,就可以實現(xiàn)雙向通信。
以node04是leader的情況為例
節(jié)點間連接情況如下
使用 netstat -natp | egrep '(2888|3888)' 查看
今天就講到這里,下節(jié)課我們講Paxos~
總結(jié)
以上是生活随笔為你收集整理的ZooKeeper实战(一):ZooKeeper原理,详细安装步骤,基本命令,节点间通信原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HotSpot源码(二):Java与C语
- 下一篇: leetcode 121. 买卖股票的最