日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

zookeeper版本更新_ZooKeeper入门,看这篇就够了!

發(fā)布時(shí)間:2024/10/8 编程问答 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 zookeeper版本更新_ZooKeeper入门,看这篇就够了! 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

思維導(dǎo)圖

前言

在很多時(shí)候,我們都可以在各種框架應(yīng)用中看到ZooKeeper的身影,比如Kafka中間件,Dubbo框架,Hadoop等等。為什么到處都看到ZooKeeper?

一、什么是ZooKeeper

ZooKeeper是一個(gè)分布式服務(wù)協(xié)調(diào)框架,提供了分布式數(shù)據(jù)一致性的解決方案,基于ZooKeeper的數(shù)據(jù)結(jié)構(gòu),Watcher,選舉機(jī)制等特點(diǎn),可以實(shí)現(xiàn)數(shù)據(jù)的發(fā)布/訂閱,軟負(fù)載均衡,命名服務(wù),統(tǒng)一配置管理,分布式鎖,集群管理等等。

二、為什么使用ZooKeeper

ZooKeeper能保證:

  • 更新請求順序進(jìn)行。來自同一個(gè)client的更新請求按其發(fā)送順序依次執(zhí)行
  • 數(shù)據(jù)更新原子性。一次數(shù)據(jù)更新要么成功,要么失敗
  • 全局唯一數(shù)據(jù)視圖。client無論連接到哪個(gè)server,數(shù)據(jù)視圖都是一致的
  • 實(shí)時(shí)性。在一定時(shí)間范圍內(nèi),client讀到的數(shù)據(jù)是最新的

三、數(shù)據(jù)結(jié)構(gòu)

ZooKeeper的數(shù)據(jù)結(jié)構(gòu)和Unix文件系統(tǒng)很類似,總體上可以看做是一棵樹,每一個(gè)節(jié)點(diǎn)稱之為一個(gè)ZNode,每一個(gè)ZNode默認(rèn)能存儲(chǔ)1M的數(shù)據(jù)。每一個(gè)ZNode可通過唯一的路徑標(biāo)識。如下圖所示:

創(chuàng)建ZNode時(shí),可以指定以下四種類型,包括:

  • PERSISTENT,持久性ZNode。創(chuàng)建后,即使客戶端與服務(wù)端斷開連接也不會(huì)刪除,只有客戶端主動(dòng)刪除才會(huì)消失。
  • PERSISTENT_SEQUENTIAL,持久性順序編號ZNode。和持久性節(jié)點(diǎn)一樣不會(huì)因?yàn)閿嚅_連接后而刪除,并且ZNode的編號會(huì)自動(dòng)增加。
  • EPHEMERAL,臨時(shí)性ZNode。客戶端與服務(wù)端斷開連接,該ZNode會(huì)被刪除。
  • EPEMERAL_SEQUENTIAL,臨時(shí)性順序編號ZNode。和臨時(shí)性節(jié)點(diǎn)一樣,斷開連接會(huì)被刪除,并且ZNode的編號會(huì)自動(dòng)增加。

四、監(jiān)聽通知機(jī)制

Watcher是基于觀察者模式實(shí)現(xiàn)的一種機(jī)制。如果我們需要實(shí)現(xiàn)當(dāng)某個(gè)ZNode節(jié)點(diǎn)發(fā)生變化時(shí)收到通知,就可以使用Watcher監(jiān)聽器。

客戶端通過設(shè)置監(jiān)視點(diǎn)(watcher)向 ZooKeeper 注冊需要接收通知的 znode,在 znode 發(fā)生變化時(shí) ZooKeeper 就會(huì)向客戶端發(fā)送消息。

這種通知機(jī)制是一次性的。一旦watcher被觸發(fā),ZooKeeper就會(huì)從相應(yīng)的存儲(chǔ)中刪除。如果需要不斷監(jiān)聽ZNode的變化,可以在收到通知后再設(shè)置新的watcher注冊到ZooKeeper。

監(jiān)視點(diǎn)的類型有很多,如監(jiān)控ZNode數(shù)據(jù)變化、監(jiān)控ZNode子節(jié)點(diǎn)變化、監(jiān)控ZNode 創(chuàng)建或刪除。

五、選舉機(jī)制

