ZooKeeper的定義用一句話就能說清:分布式服務架構 Zookeeper -- 管理分布式環境中的資料。下面從安裝開始,對這個架構進行分析。
1.安裝
1. 官網下載下傳壓縮包并解壓到D:\Program Files (x86)\zookeeper-3.4.12
2. 在D:\Program Files (x86)\zookeeper-3.4.12目錄下建立data和log檔案夾
3. 複制conf目錄下zoo_sample.cfg檔案到同目錄下,重命名為zoo.cfg(Zookeeper 在啟動時會找這個檔案作為預設配置檔案),修改其中的 dataDir 和 dataLogDir 上面建立目錄的路徑

4. 啟動測試一下
服務端啟動
啟動之後,端口檢視可以看到ZooKeeper通過2181端口啟動了一個java服務
啟動用戶端連接配接一下,成功
2. ZooKeeper配置檔案
目前配置檔案zoo.cfg中的内容如下
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=D:\\Program Files (x86)\\zookeeper-3.4.12\\data
dataLogDir=D:\\Program Files (x86)\\zookeeper-3.4.12\\log
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
單機模式下,主要配置項作用:
- tickTime:這個時間是作為 Zookeeper 伺服器之間或用戶端與伺服器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。
- dataDir:顧名思義就是 Zookeeper 儲存資料的目錄,預設情況下,Zookeeper 将寫資料的日志檔案也儲存在這個目錄裡。
- dataLogDir:顧名思義就是 Zookeeper 儲存日志檔案的目錄。
- clientPort:這個端口就是用戶端連接配接 Zookeeper 伺服器的端口,Zookeeper 會監聽這個端口,接受用戶端的通路請求。
3. 叢集模式
ZooKeeper的安裝模式分為三種,分别為:單機模式(stand-alone)、叢集模式和叢集僞分布模式。上面示範的即單機模式;通過多台機器共同提供服務即為叢集模式;一台電腦的話其實還可以進行僞叢集模式,即在一台實體機上運作多個 Zookeeper 執行個體。
叢集模式是通過增加配置檔案zoo.cfg中的配置項來設定,主要配置項如下:
initLimit=10
syncLimit=5
server.1=192.168.211.1:2888:3888
server.2=192.168.211.2:2888:3888
- initLimit:這個配置項是用來配置 Zookeeper 接受用戶端(這裡所說的用戶端不是使用者連接配接 Zookeeper 伺服器的用戶端,而是 Zookeeper 伺服器叢集中連接配接到 Leader 的 Follower 伺服器)初始化連接配接時最長能忍受多少個心跳時間間隔數。當已經超過 10 個心跳的時間(也就是 tickTime)長度後 Zookeeper 伺服器還沒有收到用戶端的傳回資訊,那麼表明這個用戶端連接配接失敗。總的時間長度就是 10*2000=20 秒
- syncLimit:這個配置項辨別 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 5*2000=10 秒
- server.A=B:C:D:其中 A 是一個數字,表示這個是第幾号伺服器;B 是這個伺服器的 ip 位址;C 表示的是這個伺服器與叢集中的 Leader 伺服器交換資訊的端口;D 表示的是萬一叢集中的 Leader 伺服器挂了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時伺服器互相通信的端口。如果是僞叢集的配置方式,由于 B 都是一樣,是以不同的 Zookeeper 執行個體通信端口号不能一樣,是以要給它們配置設定不同的端口号。
除了修改 zoo.cfg 配置檔案,叢集模式下還要配置一個檔案 myid,這個檔案在 dataDir 目錄下,這個檔案裡面就有一個資料就是 A 的值,Zookeeper 啟動時會讀取這個檔案,拿到裡面的資料與 zoo.cfg 裡面的配置資訊比較進而判斷到底是哪個 server。
單機僞叢集模式配置步驟如下:
3.1 配置檔案修改
conf目錄下複制三次zoo.cfg到同目錄下,分别命名zoo1.cfg,zoo2.cfg,zoo3.cfg,對三個檔案進行如下修改
zoo1.cfg
zoo2.cfg
zoo3.cfg
相對應的,需要在各自dataDir下建立myid檔案(無字尾名),内容分别為1,2,3,表示其為第幾号伺服器。
3.2 修改服務端啟動配置
bin目錄下複制三次zkServer.cmd到同目錄下,分别命名zkServer1.cmd,zkServer2.cmd,zkServer3.cmd,對三個檔案進行如下修改
zkServer1.cmd
zkServer2.cmd
zkServer3.cmd
3.3 啟動服務
cmd下啟動三個zkServer,在這裡我是打開三個cmd視窗啟動的,順序1-2-3,三個zkServer沒全啟動的時候會報如下錯誤,這是zookeeper的Leader選舉算法的異常資訊,當節點沒有啟動完畢的時候,Leader無法正常進行工作,這種錯誤資訊是可以忽略的,等其他節點啟動之後就正常了。
三個端口全部啟動
4. java連接配接測試
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
public class WatcherTest implements Watcher{
public void process(WatchedEvent arg0){
System.out.println("========================");
System.out.println("path:"+arg0.getPath());
System.out.println("type:"+arg0.getType());
System.out.println("state:"+arg0.getState());
}
}
建立ZooKeeper執行個體時,如果有多個連接配接,則使用逗号隔開。
import java.io.IOException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import com.zang.WatcherTest;
public class App
{
public static void main( String[] args ) throws IOException, KeeperException, InterruptedException {
//建立一個Zookeeper執行個體,第一個參數為目标伺服器位址和端口,第二個參數為Session逾時時間,第三個為節點變化時的回調方法
ZooKeeper zk = new ZooKeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183", 30000, new WatcherTest());
String node = "/node2";
Stat stat = zk.exists(node, false);
if(null == stat){
//建立一個節點,資料為test,不進行ACL權限控制,節點為永久性的
String createResult = zk.create(node, "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(createResult);
}
//取得/node2/test節點下的資料,傳回byte[]
byte[] b = zk.getData(node, false, stat);
System.out.println(new String(b));
zk.close();
}
}
參考:https://blog.csdn.net/qiunian144084/article/details/79192819
https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/