欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ZooKeeper入門教程一簡介與核心概念

 更新時間:2022年01月28日 14:44:47   作者:愛碼叔(稀有氣體)  
本文是ZooKeeper入門系列教程,涵蓋ZooKeeper核心內(nèi)容,通過實例和大量圖表,結(jié)合實戰(zhàn),幫助學(xué)習(xí)者理解和運用,有需要的朋友可以借鑒參考下,希望能夠有所幫助

本章是后續(xù)學(xué)習(xí)的基石,只有充分理解了分布式系統(tǒng)的概念和面臨的問題,以及ZooKeeper內(nèi)部的概念,才能懂得ZooKeeper是如何對分布式系統(tǒng)進行協(xié)調(diào),為后續(xù)學(xué)習(xí)打下堅實的基礎(chǔ)。

1、ZooKeeper介紹與核心概念

1.1 簡介

ZooKeeper最為主要的使用場景,是作為分布式系統(tǒng)的分布式協(xié)同服務(wù)。在學(xué)習(xí)zookeeper之前,先要對分布式系統(tǒng)的概念有所了解,否則你將完全不知道zookeeper在分布式系統(tǒng)中起到了什么作用,解決了什么問題。

1.2分布式系統(tǒng)面臨的問題

我們將分布式系統(tǒng)定義為:分布式系統(tǒng)是同時跨越多個物理主機,獨立運行的多個軟件所組成系統(tǒng)。類比一下,分布式系統(tǒng)就是一群人一起干活。人多力量大,每個服務(wù)器的算力是有限的,但是通過分布式系統(tǒng),由n個服務(wù)器組成起來的集群,算力是可以無限擴張的。

優(yōu)點顯而易見,人多干活快,并且互為備份。但是缺點也很明顯。我們可以想象一下,以一個小研發(fā)團隊開發(fā)軟件為例,假設(shè)我們有一個5人的項目組,要開始一個系統(tǒng)的開發(fā),項目組將面臨如下問題:

你一定在想,以上這些問題很簡單啊,在我的日常工作中天天都在發(fā)生,并沒感覺有什么復(fù)雜。是的,這是因為我們?nèi)祟惖拇竽X是個超級計算機,能夠靈活應(yīng)對這些問題,而且現(xiàn)實中信息的交換不依賴網(wǎng)絡(luò),不會因網(wǎng)絡(luò)延遲或者中斷,出現(xiàn)信息不對等。而且現(xiàn)實中對以上問題的處理其實并不嚴謹,從而也引發(fā)了很多問題。

想一想,項目中是不是出現(xiàn)過溝通不暢造成任務(wù)分配有歧義?是否由于人員離職造成任務(wù)進行不下去,甚至要聯(lián)系離職人員協(xié)助?是不是出現(xiàn)過任務(wù)分配不合理?類似這樣的各種問題,肯定會發(fā)生于你的項目組中。

在現(xiàn)實世界,我們可以人為去協(xié)調(diào),即使出錯了,人工去補錯,加加班搞定就好。但在計算機的世界,這樣做是行不通的,一切都要保證嚴謹,以上問題要做到盡可能不要發(fā)生。因此,分布式系統(tǒng)必須采用合理的方式解決掉以上的問題。

實際上要想解決這些問題并沒有那么復(fù)雜,我們僅需要做一件事就可以萬事無憂---讓信息在項目組成員中同步。如果能做到信息同步,那么每個人在干什么,大家都是清楚的,干到什么程度也是清晰的,無論誰離職也不會產(chǎn)生問題。分配的工作,能夠及時清晰的同步給每個組員,確保每個組員收到的任務(wù)分配沒有沖突。

分布式系統(tǒng)的協(xié)調(diào)工作就是通過某種方式,讓每個節(jié)點的信息能夠同步和共享。這依賴于服務(wù)進程之間的通信。通信方式有兩種:

1、通過網(wǎng)絡(luò)進行信息共享

這就像現(xiàn)實世界,開發(fā)leader在會上把任務(wù)傳達下去,組員通過聽leader命令或者看leader的郵件知道自己要干什么。當(dāng)任務(wù)分配有變化時,leader會單獨告訴組員,或者再次召開會議。信息通過人與人之間的直接溝通,完成傳遞。

2、通過共享存儲