ZooKeeper是一個(gè)高可用的應(yīng)用框架,因?yàn)閆ooKeeper是支持集群的。ZooKeeper在集群狀態(tài)下,配置文件是不會(huì)指定Master和Slave,而是在ZooKeeper服務(wù)器初始化時(shí)就在內(nèi)部進(jìn)行選舉,產(chǎn)生一臺做為Leader,多臺做為Follower,并且遵守半數(shù)可用原則。

由于遵守半數(shù)可用原則,所以5臺服務(wù)器和6臺服務(wù)器,實(shí)際上最大允許宕機(jī)數(shù)量都是3臺,所以為了節(jié)約成本,集群的服務(wù)器數(shù)量一般設(shè)置為奇數(shù)。

如果在運(yùn)行時(shí),如果長時(shí)間無法和Leader保持連接的話,則會(huì)再次進(jìn)行選舉,產(chǎn)生新的Leader,以保證服務(wù)的可用。

六、初の體驗(yàn)

首先在官網(wǎng)下載ZooKeeper,我這里用的是3.3.6版本。

然后解壓,復(fù)制一下/conf目錄下的zoo_sample.cfg文件,重命名為zoo.cfg。

修改zoo.cfg中dataDir的值,并創(chuàng)建對應(yīng)的目錄:

最后到/bin目錄下啟動(dòng),我用的是window系統(tǒng),所以啟動(dòng)zkServer.cmd,雙擊即可:

啟動(dòng)成功的話就可以看到這個(gè)對話框:

可視化界面的話,我推薦使用ZooInspector,操作比較簡便:

6.1 使用java連接ZooKeeper

首先引入Maven依賴:

<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.6</version> </dependency>

接著我們寫一個(gè)Main方法,進(jìn)行操作:

//連接地址及端口號private static final String SERVER_HOST = "127.0.0.1:2181";//會(huì)話超時(shí)時(shí)間private static final int SESSION_TIME_OUT = 2000;public static void main(String[] args) throws Exception {//參數(shù)一:服務(wù)端地址及端口號//參數(shù)二:超時(shí)時(shí)間//參數(shù)三:監(jiān)聽器ZooKeeper zooKeeper = new ZooKeeper(SERVER_HOST, SESSION_TIME_OUT, new Watcher() {@Overridepublic void process(WatchedEvent watchedEvent) {//獲取事件的狀態(tài)Event.KeeperState state = watchedEvent.getState();//判斷是否是連接事件if (Event.KeeperState.SyncConnected == state) {Event.EventType type = watchedEvent.getType();if (Event.EventType.None == type) {System.out.println("zk客戶端已連接...");}}}});zooKeeper.create("/java", "Hello World".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);System.out.println("新增ZNode成功");zooKeeper.close();}

創(chuàng)建一個(gè)持久性ZNode,路徑是/java,值為"Hello World":

七、API概述

7.1 創(chuàng)建

public String create(final String path, byte data[], List<ACL> acl, CreateMode createMode)

參數(shù)解釋:

  • path ZNode路徑
  • data ZNode存儲(chǔ)的數(shù)據(jù)
  • acl ACL權(quán)限控制
  • createMode ZNode類型

ACL權(quán)限控制,有三個(gè)是ZooKeeper定義的常用權(quán)限,在ZooDefs.Ids類中:

/*** This is a completely open ACL.* 完全開放的ACL,任何連接的客戶端都可以操作該屬性znode*/ public final ArrayList<ACL> OPEN_ACL_UNSAFE = new ArrayList<ACL>(Collections.singletonList(new ACL(Perms.ALL, ANYONE_ID_UNSAFE)));/*** This ACL gives the creators authentication id's all permissions.* 只有創(chuàng)建者才有ACL權(quán)限*/ public final ArrayList<ACL> CREATOR_ALL_ACL = new ArrayList<ACL>(Collections.singletonList(new ACL(Perms.ALL, AUTH_IDS)));/*** This ACL gives the world the ability to read.* 只能讀取ACL*/ public final ArrayList<ACL> READ_ACL_UNSAFE = new ArrayList<ACL>(Collections.singletonList(new ACL(Perms.READ, ANYONE_ID_UNSAFE)));

createMode就是前面講過的四種ZNode類型:

public enum CreateMode {/*** 持久性ZNode*/PERSISTENT (0, false, false),/*** 持久性自動(dòng)增加順序號ZNode*/PERSISTENT_SEQUENTIAL (2, false, true),/*** 臨時(shí)性ZNode*/EPHEMERAL (1, true, false),/*** 臨時(shí)性自動(dòng)增加順序號ZNode*/EPHEMERAL_SEQUENTIAL (3, true, true); }

