文章目錄
- zookeeper環境搭建
- linux下jdk環境搭建
- 一、安裝jdk
- jdk1.8.0_211鏈接
- zookeeper鏈接,新版本只有帶bin的是編譯過的更是我們需要的,另一個版本只是源碼
- 1、將jdk和zookeeper通過ftp轉移到linux /home下
- 2、解壓jdk和zookeeper到/usr/和/usr/local下
- 2、配置jdk和zookeeper環境變量
- 二、zookeeper配置文件
- 三、啓動zookeeper
- 3-1 zk數據模型介紹
- 3-2 zookeeper數據模型的基本操作
- 3-3 zookeeper的作用
- 4-1 zookeeper的常用命令
- 4-2 session的基本原理
- 4-3 zk特性 watcher機制
- 4-4 父節點watcher事件
- 4-5 子節點watcher事件
- 4-6 watcher使用場景
- 4-7 權限ACL
- 4-8 acl的構成 permission的構成
- 4-9 acl的命令行 world講解
- 4-10 acl命令行 auth講解
- 4-11 acl命令行 digest講解
- 4-11 acl命令行 ip講解
- 4-12 acl之super超級管理員
- 4-13 acl的常用場景
- 4-14 zk四字命令 Four letter words
- 5-1 zookeeper集羣搭建
- 5-2 單機僞分佈式集羣
- 創建額外的兩個zookeeper節點
- 修改配置文件
- /usr/local/zookeeper/conf/zoo.cfg
- 添加配置文件myid
- /usr/local/zookeeper01/conf/zoo.cfg
- 添加配置文件myid
- /usr/local/zookeeper02/conf/zoo.cfg
- 添加配置文件myid
- 節點創建配置完畢之後歐需要依次啓動三個節點的zookeeper服務器
- 驗證集羣是否配置成功:
- 5-3 三臺物理機(虛擬機)安裝zookeeper
- 6-1 客戶端與zk服務器的連接& zk會話重連機制
- 6-2 創建節點
- 6-3 修改節點數據
- 6-4 刪除節點
- 6-5 CountDownLatch的介紹
- 6-6 節點查詢
zookeeper環境搭建
linux下jdk環境搭建
一、安裝jdk
jdk1.8.0_211鏈接
zookeeper鏈接,新版本只有帶bin的是編譯過的更是我們需要的,另一個版本只是源碼
1、將jdk和zookeeper通過ftp轉移到linux /home下
2、解壓jdk和zookeeper到/usr/和/usr/local下
解壓jdk和zookeeper
tar -zxvf ....jdk
tar -zxvf ...zookeeper
修改解壓之後的jdk和zookeeper的名字
mv XXX jdk8
mv YYY zookeeper
轉移jdk和zookeeper
mv jdk8 /usr
mv zookeeper /usr/local
2、配置jdk和zookeeper環境變量
修改配置文件 vim /etc/profile
export JAVA_HOME=/usr/jdk8
export ZOOKEEPER_HOME=/usr/local/zookeeper
export CLASSPATH=.:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin
配置完環境變量測試一下是否成功
測試之前先刷新配置文件
source /etc/profile
//測試
java -version
二、zookeeper配置文件
複製zookeeper/conf/zookeeper.cfg文件
cp zookeeper.cfg zoo.cfg
1、tickTime
Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔。 也就是每隔 tickTime 時間就會發送一個心跳。以毫秒爲單位,比如session超時 N*tickTime
2、initLimit
用於集羣,允許從節點鏈接並同步到master節點的初始化連接時間,以tickTime的倍數來表示。
3、syncLimit
用於集羣,master主節點與從節點之間發送消息,請求和應答時間長度(心跳機制),超時從節點就會被拋棄
4、dataDir
必須配置
但是不能配置到臨時文件夾裏面
dataDir=/tmp/zookeeper
修改爲
dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir
5、dataLogDir
日誌目錄,如果不配置會和dataDir公用
6、clientport
連接服務器的端口,默認2181
三、啓動zookeeper
//啓動
./zkServer.sh start
//重啓,現關閉再開啓
./zkServer.sh restart
//查看狀態
./zkServer.sh status
3-1 zk數據模型介紹
1、樹形結構
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ygF1mlkK-1575608668526)(en-resource://database/1749:1)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-djztQuLN-1575608668527)(en-resource://database/1751:1)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Vc99c9ml-1575608668528)(en-resource://database/1753:1)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YGV94rXQ-1575608668528)(en-resource://database/1755:1)]
3-2 zookeeper數據模型的基本操作
- 客戶端連接
./zkCli.sh打開命令行後臺
連接到Connecting to localhost:2181
Ctrl+C退出當前客戶端 - 查看znode結構
- 關閉客戶端連接
3-3 zookeeper的作用
1、高可用,當master掛了之後,後續的從節點就會替補上去,不讓讓系統崩掉,這也叫做首腦模式,保證集羣的高可用,高可用的體現之一,局長死了,副局長立馬頂上
2、統一配置文件管理,只需要部署一臺服務器,則可以吧相同的配置文件同步更新到其他服務器,此操作在雲計算中非常多(假設修改了redis統一配置)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZGMp7qyF-1575608668529)(en-resource://database/1757:1)]
3、發佈與訂閱,例如消息隊列MQ,發佈者將信息發佈到節點,二訂閱了節點的訂閱者就會收到這個信息,相應的進行改變
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Ic7PjXA0-1575608668530)(en-resource://database/1759:1)]
4、提供分佈式鎖,分佈式環境中,不同進程的資源爭搶,類似以多線程中的鎖(爲什麼zookeeper能提供分佈式鎖呢,歸因於zookeeper的結構,在zookeeper的結構中,增加節點是往後續的,即一個個增加在後面,類似於隊列,所以第一個就是相當於master,這個唯一就是鎖)
5、集羣管理,集羣保證數據的強一致性
比如客戶端連接了主節點,並且增加數據Data-XYZ,那麼由於集羣的機制會進行同步,那麼從節點酒也有了這個數據,客戶端斷開之後,連接其他節點也會讀到相同的信息(類似於2統一文件-配置)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xgLMpyzY-1575608668530)(en-resource://database/1761:1)]
4-1 zookeeper的常用命令
- ./zkCli.sh 打開命令行後臺
- ls和ls2
ls查看目錄 ls /zookeeper
ls2是查看節點狀態信息 ls2 /
ls2相當於ls和stat - stat 查看狀態信息
- get 當前節點的數據取出來
czxid 節點創建的id
ctime 節點創建的時間
mzxid 節點修改的id
mtime 節點修改的時間
pzxid 子節點的id
cversion 子節點的版本
dataVersion 數據的版本
aclVersion 節點權限修改的版本
ephemeralOwner 之後再說
dataLength 數據長度
numChildren 下面子節點的個數
4-2 session的基本原理
基本原理一
- 客戶端與服務器之間的連接存在會話
- 每個會話都會可以設置一個超時時間
- 心跳結束,則Session過期
因爲每個心跳都會向服務器發送一個(ping包?)信息,從而保證服務器知道session還活着
基本原理二
- Session過期,則臨時節點znode會被拋棄
- 心跳機制:客戶端向服務器的ping包請求
創建節點
創建默認節點(持久存在)
create /imooc immoc-data
創建臨時節點(斷開連接後,心跳結束不存在)
cerate -e /imooc/tmp tmp-data
如何識別是臨時節點?
不是臨時節點:ephemeralOwner=0x0
是臨時節點::ephemeralOwner=0x0…
當zookeeper連接關閉時,臨時節點不會立馬被刪除,臨時節點默認存在一個心跳時間,等這個時間過後纔會被刪除
創建順序節點(持久存在)
create -s /immoc/seq seq-data
ls /imooc
[seq0000000001]
創建的順序節點從1開始
create -s /imooc/seq seq-data
ls /imooc
[seq0000000001, seq0000000002]
創建時節點序號是依次遞增的
修改節點
set [-s] [-v version] path data
set /imooc new-data 修改之後,mtime、dataVersion、dataLength就會發生變化
dataVersion遞增1
在指定版本號的節點,進行修改的情況
①、set -v 1 /imooc new
②、set -v 1 /imooc new
發生錯誤version No is not valid : /imooc
原因是①更新節點之後,dataVersion自增1變爲了2,②更新的時候版本號已經不是1了,所以纔會導致版本號不可校驗,這可以做到樂觀鎖的效果,所以在併發的時候,由於版本號的問題,就不會導致併發錯誤
所以只能修改最新版本號的節點(不加版本號,默認修改最新版本的節點),修改其他版本的節點,就會出錯
刪除節點
delete [-v version] path
其他問題同上述修改節點
4-3 zk特性 watcher機制
一:
- 針對每個節點的操作,都會有一個監督者→watcher
- 當監控的某個對象(znode)發生變化,則觸發watcher事件
- zk中的watcher是一次性的,觸發後立即銷燬
二:
- 父節點、子節點都能觸發watcher
- 針對不同的操作,watcher能表現不同的反應
(子)節點刪除事件
(子)節點修改事件
(子)節點變化事件
當(子)節點發生變化時,觸發watcher相應的事件,客戶端在收到這個事件之後,比對事件名,然後做出自己的操作,比如節點發出刪除事件,watcher發送給客戶端,客戶端接收到這個事件之後,匹配成功,然後再刪了與這個節點的連接
4-4 父節點watcher事件
- 創建父節點觸發:NodeCreate
使用 stat [-w] path 爲節點添加watcher
增加imooc節點的watcher
stat -w /imooc
創建/imooc節點
create /imooc watcher-test
WATCHER::WatchedEvent state:SyncConnected type:NodeCreated path:/imooc
- 修改父節點數據觸發:NodeDataChanged
使用 get -w path爲節點添加watcher
get -w /imooc
set /imooc new-data
WATCHER::WatchedEvent state:SyncConnected type:NodeDataChanged path:/imooc
- 刪除父節點觸發:NodeDeleted
使用 get -w path爲節點添加watcher
get -w /imooc
delete /imooc
WATCHER::WatchedEvent state:SyncConnected type:NodeDeleted path:/imooc
4-5 子節點watcher事件
- ls爲父節點(必須先存在父節點)設置watcher,創建子節點觸發:NodeChildrenChanged
- ls爲父節點設置watcher,刪除子節點觸發:NodeChildrenChanged
- ls爲父節點設置watcher,修改子節點不觸發事件
如果需要讓子節點觸發事件,那麼就需要在這各自節點上設置watcher事件,觸發NodeChanged事件
4-6 watcher使用場景
統一資源配置
4-7 權限ACL
ACL(Access control lists)權限控制
- 針對節點可以設置相關讀寫等權限,目的是爲了保證數據安全性
- 權限permissions可以指定不同的權限範圍以及角色
ACL命令行
- getAcl 得到某個節點路徑的acl權限信息
getAcl path - setAcl 設置某個節點路徑的acl權限
setAcl path acl - addauth 輸入認證授權信息,註冊時輸入明文密碼(登錄)但是在zk的系統中,密碼是以加密的形式存在的
addauth scheme auth
ASL的構成一
- zk的acl是通過[scheme🆔permission]來構成權限列表
scheme:權限模式,代表採用的某種權限機制,五種(常用四種)
id:代表允許訪問的用戶
permission:權限組合字符串
ACL的構成二 - Scheme
- world:world下只有一個id,那就是anyone,組合寫法就是world:anyone:[permissions]
- auth:代表認證登錄,需要註冊用戶有權限就可以,形式爲:auth:user:password:[permissions]
- digest:需要對密碼加密才能訪問,組合格式爲digest:username:BASE64(SHA1(password)):[permissions]
auth與digest的區別就是:一個明文、一個密文、需要不同的訪問方式
setAcl /path auth:lee:lee:cdrwa
setAcl /path digest:lee:BASE64(SHA1(lee)):cdrwa
一般auth用的不多,因爲生產環境總是要加密的
addauth digest lee:lee 後都能操作指定節點的權限
4. ip:當設置爲ip指定的ip地址,此時限制ip進行訪問,比如ip:192.168.1.1:[permissions]
因爲用的是集羣,那麼比如一個訂單服務的ip是192.168.1.1,還有一個是192.168.1.2那麼只有這兩個ip可以訪問這個節點,其他的比如報賬服務就不能訪問這個節點
5. super:代表超級管理員,擁有所有的權限,這個很危險,一般給運維或者研發經理或者CTO,所以一般不用,常用前四個
4-8 acl的構成 permission的構成
權限字符串縮寫:crdwa
- CREATE:創建子節點,不能創建節點
- READ:獲取節點/子節點
- WRITE:設置節點數據
- DELETE:刪除子節點
- ADMIN:設置權限
4-9 acl的命令行 world講解
world:anyone:crawd
設置節點的權限
4-10 acl命令行 auth講解
auth:user:pwd:crawd
digest:userBASE64(SHA1(pwd)):crawd
addauth digest user:pwd
再給節點設置權限時,先登錄,然後再給登錄對象設置權限
addauth digest user:pwd
setAcl path auth:user:pwd:[permissions]
getAcl path
4-11 acl命令行 digest講解
登錄和auth一樣
addauth digest imooc:imocc
setAcl path digest:imooc:(imooc的密文):[permissions]
4-11 acl命令行 ip講解
setAcl path ip:(ip地址):[permissions]
在之後的java客戶端連接中,我們再來演示
4-12 acl之super超級管理員
場景:創建一個ipd能訪問的節點,在這我們使用超級管理員賬號去訪問該節點
創建一個ip能訪問的節點
create /names/ip xxx.xxx.xxx.xxx
setAcl /names/ip ip:xxx.xxx.xxx.xxx:crawd
修改配置文件,添加超級管理員賬號
vim zkServer.sh
在nohup塊中添加超級管理員賬號密碼(密文imooc,經過sha1和base64加密得到XwEDaL3J0JQGkRQzM0DpO6zMzZs=)
“-Dzookeeper.DigestAuthenticationProvider.superDigest=imooc:XwEDaL3J0JQGkRQzM0DpO6zMzZs=”\
重啓zookeeper
./zkServer.sh restart
登錄超級管理員
addauth digest imooc:imooc
getAcl /names/ip
如果沒有登陸,或者登錄的其他賬號,則都不能訪問該節點
4-13 acl的常用場景
- 開發/測試環境分離,開發者無權操作測試庫的節點,只能看
- 生產環境控制指定ip的服務可以訪問相關節點,防止混亂,由於有些是動態ip,有可能有點不方便
4-14 zk四字命令 Four letter words
- zk可以通過它自身提供的簡寫命令來和服務器進行交互
- 需要使用到nc命令 ,安裝yum install nc
- echo [commond] | nc [ip] [port]
【stat】:查看zk的狀態信息,以及是否mode
【ruok】:查看當前zkServer是否啓動,返回imok
【dump】:列出未經處理的會話和臨時節點
【conf】:查看相關配置信息
【cons】:展示連接到客戶端的連接信息i
【envi】:環境變量,jdk,zookeeper等
【mntr】:監控zk的健康信息
【wchs】:展示watch的信息
【wchc與wchp】:session與watch及path與watch信息
注:如果報錯例如:
ruok is not executed because it is not in the whitelist.解決方法請看https://blog.csdn.net/x763795151/article/details/80599498
注:查看zookeeper事務日誌
在配置文件zoo_sample.cfg中,事務日誌和快照日誌,默認在dataDir中
在配置了zoo.cfg之後,事務日誌和快照日誌分離,事務日誌在在我們配置的dataLogDir中
由於事務日誌是二進制數據,因此用vi/vim不能查看得到,因此只能解碼後查看
mkdir /use/log
cd /usr/local/zookeeper/lib
cp slf4j-api.1.7.25.jar zookeeper.3.5.6.jar zookeeper.jute.3.5.6.jar /usr/logjava -classpath .:slf4j-api.1.7.25.jar:zookeeper.3.5.6.jar:zookeeper.jute.3.5.6.jar org.apache.zookeeper.LogFormatter /usr/local/zookeeper/dataLogDir/version-2/log.4e
1.創建一個文件夾log保存我們所需要的jar包
2.切換到zookeeper的lib文件夾下
3.複製所需要jar包到log中
4.編寫解碼信息
/usr/local/zookeeper/dataLogDir/version-2/log.4e
是我們的事務日誌路徑
注:測試ookeeper版本爲3.5.6
1、節點目錄下有子節點,則父節點不能刪除------父節點不能刪除
2、如果節點是在/目錄下且該節點沒有子節點,不管有沒有刪除權限,任何的授權或者未授權用戶都能刪除該節點------根節點若沒有子節點可以隨便刪除
3、如果該節點上一層且只能是上一層父節點,沒有刪除權限,則該節點不能被刪除------本節點的父節點沒有被刪除的權限,則該節點也不能刪除
5-1 zookeeper集羣搭建
zk集羣,主從節點,心跳機制(選舉模式)
zookeeper集羣搭建注意點
1.配置數據文件myid1/2/3對應server.1/2/3
2.通過./zkCli.sh -server [ip]:[port]檢測集羣是否配置成功
5-2 單機僞分佈式集羣
單機的意思是在一臺服務器上創建多個zookeeper節點,ip不見端口不一
創建額外的兩個zookeeper節點
cp zookeeper zookeeper01 -rf
cp zookeeper zookeeper02 -rf
修改配置文件
/usr/local/zookeeper/conf/zoo.cfg
vim /usr/local/zookeeper/conf/zoo.cfg
dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir
clientPort=2181
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890
添加配置文件myid
vim /usr/local/zookeeper/conf/myid
1
/usr/local/zookeeper01/conf/zoo.cfg
vim /usr/local/zookeeper01/conf/zoo.cfg
dataDir=/usr/local/zookeeper01/dataDir
dataLogDir=/usr/local/zookeeper01/dataLogDir
clientPort=2182
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890
添加配置文件myid
vim /usr/local/zookeeper/conf/myid
2
/usr/local/zookeeper02/conf/zoo.cfg
vim /usr/local/zookeeper02/conf/zoo.cfg
dataDir=/usr/local/zookeeper02/dataDir
dataLogDir=/usr/local/zookeeper02/dataLogDir
clientPort=2183
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890
添加配置文件myid
vim /usr/local/zookeeper/conf/myid
3
節點創建配置完畢之後歐需要依次啓動三個節點的zookeeper服務器
cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2181
cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2182
cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2183
驗證集羣是否配置成功:
在一個zookeeper端口創建一個節點/team在另一個zookeeper端口查看是否存在這個節點/team,如果存在就代表配置成功
5-3 三臺物理機(虛擬機)安裝zookeeper
需要克隆三臺虛擬機
將serveer的ip和端口替換即可
zoo.cfg都替換如下列屬性
dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir
clientPort=2181
server.1=192.168.227.131:2888:3888
server.2=192.168.227.132:2888:3888
server.3=192.168.227.133:2888:3888
6-1 客戶端與zk服務器的連接& zk會話重連機制
連不上
//zookeeper的地址
public static final String zkAddress = "192.168.227.131:2181";
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zk = new ZooKeeper(zkAddress, 2000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent)
{
System.out.println("watcher事件:" + watchedEvent.getState().toString());
}
});
long sessionId = zk.getSessionId();
byte[] sessionPwd = zk.getSessionPasswd();
System.out.println("與zookeeper正在連接:" + zk.getState());
//連接過程需要時間
Thread.sleep(2000);
System.out.println("與zookeepeer連接成功:" + zk.getState());
//zk會話重連
zk = new ZooKeeper(zkAddress, 2000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {}
}, sessionId, sessionPwd);
System.out.println("與zookeeper正在連接:" + zk.getState());
Thread.sleep(2000);
System.out.println("與zookeepeer重連成功:" + zk.getState());
}
//控制檯打印
與zookeeper正在連接:CONNECTING
watcher事件:SyncConnected
與zookeepeer連接成功:CONNECTED
watcher事件:Closed
zk狀態:CLOSED
與zookeepeer開始重連...
與zookeeper正在連接:CONNECTING
與zookeepeer重連成功:CONNECTED
如果連接不上zookeeper:請關閉虛擬機防火牆,再次連接
systemctl stop firewalld.service
6-2 創建節點
同步創建:zk.create(path, data, acl, CreateMode);
異步創建:zk.create(path, data, acl, CreateMode, CallBack, ctx);
acl:控制權限策略
Ids.OPEN_ACL_UNSAFE–>world:anyone:crawd
CREATOR_ALL_ACL–>auth:user:password:crawdCreateMode:節點類型:是一個枚舉
PRESISTENT:持久節點
PRESISTENT_SEQUENTIAL:持久順序節點
EPHEMERAL:臨時節點
EPHEMERAL_SEQUENTIAL:臨時順序節點
//同步創建
zk.create("/java", "java".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
//異步創建
zk.create("/sys_java", "sys_java".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new MyCallBack(), ctx);
//執行回調函數需要時間
Thread.sleep(2000);
6-3 修改節點數據
同步方式
setData(path, data, version)
異步方式
setData(path, data, version, CallBack, ctx)
6-4 刪除節點
同步方式
delete(path, data, version)
異步方式
delete(path, data, version, CallBack, ctx)
6-5 CountDownLatch的介紹
線程中的計數器
分佈式鎖中的計數器
- 它是一個計數器,可以累減
- 多用於線程,樂意暫停也可以繼續
- .await() .CountDown()
6-6 節點查詢
//節點查詢有同步查詢有異步查詢,在這裏討論的是同步查詢,異步查詢只不過有個回調函數,返回一些需要的數據,可以自己試試看
//父節點查詢
ZooKeeperServer zooKeeperServer = new ZooKeeperServer(addressPath);
//true表示再次添加watcher監聽,false爲不在添加
byte[] data = zooKeeperServer.getZooKeeperServer().getData("/java", false, stat);
String info = new String(data);
System.out.print(info);
//子節點查詢
List<String> nodeList = zookeeper.getZookeeperServer().getChildren("/java",false,stat);
for(String nodeName : nodeList) {
System.out.print(nodeName);
}