目錄
4.1 ZooKeeper的核心概念
4.1.1Session回話機制
4.1.2資料節點、版本與Watcher的關聯
4.1.3ACL策略
4.2 ZooKeeper的安裝與運行
4.2.1 創建ZooKeeper檔案夾
4.2.2 拖拽檔案進虛擬機并解壓
4.2.3配置ZooKeeper
(1)復制并重命名檔案
(2)編輯zoo.cfg
(3)復制ZooKeeper檔案夾到其他節點上
(4)創建myid檔案
(5)配置環境變數(3臺機器)
(7)啟動ZooKeeper服務(3臺服務器)
4.3 ZooKeeper服務端的常用命令
4.4 客戶端鏈接ZooKeeper的相關操作
4.4.1查看ZooKeeper常用命令
4.4.2connect命令與ls命令
4.4.3create命令--創建節點
4.4.4get命令--獲取資料與資訊
4.4.5set命令--修改節點內容
4.4.6delete命令--洗掉節點
5.5 使用Java API訪問ZooKeeper
5.5.1環境準備與創建會話實體
(1)匯入jar包
(2)添加一個log4j.properties檔案,里面內容如下
(3)創建zookeeper實體
(4)運行主方法
5.5.2JAVA API 訪問ZooKeeper實體
(1)創建java_zookeeper.java檔案
(2)撰寫代碼
(3)運行結果
ZooKeeper在分布式應用中提供了諸如統一命名服務、配置管理和分布式鎖的基礎,成為高效、穩健的分布式協調服務,另外,在分布式資料一致的情況下,ZooKeeper采用一種被稱為ZAB(ZooKeeper Automic Broadcast)的一致性協議,
4.1 ZooKeeper的核心概念
在分布式系統構建的集群中,每臺機器都有自己的角色定位,其中最經典的是Master/Slave模式,在這種模式中,所有寫操作的機器都可以稱為Master機器;所有通過異步復制方式獲取最新資料并提供讀服務的機器都可以稱為Slave機器,
除Leader外,其他機器包括Follower和Observer都能夠提供讀服務,唯一不同的是,Leader選舉程序和寫操作的“過半寫功能”策略--Observer都是不參與的,所以在不影響寫性能的情況下,Observer可以提升集群的讀性能,接下來我們介紹ZooKeeper的核心概念,
4.1.1Session回話機制
在ZooKeeper中,當客戶端與服務器端成功建立鏈接后,Session會話會隨之建立,同時會生成一個全域唯一的會話ID(Session ID),在ZooKeeper中,一個客戶端鏈接是指客戶端和服務器之間的一個TCP長鏈接,
ZooKeeper對外的服務埠默認是2181,當客戶端啟動時,新建立的TCP鏈接也將第一次啟動,他能通過心跳檢測與服務器保持有效會話,同時還會向ZooKeeper發送請求并接收回應,另外還能夠接收來自服務器的Watch事件通知,
Session的SessionTimeout值用來設定一個客戶端會話的超時時間,當出現故障而又想要保存之間創建的會話時,只需在SessionTimeout規定的時間內重新連接上集群的任意一臺服務器即可,
4.1.2資料節點、版本與Watcher的關聯
在ZooKeeper中,“節點”是指資料模型中的資料單元,也叫資料節點--Znode
資料模型是以數(Znode Tree)的格式進行存盤,并通過斜杠(/)來分割路徑,分割后的每一個Znode都會保存自己的資料內容,同時還會保存一系列屬性值,如zoo/path,
ZooKeeper的每一個Znode都對對應一個叫做Stat的資料結構,而Stat記錄了version(當前Znode的版本)、cversion(當前Znode子節點的版本)和aversion(當前Znode的ACL版本)當前的3個資料版本,
當用戶在ZooKeeper中注冊一些Watcher(時間監聽器)后,在一些特定時間觸發的情況下,ZooKeeper將會把時間通知發送到感興趣的客戶端上,這是ZooKeeper分布式協調服務的重要特性,
4.1.3ACL策略
ZooKeeper的權限控制系統類似于UNIX檔案系統,它采用的是ACL(Access Control Lists)策略,
ZooKeeper定義列如下5種權限,
CREATE:創建子節點的權限,
READ:獲取節點資料和子節點的權限,
WRITE:更新節點資料的權限
DELETE:洗掉節點的權限
ADMIN:設定節點ACL的權限
4.2 ZooKeeper的安裝與運行
安裝ZooKeeper需要JDK安裝,第2章的時候我們已經安裝了,沒有的回傳去看,
4.2.1 創建ZooKeeper檔案夾
在虛擬機的/usr/local/目錄下創建zookeeper
mkdir /usr/local/zookeeper
4.2.2 拖拽檔案進虛擬機并解壓
如何拖拽,就跟第2章搭建hadoop時一樣,