這就好比開發(fā)leader按照約定的時間和路徑,把任務(wù)分配表放到了svn上,組員每天去svn上拉取最新的任務(wù)分配表,然后干活。其中svn就是共享存儲。更好一點的做法是,當(dāng)svn文件版本更新時,觸發(fā)郵件通知,每個組員再去拉取最新的任務(wù)分配表。這樣做更好,因為每次更新,組員都能第一時間得到消息,從而讓自己手中的任務(wù)分配表永遠是最新的。此種方式依賴于中央存儲。整個過程如下圖所示:

1.3 ZooKeeper如何解決分布式系統(tǒng)面臨的問題

ZooKeeper對分布式系統(tǒng)的協(xié)調(diào),使用的是第二種方式,共享存儲。其實共享存儲,分布式應(yīng)用也需要和存儲進行網(wǎng)絡(luò)通信。網(wǎng)絡(luò)通信是分布式系統(tǒng)并發(fā)設(shè)計的基礎(chǔ)。

實際上,通過ZooKeeper實現(xiàn)分布式協(xié)同的原理,和項目組通過SVN同步工作任務(wù)的例子是一樣的。ZooKeeper就像是svn,存儲了任務(wù)的分配、完成情況等共享信息。每個分布式應(yīng)用的節(jié)點就是組員,訂閱這些共享信息。當(dāng)主節(jié)點(組leader),對某個從節(jié)點的分工信息作出改變時,相關(guān)訂閱的從節(jié)點得到zookeeper的通知,取得自己最新的任務(wù)分配。完成工作后,把完成情況存儲到zookeeper。主節(jié)點訂閱了該任務(wù)的完成情況信息,所以將得到zookeeper的完工的通知。參考下圖,回味一下,是不是和前面項目組通過svn分配工作的例子一模一樣?僅僅是把svn和郵件系統(tǒng)合二為一,以ZooKeeper代替。

注:Slave節(jié)點要想獲取ZooKeeper的更新通知,需事先在關(guān)心的數(shù)據(jù)節(jié)點上設(shè)置觀察點。

大多數(shù)分布式系統(tǒng)中出現(xiàn)的問題,都源于信息的共享出了問題。如果各個節(jié)點間信息不能及時共享和同步,那么就會在協(xié)作過程中產(chǎn)生各種問題。ZooKeeper解決協(xié)同問題的關(guān)鍵,在于保證分布式系統(tǒng)信息的一致性。

通過以上章節(jié)的講解,我們應(yīng)該已經(jīng)理解分布式系統(tǒng)以及其面臨的問題。了解了ZooKeeper通過什么樣的機制去解決這些問題。從宏觀上對ZooKeeper已經(jīng)有了認知,接下來我們先切入到zookeeper自身,講解zookeeper的概念,這些概念很重要,所有zookeeper的應(yīng)用都會圍繞這些概念來實現(xiàn)。

1.4 zookeeper概念介紹

ZooKeeper并不直接暴露分布式服務(wù)所需要的原語及原語的調(diào)用方法。什么是原語?舉個例子,比如說分布式鎖機制是一個原語,它會暴露出創(chuàng)建、獲取、釋放三個調(diào)用方法。ZooKeeper以類似文件系統(tǒng)的方式存儲數(shù)據(jù),暴漏出調(diào)用這些數(shù)據(jù)的API。讓應(yīng)用通過ZooKeeper的機制和API,自己來實現(xiàn)分布式相關(guān)原語。

我們?nèi)粝胱寫?yīng)用能夠通過ZooKeeper實現(xiàn)分布式協(xié)同,那么第一件事就是了解ZooKeeper的特性及相關(guān)概念,另外熟悉它給我們提供了哪些API。

1.4.1 znode

Zookeeper會保存任務(wù)的分配、完成情況,等共享信息,那么ZooKeeper是如何保存的呢?在ZooKeeper中,這些信息被保存在一個個數(shù)據(jù)節(jié)點上,這些節(jié)點被稱為znode。它采用了類似文件系統(tǒng)的層級樹狀結(jié)構(gòu)進行管理。見下圖示例:

根節(jié)點/包含4個子節(jié)點,其中三個擁有下一級節(jié)點。有的葉子節(jié)點存儲了信息。

節(jié)點上沒有存儲數(shù)據(jù),也有著重要的含義。比如在主從模式中,當(dāng)/master節(jié)點沒有數(shù)據(jù)時,代表分布式應(yīng)用的主節(jié)點還沒有選舉出來。

