• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            zookeeper簡介

            轉載自:http://blog.csdn.net/jirongzi_cs2011/article/details/41787893

            ZooKeeper是一個分布式的,開放源碼的分布式應用程序協調服務,它包含一個簡單的原語集,分布式應用程序可以基于它實現同步服務,配置維護和命名服務等。Zookeeper是hadoop的一個子項目,其發展歷程無需贅述。在分布式應用中,由于工程師不能很好地使用鎖機制,以及基于消息的協調機制不適合在某些應用中使用,因此需要有一種可靠的、可擴展的、分布式的、可配置的協調機制來統一系統的狀態。Zookeeper的目的就在于此。本文簡單分析zookeeper的工作原理,對于如何使用zookeeper不是本文討論的重點。

            1 Zookeeper的基本概念

            1.1 角色

            Zookeeper中的角色主要有以下三類,如下表所示:

            系統模型如圖所示:

            1.2 設計目的

            1.最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖,這是zookeeper最重要的性能。

            2 .可靠性:具有簡單、健壯、良好的性能,如果消息m被到一臺服務器接受,那么它將被所有的服務器接受。

            3 .實時性:Zookeeper保證客戶端將在一個時間間隔范圍內獲得服務器的更新信息,或者服務器失效的信息。但由于網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,應該在讀數據之前調用sync()接口。

            4 .等待無關(wait-free):慢的或者失效的client不得干預快速的client的請求,使得每個client都能有效的等待。

            5.原子性:更新只能成功或者失敗,沒有中間狀態。

            6 .順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息b前發布,則在所有Server上消息a都將在消息b前被發布;偏序是指如果一個消息b在消息a后被同一個發送者發布,a必將排在b前面。

            2 ZooKeeper的工作原理

            Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啟動或者在領導者崩潰后,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和leader的狀態同步以后,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。

            為了保證事務的順序一致性,zookeeper采用了遞增的事務id號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識leader關系是否改變,每次一個leader被選出來,它都會有一個新的epoch,標識當前屬于那個leader的統治時期。低32位用于遞增計數。

            每個Server在工作過程中有三種狀態:

            • LOOKING:當前Server不知道leader是誰,正在搜尋

            • LEADING:當前Server即為選舉出來的leader

            • FOLLOWING:leader已經選舉出來,當前Server與之同步

            2.1 選主流程

            當leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的leader,讓所有的Server都恢復到一個正確的狀態。Zk的選舉算法有兩種:一種是基于basic paxos實現的,另外一種是基于fast paxos算法實現的。系統默認的選舉算法為fast paxos。先介紹basic paxos流程:

            1. 1 .選舉線程由當前Server發起選舉的線程擔任,其主要功能是對投票結果進行統計,并選出推薦的Server;

            2. 2 .選舉線程首先向所有Server發起一次詢問(包括自己);

            3. 3 .選舉線程收到回復后,驗證是否是自己發起的詢問(驗證zxid是否一致),然后獲取對方的id(myid),并存儲到當前詢問對象列表中,最后獲取對方提議的leader相關信息(id,zxid),并將這些信息存儲到當次選舉的投票記錄表中;

            4. 4.  收到所有Server回復以后,就計算出zxid最大的那個Server,并將這個Server相關信息設置成下一次要投票的Server;

            5. 5.  線程將當前zxid最大的Server設置為當前Server要推薦的Leader,如果此時獲勝的Server獲得n/2 + 1的Server票數, 設置當前推薦的leader為獲勝的Server,將根據獲勝的Server相關信息設置自己的狀態,否則,繼續這個過程,直到leader被選舉出來。

            通過流程分析我們可以得出:要使Leader獲得多數Server的支持,則Server總數必須是奇數2n+1,且存活的Server的數目不得少于n+1.

            每個Server啟動后都會重復以上流程。在恢復模式下,如果是剛從崩潰狀態恢復的或者剛啟動的server還會從磁盤快照中恢復數據和會話信息,zk會記錄事務日志并定期進行快照,方便在恢復時進行狀態恢復。選主的具體流程圖如下所示:

            fast paxos流程是在選舉過程中,某Server首先向所有Server提議自己要成為leader,當其它Server收到提議以后,解決epoch和zxid的沖突,并接受對方的提議,然后向對方發送接受提議完成的消息,重復這個流程,最后一定能選舉出Leader。其流程圖如下所示:

            2.2 同步流程

            選完leader以后,zk就進入狀態同步過程。

            1. 1. leader等待server連接;

            2. 2 .Follower連接leader,將最大的zxid發送給leader;

            3. 3 .Leader根據follower的zxid確定同步點;

            4. 4 .完成同步后通知follower 已經成為uptodate狀態;

            5. 5 .Follower收到uptodate消息后,又可以重新接受client的請求進行服務了。

            流程圖如下所示:

            2.3 工作流程

            2.3.1 Leader工作流程

            Leader主要有三個功能:

            1. 1 .恢復數據;

            2. 2 .維持與Learner的心跳,接收Learner請求并判斷Learner的請求消息類型;

            3. 3 .Learner的消息類型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根據不同的消息類型,進行不同的處理。

            PING消息是指Learner的心跳信息;REQUEST消息是Follower發送的提議信息,包括寫請求及同步請求;ACK消息是Follower的對提議的回復,超過半數的Follower通過,則commit該提議;REVALIDATE消息是用來延長SESSION有效時間。
            Leader的工作流程簡圖如下所示,在實際實現中,流程要比下圖復雜得多,啟動了三個線程來實現功能。

            2.3.2 Follower工作流程

            Follower主要有四個功能:

            1. 1. 向Leader發送請求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);

            2. 2 .接收Leader消息并進行處理;

            3. 3 .接收Client的請求,如果為寫請求,發送給Leader進行投票;

            4. 4 .返回Client結果。

            Follower的消息循環處理如下幾種來自Leader的消息:

            1. 1 .PING消息: 心跳消息;

            2. 2 .PROPOSAL消息:Leader發起的提案,要求Follower投票;

            3. 3 .COMMIT消息:服務器端最新一次提案的信息;

            4. 4 .UPTODATE消息:表明同步完成;

            5. 5 .REVALIDATE消息:根據Leader的REVALIDATE結果,關閉待revalidate的session還是允許其接受消息;

            6. 6 .SYNC消息:返回SYNC結果到客戶端,這個消息最初由客戶端發起,用來強制得到最新的更新。

            Follower的工作流程簡圖如下所示,在實際實現中,Follower是通過5個線程來實現功能的。

            對于observer的流程不再敘述,observer流程和Follower的唯一不同的地方就是observer不會參加leader發起的投票。


            主流應用場景:

            Zookeeper的主流應用場景實現思路(除去官方示例) 

            (1)
            配置管理
            集中式的配置管理在應用集群中是非常常見的,一般商業公司內部都會實現一套集中的配置管理中心,應對不同的應用集群對于共享各自配置的需求,并且在配置變更時能夠通知到集群中的每一個機器。

            Zookeeper
            很容易實現這種集中式的配置管理,比如將APP1的所有配置配置到/APP1 znode下,APP1所有機器一啟動就對/APP1這個節點進行監控(zk.exist("/APP1",true)),并且實現回調方法Watcher,那么在zookeeper/APP1 znode節點下數據發生變化的時候,每個機器都會收到通知,Watcher方法將會被執行,那么應用再取下數據即可(zk.getData("/APP1",false,null));

            以上這個例子只是簡單的粗顆粒度配置監控,細顆粒度的數據可以進行分層級監控,這一切都是可以設計和控制的。
                 
            (2)集群管理 
            應用集群中,我們常常需要讓每一個機器知道集群中(或依賴的其他某一個集群)哪些機器是活著的,并且在集群機器因為宕機,網絡斷鏈等原因能夠不在人工介入的情況下迅速通知到每一個機器。

            Zookeeper
            同樣很容易實現這個功能,比如我在zookeeper服務器端有一個znode/APP1SERVERS,那么集群中每一個機器啟動的時候都去這個節點下創建一個EPHEMERAL類型的節點,比如server1創建/APP1SERVERS/SERVER1(可以使用ip,保證不重復)server2創建/APP1SERVERS/SERVER2,然后SERVER1SERVER2watch /APP1SERVERS這個父節點,那么也就是這個父節點下數據或者子節點變化都會通知對該節點進行watch的客戶端。因為EPHEMERAL類型節點有一個很重要的特性,就是客戶端和服務器端連接斷掉或者session過期就會使節點消失,那么在某一個機器掛掉或者斷鏈的時候,其對應的節點就會消失,然后集群中所有對/APP1SERVERS進行watch的客戶端都會收到通知,然后取得最新列表即可。

            另外有一個應用場景就是集群選
            master,一旦master掛掉能夠馬上能從slave中選出一個master,實現步驟和前者一樣,只是機器在啟動的時候在APP1SERVERS創建的節點類型變為EPHEMERAL_SEQUENTIAL類型,這樣每個節點會自動被編號

            我們默認規定編號最小的為
            master,所以當我們對/APP1SERVERS節點做監控的時候,得到服務器列表,只要所有集群機器邏輯認為最小編號節點為master,那么master就被選出,而這個master宕機的時候,相應的znode會消失,然后新的服務器列表就被推送到客戶端,然后每個節點邏輯認為最小編號節點為master,這樣就做到動態master選舉。

            Zookeeper 監視(Watches) 簡介

            Zookeeper C API 的聲明和描述在 include/zookeeper.h 中可以找到,另外大部分的 Zookeeper C API 常量、結構體聲明也在 zookeeper.h 中,如果如果你在使用 C API 是遇到不明白的地方,最好看看 zookeeper.h,或者自己使用 doxygen 生成 Zookeeper C API 的幫助文檔。

            Zookeeper 中最有特色且最不容易理解的是監視(Watches)。Zookeeper 所有的讀操作——getData()getChildren(), 和 exists() 都 可以設置監視(watch),監視事件可以理解為一次性的觸發器, 官方定義如下: a watch event is one-time trigger, sent to the client that set the watch, which occurs when the data for which the watch was set changes。對此需要作出如下理解:

            • (一次性觸發)One-time trigger

              當設置監視的數據發生改變時,該監視事件會被發送到客戶端,例如,如果客戶端調用了 getData("/znode1", true) 并且稍后 /znode1 節點上的數據發生了改變或者被刪除了,客戶端將會獲取到 /znode1 發生變化的監視事件,而如果 /znode1 再一次發生了變化,除非客戶端再次對 /znode1 設置監視,否則客戶端不會收到事件通知。

            • (發送至客戶端)Sent to the client

              Zookeeper 客戶端和服務端是通過 socket 進行通信的,由于網絡存在故障,所以監視事件很有可能不會成功地到達客戶端,監視事件是異步發送至監視者的,Zookeeper 本身提供了保序性(ordering guarantee):即客戶端只有首先看到了監視事件后,才會感知到它所設置監視的 znode 發生了變化(a client will never see a change for which it has set a watch until it first sees the watch event). 網絡延遲或者其他因素可能導致不同的客戶端在不同的時刻感知某一監視事件,但是不同的客戶端所看到的一切具有一致的順序。

            • (被設置 watch 的數據)The data for which the watch was set

              這意味著 znode 節點本身具有不同的改變方式。你也可以想象 Zookeeper 維護了兩條監視鏈表:數據監視和子節點監視(data watches and child watches) getData() and exists() 設置數據監視,getChildren() 設置子節點監視。 或者,你也可以想象 Zookeeper 設置的不同監視返回不同的數據,getData() 和 exists() 返回 znode 節點的相關信息,而 getChildren() 返回子節點列表。因此, setData() 會觸發設置在某一節點上所設置的數據監視(假定數據設置成功),而一次成功的 create() 操作則會出發當前節點上所設置的數據監視以及父節點的子節點監視。一次成功的 delete() 操作將會觸發當前節點的數據監視和子節點監視事件,同時也會觸發該節點父節點的child watch。

            Zookeeper 中的監視是輕量級的,因此容易設置、維護和分發。當客戶端與 Zookeeper 服務器端失去聯系時,客戶端并不會收到監視事件的通知,只有當客戶端重新連接后,若在必要的情況下,以前注冊的監視會重新被注冊并觸發,對于開發人員來說 這通常是透明的。只有一種情況會導致監視事件的丟失,即:通過 exists() 設置了某個 znode 節點的監視,但是如果某個客戶端在此 znode 節點被創建和刪除的時間間隔內與 zookeeper 服務器失去了聯系,該客戶端即使稍后重新連接 zookeeper服務器后也得不到事件通知。

            Zookeeper C API 常量與部分結構(struct)介紹

            與 ACL 相關的結構與常量:

            struct Id 結構為:

            struct Id {     char * scheme;     char * id; };

             

            struct ACL 結構為:

            struct ACL {     int32_t perms;     struct Id id; };

             

            struct ACL_vector 結構為:

            struct ACL_vector {     int32_t count;     struct ACL *data; };

             

            與 znode 訪問權限有關的常量

            • const int ZOO_PERM_READ; //允許客戶端讀取 znode 節點的值以及子節點列表。

            • const int ZOO_PERM_WRITE;// 允許客戶端設置 znode 節點的值。

            • const int ZOO_PERM_CREATE; //允許客戶端在該 znode 節點下創建子節點。

            • const int ZOO_PERM_DELETE;//允許客戶端刪除子節點。

            • const int ZOO_PERM_ADMIN; //允許客戶端執行 set_acl()。

            • const int ZOO_PERM_ALL;//允許客戶端執行所有操作,等價與上述所有標志的或(OR) 。

            與 ACL IDs 相關的常量

            • struct Id ZOO_ANYONE_ID_UNSAFE; //(‘world’,’anyone’)

            • struct Id ZOO_AUTH_IDS;// (‘auth’,’’)

            三種標準的 ACL

            • struct ACL_vector ZOO_OPEN_ACL_UNSAFE; //(ZOO_PERM_ALL,ZOO_ANYONE_ID_UNSAFE)

            • struct ACL_vector ZOO_READ_ACL_UNSAFE;// (ZOO_PERM_READ, ZOO_ANYONE_ID_UNSAFE)

            • struct ACL_vector ZOO_CREATOR_ALL_ACL; //(ZOO_PERM_ALL,ZOO_AUTH_IDS)

            與 Interest 相關的常量:ZOOKEEPER_WRITEZOOKEEPER_READ

            這 兩個常量用于標識感興趣的事件并通知 zookeeper 發生了哪些事件。Interest 常量可以進行組合或(OR)來標識多種興趣(multiple interests: write, read),這兩個常量一般用于 zookeeper_interest() 和 zookeeper_process()兩個函數中。

            與節點創建相關的常量:ZOO_EPHEMERALZOO_SEQUENCE

            zoo_create 函數標志,ZOO_EPHEMERAL 用來標識創建臨時節點,ZOO_SEQUENCE 用來標識節點命名具有遞增的后綴序號(一般是節點名稱后填充 10 位字符的序號,如 /xyz0000000000, /xyz0000000001, /xyz0000000002, ...),同樣地,ZOO_EPHEMERALZOO_SEQUENCE 可以組合。

            與連接狀態 Stat 相關的常量

            以下常量均與 Zookeeper 連接狀態有關,他們通常用作監視器回調函數的參數。

            ZOOAPI const int  ZOO_EXPIRED_SESSION_STATE
            ZOOAPI const int  ZOO_AUTH_FAILED_STATE
            ZOOAPI const int  ZOO_CONNECTING_STATE
            ZOOAPI const int  ZOO_ASSOCIATING_STATE
            ZOOAPI const int  ZOO_CONNECTED_STATE

            與監視類型(Watch Types)相關的常量

            以下常量標識監視事件的類型,他們通常用作監視器回調函數的第一個參數。

            Zookeeper C API 錯誤碼介紹 ZOO_ERRORS

            ZOK 

            正常返回

            ZSYSTEMERROR 

            系統或服務器端錯誤(System and server-side errors),服務器不會拋出該錯誤,該錯誤也只是用來標識錯誤范圍的,即大于該錯誤值,且小于 ZAPIERROR 都是系統錯誤。

            ZRUNTIMEINCONSISTENCY 

            運行時非一致性錯誤。

            ZDATAINCONSISTENCY 

            數據非一致性錯誤。

            ZCONNECTIONLOSS 

            Zookeeper 客戶端與服務器端失去連接

            ZMARSHALLINGERROR 

            在 marshalling 和 unmarshalling 數據時出現錯誤(Error while marshalling or unmarshalling data)

            ZUNIMPLEMENTED 

            該操作未實現(Operation is unimplemented)

            ZOPERATIONTIMEOUT 

            該操作超時(Operation timeout)

            ZBADARGUMENTS 

            非法參數錯誤(Invalid arguments)

            ZINVALIDSTATE 

            非法句柄狀態(Invliad zhandle state)

            ZAPIERROR 

            API 錯誤(API errors),服務器不會拋出該錯誤,該錯誤也只是用來標識錯誤范圍的,錯誤值大于該值的標識 API 錯誤,而小于該值的標識 ZSYSTEMERROR。

            ZNONODE 

            節點不存在(Node does not exist)

            ZNOAUTH 

            沒有經過授權(Not authenticated)

            ZBADVERSION 

            版本沖突(Version conflict)

            ZNOCHILDRENFOREPHEMERALS 

            臨時節點不能擁有子節點(Ephemeral nodes may not have children)

            ZNODEEXISTS 

            節點已經存在(The node already exists)

            ZNOTEMPTY 

            該節點具有自身的子節點(The node has children)

            ZSESSIONEXPIRED 

            會話過期(The session has been expired by the server)

            ZINVALIDCALLBACK 

            非法的回調函數(Invalid callback specified)

            ZINVALIDACL 

            非法的ACL(Invalid ACL specified)

            ZAUTHFAILED 

            客戶端授權失敗(Client authentication failed)

            ZCLOSING 

            Zookeeper 連接關閉(ZooKeeper is closing)

            ZNOTHING 

            并非錯誤,客戶端不需要處理服務器的響應(not error, no server responses to process)

            ZSESSIONMOVED 

            會話轉移至其他服務器,所以操作被忽略(session moved to another server, so operation is ignored)

             

            Watch事件類型:

             

            ZOO_CREATED_EVENT:節點創建事件,需要watch一個不存在的節點,當節點被創建時觸發,此watch通過zoo_exists()設置
            ZOO_DELETED_EVENT:節點刪除事件,此watch通過zoo_exists()或zoo_get()設置
            ZOO_CHANGED_EVENT:節點數據改變事件,此watch通過zoo_exists()或zoo_get()設置
            ZOO_CHILD_EVENT:子節點列表改變事件,此watch通過zoo_get_children()或zoo_get_children2()設置
            ZOO_SESSION_EVENT:會話失效事件,客戶端與服務端斷開或重連時觸發
            ZOO_NOTWATCHING_EVENT:watch移除事件,服務端出于某些原因不再為客戶端watch節點時觸發


            posted on 2015-01-31 10:39 楊粼波 閱讀(3913) 評論(0)  編輯 收藏 引用

            WWW婷婷AV久久久影片| 精品人妻伦九区久久AAA片69| 久久中文字幕人妻熟av女| 狠狠色伊人久久精品综合网| 97r久久精品国产99国产精| 久久精品夜夜夜夜夜久久| 欧美喷潮久久久XXXXx| 丰满少妇高潮惨叫久久久| 国产精品毛片久久久久久久| 久久亚洲AV成人出白浆无码国产| 亚洲综合伊人久久综合| 亚洲av伊人久久综合密臀性色| 中文字幕精品无码久久久久久3D日动漫 | 无码国内精品久久人妻麻豆按摩| 久久精品无码免费不卡| 久久国产影院| 国产精品成人久久久| 人妻少妇久久中文字幕| 青青草原1769久久免费播放| 国产免费福利体检区久久| 亚洲午夜无码久久久久小说| 亚洲国产另类久久久精品小说| 久久久久久毛片免费播放| a级毛片无码兔费真人久久| 色综合久久天天综线观看| 性欧美大战久久久久久久久| 久久久久综合网久久| 久久伊人精品青青草原日本| 亚洲愉拍99热成人精品热久久| 精品久久一区二区| 色欲综合久久躁天天躁| 成人国内精品久久久久一区| 久久久久亚洲爆乳少妇无| 一本色道久久综合狠狠躁| 精品无码人妻久久久久久| 久久精品国产99久久久古代| 亚洲嫩草影院久久精品| 亚洲国产精品无码久久久蜜芽 | 久久精品一本到99热免费| 久久天堂电影网| 国产成人无码精品久久久性色|