進入zookeeper檔案夾進行解壓,解壓完成之后洗掉安裝包,
tar -zxvf zookeeper-3.4.9.tar.gz #解壓安裝包
rm -rf zookeeper-3.4.9.tar.gz #洗掉安裝包
4.2.3配置ZooKeeper
進入zookeeper/conf檔案夾下,進行配置,
(1)復制并重命名檔案
cp zoo_sample.cfg zoo.cfg
(2)編輯zoo.cfg
在/usr/local/zookeeper/zookeeper-3.4.9 檔案下創建data檔案夾
mkdir data
vim zoo.cfg
在/usr/local/zookeeper/zookeeper-3.4.9 檔案下創建data檔案夾

該配置中,tickTime屬性指定了ZooKeeper中的基本時間單元,dataDir屬性指定了ZooKeeper存盤持久資料的本地檔案系統設定,clientPort屬性指定列ZooKeeper用于監聽客戶端鏈接的埠,
initLimit引數設定列所有更隨著與Leader節點進行鏈接并同步的時間范圍,如果在設定的時間段內,半數以上的跟隨者未能完成同步,Leader節點便回旋不放棄Leader的地位,然后進行另外一次Leader選舉,
如果這種情況經常發生,則表明設定的值太小,syncLimit引數設定列允許一個Follower與Leader進行同步的時間,其中那3個IP分別代表三個節點的IP地址,
(3)復制ZooKeeper檔案夾到其他節點上
提醒一點,這個復制是在 、usr/local/zookeeper檔案夾下
scp -r zookeeper-3.4.9 hadoo4:$PWD
scp -r zookeeper-3.4.9 hadoo6:$PWD
(4)創建myid檔案
在三個節點下的zookeeper/data檔案夾下分別創建myid檔案,并寫入數字1、2、3,192.168.252.14寫入1,其他類推,
(5)配置環境變數(3臺機器)
vim /etc/profile

這里面添加了ZOOKEEPER_HOME,和在PATH后面添加了ZOOKEEPER/bin,三臺機器都得修改環境變數,(也可以配置好一臺復制給其他兩臺)
然后生效環境變數
(7)啟動ZooKeeper服務(3臺服務器)
進入/usr/local/zookeeper/zookeeper-3.4.9/bin
4.3 ZooKeeper服務端的常用命令
./zkServer.sh start #啟動
./zkServer.sh status #查看狀態
./zkServer.sh stop #停止
./zkServer.sh restart #重啟
4.4 客戶端鏈接ZooKeeper的相關操作
現在我們就可以通過客戶端鏈接到ZooKeeper了,鏈接方式可以使用bin目錄下的zkCli.sh命令,連接格式是 zkCli.sh -server IP:port,比如,現在要鏈接本機的2181埠,代碼如下
./zkCli.sh -server 127.0.0.1:2181 #大家可以嘗試別的虛擬機鏈接例如我下面的用hadoop4連接hadoop
在hadoop4 的bin下
./zkCli.sh -server 192.168.252.15:2181

4.4.1查看ZooKeeper常用命令
一旦鏈接到ZooKeeper上就可以通過相關命令進行操作了,可以通過help命令查看有哪些命令,具體如下:

通過這些命令,我們就可以實作對ZooKeeper的操作了,這里的操作都是對ZooKeeper的節點進行操作,比如列出節點、創建節點和洗掉節點,可以吧ZooKeeper理解為一下結構
4.4.2connect命令與ls命令
connect命令用于鏈接ZooKeeper服務器端,比如通過connect 127.0.0.1:2181,可以鏈接到本地的2181埠(我們現在已經處于連接狀態了),大家也可以嘗試其他虛擬的埠,
ls命令格式:ls path ,表示列出path下的檔案
ls命令用于獲取路徑下的節點資訊,需要注意的是該路徑為絕對路徑
比如:ls/ 可以列出根目錄下的所有檔案,從下面的運行結果可以看出根目錄下有一個zookeeper節點,想要列出zookeeper下的資訊,需要用到絕對路徑,

4.4.3create命令--創建節點
create命令格式如下:
create [-s] [-e] path data acl
其中-s和-e引數分別指定節點為持久節點或臨時節點,在不指定的情況下,則表示是持久節點:acl用來進行權限控制,如果是臨時節點,會話關閉后節點也就不存在列,比如 create/mynode1 content1 命令來創建mynode1節點,并給mynode1賦值content1:
![]()
4.4.4get命令--獲取資料與資訊
get命令用于獲取zookeeper節點的資料內容和相關資訊,比如我們要取得mynode1的內容,執行get/mynode1命令后,運行結果是節點的資料內容content1和此節點的相關匹配資訊,

4.4.5set命令--修改節點內容
set命令格式如下:
set path data
set命令用于修改節點內容,其中data引數是需要更新的內容,在這里第一次把mynode1的內容修改為content2,第二次修改為content3,具體代碼如下


通過運行結果回發現,在運行set /mynode1 content2 后,dataVersion=1,運行完set /mynode1 content3后,dataVersion=2,
修改完后,通過get命令查看結果,發現內容已經變成了content3