znode節(jié)點存儲的數(shù)據(jù)為字節(jié)數(shù)組。存儲數(shù)據(jù)的格式zookeeper不做限制,也不提供解析,需要應(yīng)用自己實現(xiàn)。

實際上圖就是主從模式存儲數(shù)據(jù)的示例,這里先簡單講解:

  • /master,存儲了當(dāng)前主節(jié)點的信息
  • /workers,下面的每個子znode代表一個從節(jié)點,子znode上存儲的數(shù)據(jù),如“foo.com:2181”,代表從節(jié)點的信息。
  • /tasks,下面的每個子znode代表一個任務(wù),子znode上存儲的信息如“run cmd”,代表該內(nèi)務(wù)內(nèi)容
  • /assign,下面每個子znode代表一個從節(jié)點的任務(wù)集合。如/assign/worker-1,代表worker-1這個從節(jié)點的任務(wù)集合。/assign/worker-1下的每個子znode代表分配給worker-1的一個任務(wù)。
持久節(jié)點(persistent)和臨時節(jié)點(ephemeral)

持久節(jié)點只能通過delete刪除。臨時節(jié)點在創(chuàng)建該節(jié)點的客戶端崩潰或關(guān)閉時,自動被刪除。

前面例子中的/master應(yīng)該使用臨時節(jié)點,這樣當(dāng)主節(jié)點失效或者退出時,該znode被刪除,其他節(jié)點知道主節(jié)點崩潰了,開始進行選舉的邏輯。另外/works/worker-1也應(yīng)該是臨時節(jié)點,在此從節(jié)點失效的時候,該臨時節(jié)點自動刪除。

在目前的版本,由于臨時znode會因為創(chuàng)建者會話過期被刪除,所以不允許臨時節(jié)點擁有子節(jié)點。

有序節(jié)點

znode可以被設(shè)置為有序(sequential)節(jié)點。有序znode節(jié)點被分配唯一一個單調(diào)遞增的證書。如果創(chuàng)建了個一有序節(jié)點為/workers/worker-,zookeeper會自動分配一個序號1,追加在名字后面,znode名稱為/workers/worker-1。通過這種方式,可以創(chuàng)建唯一名稱znode,并且可以直觀的看到創(chuàng)建的順序。

znode支持的操作及暴露的API:

create /path data

    創(chuàng)建一個名為/path的znode,數(shù)據(jù)為data。

delete /path

    刪除名為/path的znode。

exists /path

    檢查是否存在名為/path的znode

setData /path data

    設(shè)置名為/path的znode的數(shù)據(jù)為data

getData /path

    返回名為/path的znode的數(shù)據(jù)

getChildren /path

    返回所有/path節(jié)點的所有子節(jié)點列表

1.4.2 觀察與通知

分布式應(yīng)用需要及時知道zookeeper中znode的變化,從而了解到分布式應(yīng)用整體的狀況,如果采用輪詢方式,代價太大,絕大多數(shù)查詢都是無效的。因此,zookeeper采用了通知的機制??蛻舳讼騴ookeeper請求,在特定的znode設(shè)置觀察點(watch)。當(dāng)該znode發(fā)生變化時,會觸發(fā)zookeeper的通知,客戶端收到通知后進行業(yè)務(wù)處理。觀察點觸發(fā)后立即失效。所以一旦觀察點觸發(fā),需要再次設(shè)置新的觀察點。

我們使用Zookeeper不能期望能夠監(jiān)控到節(jié)點每次的變化。思考如下場景:

  • 1、客戶端C1設(shè)置觀察點在/tasks
  • 2、觀察點觸發(fā),C1處理自己的邏輯
  • 3、C1設(shè)置新的觀察點前,C2更新了/tasks
  • 4、C1處理完邏輯,再次設(shè)置了觀察點。

此時C1不會得到第三步的通知,因此錯過了C2更新/tasks這次操作。要想不錯過這次更新,C1需要在設(shè)置監(jiān)視點前讀取/tasks的數(shù)據(jù),進行對比,發(fā)現(xiàn)更新。

