1.Zookeeper應用場景## 2.Zookeeper數據結構
3.Zookeeperan安裝
1.上傳zk並且解壓
cd /usr/local/
tar -zxvf zookeeper-3.4.6.tar.gz
mv zookeeper-3.4.6 zookeeper
2.修改zookeeper環境變量
vi /etc/profile
export ZOOKEEPER_HOME=/usr/local/zookeeper
source /etc/profile
3.修改zoo_sample.cfg文件
cd /usr/local/zookeeper/conf
mv zoo_sample.cfg zoo.cfg
修改conf: vi zoo.cfg
dataDir=/usr/local/zookeeper/data(注意同時在zookeeper創建data目錄)
4.啓動zookeeper
路徑:cd /usr/local/zookeeper/bin
執行:./ zkServer.sh start
查詢狀態: ./zkServer.sh status
4.Java操作Zookeeper
Zookeeper說明
創建節點(znode) 方法:
create:
提供了兩套創建節點的方法,同步和異步創建節點方式。
同步方式:
參數1,節點路徑《名稱) : InodeName (不允許遞歸創建節點,也就是說在父節點不存在
的情況下,不允許創建子節點)
參數2,節點內容: 要求類型是字節數組(也就是說,不支持序列化方式,如果需要實現序
列化,可使用java相關序列化框架,如Hessian、Kryo框架)
參數3,節點權限: 使用Ids.OPEN_ACL_UNSAFE開放權限即可。(這個參數一般在權展
沒有太高要求的場景下,沒必要關注)
參數4,節點類型: 創建節點的類型: CreateMode,提供四種首點象型
PERSISTENT 持久化節點
PERSISTENT_SEQUENTIAL 順序自動編號持久化節點,這種節點會根據當前已存在的節點數自動加 1
EPHEMERAL 臨時節點, 客戶端session超時這類節點就會被自動刪除
EPHEMERAL_SEQUENTIAL 臨時自動編號節點
Watcher
在ZooKeeper中,接口類Watcher用於表示一個標準的事件處理器,其定義了事件通知相關的邏輯,包含KeeperState和EventType兩個枚舉類,分別代表了通知狀態和事件類型,同時定義了事件的回調process(WatchedEvent event)。
什麼是Watcher接口?
同一個事件類型在不同的通知狀態中代表的含義有所不同,列舉了常見的通知狀態和事件類型。
Watcher通知狀態與事件類型一覽
ZooKeeper創建修改刪除節點實現
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @author Administrator
*/
public class ZooKeeperTest {
/**
* 連接地址
*/
private static final String ZOOKEEPER_ADDRESS = "192.168.223.120:2181";
/**
* session 會話
*/
private static final int SESSION_OUT = 30000;
/**
* 信號量,阻塞程序執行,用戶等待zookeeper連接成功,發送成功信號,
*/
private static CountDownLatch countDownLatch = new CountDownLatch(1);
/**
* 創建節點路徑
*/
private static String LOG_MAIN = "/rootNode";
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zooKeeper = new ZooKeeper(ZOOKEEPER_ADDRESS, SESSION_OUT, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
// 通知狀態
Event.KeeperState keeperState = watchedEvent.getState();
// 事件類型
Event.EventType eventType = watchedEvent.getType();
// 獲取Zk路徑
String path = watchedEvent.getPath();
if (Event.KeeperState.SyncConnected == keeperState) {
if (Event.EventType.None == eventType) {
countDownLatch.countDown();
System.out.println("已經建立了連接");
} else if (Event.EventType.NodeCreated == eventType) {
System.out.println("節點創建:" + path);
} else if (Event.EventType.NodeDataChanged == eventType) {
System.out.println("節點修改:" + path);
} else if (Event.EventType.NodeDeleted == eventType) {
System.out.println("節點刪除:" + path);
}
}
}
});
countDownLatch.await();
createRootPath(zooKeeper);
setRootPath(zooKeeper);
deleteRootPath(zooKeeper);
}
public static void createRootPath(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
/**
* CreateMode四種節點類型
* PERSISTENT 持久化節點
* PERSISTENT_SEQUENTIAL 順序自動編號持久化節點,這種節點會根據當前已存在的節點數自動加 1
* EPHEMERAL 臨時節點, 客戶端session超時這類節點就會被自動刪除
* EPHEMERAL_SEQUENTIAL 臨時自動編號節點
*/
zooKeeper.exists(LOG_MAIN, true);
zooKeeper.create(LOG_MAIN, LOG_MAIN.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public static void setRootPath(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
// exists() 方法如果路徑刪除成功,true 表示會調用監聽事件
zooKeeper.exists(LOG_MAIN, true);
zooKeeper.setData(LOG_MAIN, "root".getBytes(), -1);
}
public static void deleteRootPath(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
// exists() 方法如果路徑刪除成功,true 表示會調用監聽事件
zooKeeper.exists(LOG_MAIN, true);
zooKeeper.delete(LOG_MAIN, 1);
}
}
結果