4.4.6delete命令--洗掉節點
delete命令格式如下:
delete path [version]
通過delete命令可以洗掉ZooKeeper上的指定節點,

5.5 使用Java API訪問ZooKeeper
5.5.1環境準備與創建會話實體
在IDEA創建一個專案,然后目錄如下,這里面的out是運行后才有的,log4j.properties是后面加進去的,src下面的zookeeper包是新建的,zookeeper檔案也是新建的,

(1)匯入jar包
創建完成之后,我們需要先匯入jar包,點擊IDEA左上角File--》Project Structure

我們需要把本地hadoop/share/hadoop/common下的3個jar包和lib里面的jar包匯入,這個是本地的hadoop檔案里面的大家可以翻看第3章的回顧一下找一下位置

(2)添加一個log4j.properties檔案,里面內容如下
log4j.rootLogger=INFO,console,dailyFile
# TODO 發布到阿里云記得添加,另外控制臺不輸出(只輸出warn或者error資訊)
# log4j.logger.org.mybatis = INFO
log4j.logger.com.imooc.mapper=INFO
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.encoding=UTF-8
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%l] - [%p] %m%n
# 定期滾動日志檔案,每天都會生成日志
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.encoding=UTF-8
log4j.appender.dailyFile.Threshold=INFO
# TODO 本地日志地址,正式環境請務必切換為阿里云地址
log4j.appender.dailyFile.File=C:/logs/maven-ssm-alipay/log.log4j
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%l] - [%p] %m%n
(3)創建zookeeper實體
在zookeeper.java 檔案中寫入下面代碼,這里面有個30000,這是會話連接超時時間設定,我們最好去我們虛擬機里面的zoo.cfg中把這個也改成30000,避免連接超時錯誤,
package zookeeper;
import org.apache.zookeeper.*;
public class zookeeper {
public static void main(String[] args) throws Exception {
// 初始化 ZooKeeper實體(zk地址、會話超時時間,與系統默認一致、watcher)
ZooKeeper zk = new ZooKeeper("192.168.252.15:2181", 30000, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("事件型別為:" + event.getType());
System.out.println("事件發生的路徑:" + event.getPath());
System.out.println("通知狀態為:" + event.getState());
}
});
zk.close();
}
}
(4)運行主方法
得到下面結果:

不要以為沒連接上吼,大家看看我虛擬機連接本地埠的資訊就知道了,看下圖的最后一行,

5.5.2JAVA API 訪問ZooKeeper實體
(1)創建java_zookeeper.java檔案

(2)撰寫代碼
package zookeeper;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
public class java_zookeeper implements Watcher {
private static final int SESSION_TIMEOUT=30000;
public static ZooKeeper ZooKeeper1;
public static void main(String args[]){
String path = "/zknode10";
try {
ZooKeeper1 = new ZooKeeper("192.168.252.15:2181",SESSION_TIMEOUT,new java_zookeeper());
ZooKeeper1.exists(path,true);
//創建節點
ZooKeeper1.create(path,"mycontent1".getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
Thread.sleep(3000);
//得到節點內容
byte[] bytes1 = ZooKeeper1.getData(path,null,null);
String result = new String(bytes1);
System.out.println("result:"+result);
//設定節點
ZooKeeper1.setData(path,"testSetData000".getBytes(),-1);
//再次得到節點內容
byte[] bytes2 = ZooKeeper1.getData(path,null,null);
String result2 = new String(bytes2);
System.out.println("result:"+result2);
//洗掉節點
ZooKeeper1.delete(path,-1);
ZooKeeper1.close();
} catch (Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void process(WatchedEvent event){
if (KeeperState.SyncConnected == event.getState()){
if (EventType.NodeCreated == event.getType()){
//當節點創建成功時進行回呼,此處進行提示列印
System.out.println("Node created success");
try{
ZooKeeper1.exists(event.getPath(),true);
}catch (KeeperException | InterruptedException e){
e.printStackTrace();
}
}else if (EventType.NodeDeleted == event.getType()){
try {
ZooKeeper1.exists(event.getPath(),true);
}catch (KeeperException | InterruptedException e){
e.printStackTrace();
}
System.out.println("Node deleted success");
}else if (EventType.NodeDataChanged == event.getType()){
try {
ZooKeeper1.exists(event.getPath(),true);
}catch (KeeperException | InterruptedException e){
e.printStackTrace();
}
System.out.println("Node changed success");
}
}
}
}
(3)運行結果

(4)注意事項

當大家寫到右下角的那個new java_zookeeper()的時候會有一個錯誤提示,不要管,堅持把代碼寫完(寫完你會 發現下面的那個回呼的時候@Override也有錯誤),寫完后在new java_zookeeper()提示的小燈泡 點擊那個黃色/紅色的小燈泡然后make···什么來著我給忘記了,大家試試
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/301902.html
標籤:其他