再如下面的場景:

  • 1、客戶端C1設(shè)置觀察點在/tasks
  • 2、/tasks上發(fā)生了連續(xù)兩次更新
  • 3、C1在得到第一次更新的通知后就讀取了/tasks的數(shù)據(jù)
  • 4、此時第二次更新也已經(jīng)發(fā)生,C1用第一次的通知,讀取到兩次更新后的數(shù)據(jù)

此時C1雖然錯過了第二次通知,但是C1最終還是讀取到了最新的數(shù)據(jù)。

因此Zookeeper只能保證最終的一致性,而無法保證強一致性。

zookeeper可以定義不同的觀察類型。例如觀察znode數(shù)據(jù)變化,觀察znode子節(jié)點變化,觀察znode創(chuàng)建或者刪除。

1.4.3 版本

每個znode都有版本號,隨著每次數(shù)據(jù)變化自增。setData和delete,以版本號作為參數(shù),當(dāng)傳入的版本號和服務(wù)器上不一致時,調(diào)用失敗。當(dāng)多個zookeeper客戶端同時對一個znode操作時,版本將會起到作用,假設(shè)c1,c2同時往一個znode寫數(shù)據(jù),c1先寫完后版本從1升為2,但是c2寫的時候攜帶版本號1,c2會寫入失敗。

1.4.4 法定人數(shù)

zookeeper服務(wù)器運行于兩種模式:獨立模式和仲裁模式(集群)。仲裁模式下,會復(fù)制所有服務(wù)器的數(shù)據(jù)樹。但如果讓客戶端等待所有復(fù)制完成,延遲太高。這里引入法定人數(shù)概念,指為了使zookeeper集群正常工作,必須有效運行的服務(wù)器數(shù)量。同時也是服務(wù)器通知客戶端保存成功前,必須保存數(shù)據(jù)的服務(wù)器最小數(shù)。例如我們有一個5臺服務(wù)器的zookeeper集群,法定人數(shù)為3,只要任何3個服務(wù)器保存了數(shù)據(jù),客戶端就會收到確認。只要有3臺服務(wù)器存活,整個zookeeper集群就是可用的。

下圖展示了客戶端提交請求到收到回復(fù)的過程:

法定人數(shù)需要大于服務(wù)器數(shù)量的一半。也稱為多數(shù)原則。舉個例子說明,假如集群有5臺服務(wù)器,法定人數(shù)為2,那么有2臺服務(wù)器參與復(fù)制即可,若這2臺server剛剛復(fù)制完/z這個znode,就掛掉了。此時剩下了3臺server,大于法定人數(shù)2,所以zookeeper認為集群正常,但這三臺服務(wù)器是無法發(fā)現(xiàn)/z這個znode的。如果法定人數(shù)大于服務(wù)器數(shù)量一半,那么法定人數(shù)復(fù)制完成,就可以確保集群存活時,至少有一臺服務(wù)器有最新的znode,否則集群認為自己已經(jīng)崩潰。

下面兩個例子闡明了,為何要遵循多數(shù)原則。

下圖展示了5臺server,法定人數(shù)為3,在確保zookeeper集群存活的前提下,最壞的情況掛了2臺server(剩余及器數(shù)量3>=法定人數(shù)3),zookeeper是如何能確保數(shù)據(jù)完備,集群繼續(xù)工作的。

接下來兩張圖展示了5臺server,未遵循多數(shù)原則,法定人數(shù)設(shè)為2。同樣掛了兩臺server時,為什么zookeeper集群會出問題。

首先,客戶端發(fā)起請求,2個server復(fù)制數(shù)據(jù)后即返回客戶端接收成功。

就在此刻,很不幸,在繼續(xù)同步更新給其他節(jié)點前,剛剛兩個復(fù)制了數(shù)據(jù)的節(jié)點掛了。

此時會怎樣呢?如下圖:

可以看到創(chuàng)建/z的操作在zookeeper集群中丟失了。

相信通過以上講解,你已經(jīng)能夠理解為什么法定人數(shù)一定要多于一半服務(wù)器的數(shù)量。

此外,我們要盡量選用奇數(shù)個服務(wù)器,這樣集群能容忍崩潰服務(wù)器占比更大,性價比更高。例如4臺服務(wù)器的集群,法定人數(shù)最少為3,那么只能允許1臺服務(wù)器崩潰,也就是僅允許25%的機器崩潰。而5臺服務(wù)器的集群,法定人數(shù)最少也是3,但是此時允許2臺服務(wù)器崩潰。換句話講,40%的機器崩潰后還能工作。