7.2 查詢

//同步獲取節(jié)點(diǎn)數(shù)據(jù) public byte[] getData(String path, boolean watch, Stat stat){... }//異步獲取節(jié)點(diǎn)數(shù)據(jù) public void getData(final String path, Watcher watcher, DataCallback cb, Object ctx){... }

同步getData()方法中的stat參數(shù)是用于接收返回的節(jié)點(diǎn)描述信息:

public byte[] getData(final String path, Watcher watcher, Stat stat){//省略...GetDataResponse response = new GetDataResponse();//發(fā)送請求到ZooKeeper服務(wù)器,獲取到responseReplyHeader r = cnxn.submitRequest(h, request, response, wcb);if (stat != null) {//把response的Stat賦值到傳入的stat中DataTree.copyStat(response.getStat(), stat);} }

使用同步getData()獲取數(shù)據(jù):

//數(shù)據(jù)的描述信息,包括版本號,ACL權(quán)限,子節(jié)點(diǎn)信息等等Stat stat = new Stat();//返回結(jié)果是byte[]數(shù)據(jù),getData()方法底層會(huì)把描述信息復(fù)制到stat對象中byte[] bytes = zooKeeper.getData("/java", false, stat);//打印結(jié)果System.out.println("ZNode的數(shù)據(jù)data:" + new String(bytes));//Hello WorldSystem.out.println("獲取到dataVersion版本號:" + stat.getVersion());//默認(rèn)數(shù)據(jù)版本號是0

7.3 更新

public Stat setData(final String path, byte data[], int version){... }

值得注意的是第三個(gè)參數(shù)version,使用CAS機(jī)制,這是為了防止多個(gè)客戶端同時(shí)更新節(jié)點(diǎn)數(shù)據(jù),所以需要在更新時(shí)傳入版本號,每次更新都會(huì)使版本號+1,如果服務(wù)端接收到版本號,對比發(fā)現(xiàn)不一致的話,則會(huì)拋出異常。

所以,在更新前需要先查詢獲取到版本號,否則你不知道當(dāng)前版本號是多少,就沒法更新:

//獲取節(jié)點(diǎn)描述信息Stat stat = new Stat();zooKeeper.getData("/java", false, stat);System.out.println("更新ZNode數(shù)據(jù)...");//更新操作,傳入路徑,更新值,版本號三個(gè)參數(shù),返回結(jié)果是新的描述信息Stat setData = zooKeeper.setData("/java", "fly!!!".getBytes(), stat.getVersion());System.out.println("更新后的版本號為:" + setData.getVersion());//更新后的版本號為:1

更新后,版本號增加了:

如果傳入的版本參數(shù)是"-1",就是告訴zookeeper服務(wù)器,客戶端需要基于數(shù)據(jù)的最新版本進(jìn)行更新操作。但是-1并不是一個(gè)合法的版本號,而是一個(gè)標(biāo)識符。

7.4 刪除

public void delete(final String path, int version){... }
  • path 刪除節(jié)點(diǎn)的路徑
  • version 版本號

這里也需要傳入版本號,調(diào)用getData()方法即可獲取到版本號,很簡單:

Stat stat = new Stat(); zooKeeper.getData("/java", false, stat); //刪除ZNode zooKeeper.delete("/java", stat.getVersion());

7.5 watcher機(jī)制

在上面第三點(diǎn)提到,ZooKeeper是可以使用通知監(jiān)聽機(jī)制,當(dāng)ZNode發(fā)生變化會(huì)收到通知消息,進(jìn)行處理。基于watcher機(jī)制,ZooKeeper能玩出很多花樣。怎么使用?

ZooKeeper的通知監(jiān)聽機(jī)制,總的來說可以分為三個(gè)過程:

①客戶端注冊 Watcher

②服務(wù)器處理 Watcher

③客戶端回調(diào) Watcher客戶端。

注冊 watcher 有 4 種方法,new ZooKeeper()、getData()、exists()、getChildren()。下面演示一下使用exists()方法注冊watcher:

首先需要實(shí)現(xiàn)Watcher接口,新建一個(gè)監(jiān)聽器:

public class MyWatcher implements Watcher {@Overridepublic void process(WatchedEvent event) {//獲取事件類型Event.EventType eventType = event.getType();//通知狀態(tài)Event.KeeperState eventState = event.getState();//節(jié)點(diǎn)路徑String eventPath = event.getPath();System.out.println("監(jiān)聽到的事件類型:" + eventType.name());System.out.println("監(jiān)聽到的通知狀態(tài):" + eventState.name());System.out.println("監(jiān)聽到的ZNode路徑:" + eventPath);} }

然后調(diào)用exists()方法,注冊監(jiān)聽器:

zooKeeper.exists("/java", new MyWatcher()); //對ZNode進(jìn)行更新數(shù)據(jù)的操作,觸發(fā)監(jiān)聽器 zooKeeper.setData("/java", "fly".getBytes(), -1);

然后在控制臺就可以看到打印的信息:

這里我們可以看到Event.EventType對象就是事件類型,我們可以對事件類型進(jìn)行判斷,再配合Event.KeeperState通知狀態(tài),做相關(guān)的業(yè)務(wù)處理,事件類型有哪些?

打開EventType、KeeperState的源碼查看:

//事件類型是一個(gè)枚舉 public enum EventType {None (-1),//無NodeCreated (1),//Watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)被創(chuàng)建NodeDeleted (2),//Watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)被刪除NodeDataChanged (3),//Watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)內(nèi)容發(fā)生變更NodeChildrenChanged (4);//Watcher監(jiān)聽的數(shù)據(jù)節(jié)點(diǎn)的子節(jié)點(diǎn)列表發(fā)生變更 }//通知狀態(tài)也是一個(gè)枚舉 public enum KeeperState {Unknown (-1),//屬性過期Disconnected (0),//客戶端與服務(wù)端斷開連接NoSyncConnected (1),//屬性過期SyncConnected (3),//客戶端與服務(wù)端正常連接AuthFailed (4),//身份認(rèn)證失敗ConnectedReadOnly (5),//返回這個(gè)狀態(tài)給客戶端,客戶端只能處理讀請求SaslAuthenticated(6),//服務(wù)器采用SASL做校驗(yàn)時(shí)Expired (-112);//會(huì)話session失效 }

7.5.1 watcher的特性

  • 一次性。一旦watcher被觸發(fā),ZK都會(huì)從相應(yīng)的存儲(chǔ)中移除。
zooKeeper.exists("/java", new Watcher() {@Overridepublic void process(WatchedEvent event) {System.out.println("我是exists()方法的監(jiān)聽器");}});//對ZNode進(jìn)行更新數(shù)據(jù)的操作,觸發(fā)監(jiān)聽器zooKeeper.setData("/java", "fly".getBytes(), -1);//企圖第二次觸發(fā)監(jiān)聽器zooKeeper.setData("/java", "spring".getBytes(), -1);

  • 串行執(zhí)行。客戶端Watcher回調(diào)的過程是一個(gè)串行同步的過程,這是為了保證順序。
zooKeeper.exists("/java", new Watcher() {@Overridepublic void process(WatchedEvent event) {System.out.println("我是exists()方法的監(jiān)聽器");}});Stat stat = new Stat();zooKeeper.getData("/java", new Watcher() {@Overridepublic void process(WatchedEvent event) {System.out.println("我是getData()方法的監(jiān)聽器");}}, stat);//對ZNode進(jìn)行更新數(shù)據(jù)的操作,觸發(fā)監(jiān)聽器zooKeeper.setData("/java", "fly".getBytes(), stat.getVersion());

打印結(jié)果,說明先調(diào)用exists()方法的監(jiān)聽器,再調(diào)用getData()方法的監(jiān)聽器。因?yàn)閑xists()方法先注冊了。

  • 輕量級。WatchedEvent是ZK整個(gè)Watcher通知機(jī)制的最小通知單元。WatchedEvent包含三部分:通知狀態(tài),事件類型,節(jié)點(diǎn)路徑。Watcher通知僅僅告訴客戶端發(fā)生了什么事情,而不會(huì)說明事件的具體內(nèi)容。

寫在最后

我記得B站的UP主李永樂說過,只有你讓更多的人生活變得更美好時(shí),自己的生活才能變得更美好。

這句話也是我今年開始寫技術(shù)分享的一個(gè)動(dòng)力源泉,希望這篇文章對你有用~

著名的飛行家馬老師說過:回城是收費(fèi)的,而點(diǎn)贊是免費(fèi)的~

覺得我有點(diǎn)東西的話,可以公眾號搜索「java技術(shù)愛好者」,關(guān)注一下吧~

與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的zookeeper版本更新_ZooKeeper入门,看这篇就够了!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。