仲裁模式下,負載均衡通過客戶端隨機選擇連接串中的某個服務(wù)器來實現(xiàn)。

1.4.5 會話

客戶端對zookeeper集群發(fā)送任何請求前,需要和zookeeper集群建立會話??蛻舳颂峤唤ozookeeper的所有操作均關(guān)聯(lián)在一個會話上。當(dāng)一個會話因某種原因終止時,會話期間創(chuàng)建的臨時節(jié)點將會消失。而當(dāng)當(dāng)前服務(wù)器的問題,無法繼續(xù)通信時,會話將被透明的轉(zhuǎn)移到另外一臺zookeeper集群的服務(wù)器上。

會話提供了順序保障。同一個會話中的請求以FIFO順序執(zhí)行。并發(fā)會話的FIFO順序無法保證。

1.4.6 會話狀態(tài)和生命周期

會話狀態(tài)有:

connecting、connected、closed、not_connected

創(chuàng)建會話時,需要設(shè)置會話超時這個重要的參數(shù)。如果經(jīng)過時間t后服務(wù)接受不到這個會話的任何消息,服務(wù)就會聲明會話過期??蛻舳藗?cè),t/3時間未收到任何消息,客戶端向服務(wù)器發(fā)送心跳消息,2t/3時間后,客戶端開始尋找其他服務(wù)器。此時他有t/3的時間去尋找,找不到的話,會話失效。

重連服務(wù)器時,只有更新大于客戶端的服務(wù)器才能被連接,以免連接到落后的服務(wù)器。zookeeper中通過更新建立的順序,分配事務(wù)標識符。只有服務(wù)器的事物標識符大于客戶端攜帶的標識符時,才可連接。

回顧總結(jié)

本章首先介紹了分布式系統(tǒng)及分布式系統(tǒng)面臨的問題,隨后介紹了zookeeper是以何機制來解決這些問題的。最后介紹了zookeeper中的重要概念,在開始后續(xù)學(xué)習(xí)前,一定要確保自己理解了這些重要的概念,本章知識是后面章節(jié)學(xué)習(xí)的重要基石,希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring中的spring.factories文件用法(Spring如何加載第三方Bean)

    Spring中的spring.factories文件用法(Spring如何加載第三方Bean)

    這篇文章主要介紹了Spring中的spring.factories文件用法(Spring如何加載第三方Bean),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot整合minio快速入門教程(代碼示例)

    SpringBoot整合minio快速入門教程(代碼示例)

    這篇文章主要介紹了SpringBoot整合minio快速入門實現(xiàn)文件上傳和下載的示例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • java list常用方法總結(jié)

    java list常用方法總結(jié)

    這篇文章主要介紹了java list常用方法總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • java實現(xiàn)微信企業(yè)付款到個人功能

    java實現(xiàn)微信企業(yè)付款到個人功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)微信企業(yè)付款到個人功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • SpringBoot項目沒有把依賴的jar包一起打包的問題解決

    SpringBoot項目沒有把依賴的jar包一起打包的問題解決

    這篇文章主要介紹了SpringBoot項目沒有把依賴的jar包一起打包的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09
  • java實現(xiàn)打印正三角的方法

    java實現(xiàn)打印正三角的方法

    這篇文章主要為大家詳細介紹了java實現(xiàn)打印正三角的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 使用@PathVariable注解如何實現(xiàn)動態(tài)傳值

    使用@PathVariable注解如何實現(xiàn)動態(tài)傳值

    這篇文章主要介紹了使用@PathVariable注解如何實現(xiàn)動態(tài)傳值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java8簡單了解Lambda表達式與函數(shù)式接口

    Java8簡單了解Lambda表達式與函數(shù)式接口

    這篇文章主要介紹了Java8簡單了解Lambda表達式與函數(shù)式接口,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • 淺談Java中復(fù)制數(shù)組的方式

    淺談Java中復(fù)制數(shù)組的方式

    這篇文章主要介紹了Java中復(fù)制數(shù)組的幾種方法,需要的朋友可以參考下。
    2017-08-08
  • SpringMVC @RequestBody的使用解析

    SpringMVC @RequestBody的使用解析

    這篇文章主要介紹了SpringMVC @RequestBody的使用解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評論