| zookeeper分布式鎖原理:https://my.oschina.net/u/3492343/blog/2992492 zookeeper的樹(shù)形結(jié)構(gòu) 
 zookeeper節(jié)點(diǎn)特性 1.同級(jí)節(jié)點(diǎn)唯一性 2.臨時(shí)節(jié)點(diǎn)和持久化節(jié)點(diǎn) 3.有序節(jié)點(diǎn)和無(wú)序節(jié)點(diǎn) 4.臨時(shí)節(jié)點(diǎn)下不能存在子節(jié)點(diǎn) 集群搭建server.id = ip:port:port 在zoo.cfg里面加入以下 server.1=192.168.182.128:2888:3888 192.168.182.128:2888是完成數(shù)據(jù)同步的節(jié)點(diǎn) 192.168.182.128:3888是選舉leader的節(jié)點(diǎn) 自己練習(xí)的話關(guān)閉防火墻service iptables stop,生產(chǎn)就開(kāi)放相關(guān)端口, 在data目錄下創(chuàng)建myid(id一定要和上面id對(duì)應(yīng)的ip對(duì)應(yīng)) vim /tmp/zookeeper/myid 里面加入:1或2或3 zoo.cfg里面的參數(shù) 1.tickTime=2000 心跳時(shí)間 2.initLimit=10 初始化同步數(shù)據(jù)的時(shí)候10個(gè)心跳時(shí)間 3.syncLimit=5 心跳檢測(cè)的最大延遲 4.dataDir = /x 同步數(shù)據(jù)存儲(chǔ)的位置 5.clientPort=2181 客戶(hù)端和服務(wù)端連接的端口 [zk: localhost:2181(CONNECTED) 1] get /mic mic cZxid = 0x100000002 ctime = Tue Dec 03 21:08:23 CST 2019 mZxid = 0x100000002 mtime = Tue Dec 03 21:08:23 CST 2019 pZxid = 0x100000002 //子節(jié)點(diǎn)變更以后才會(huì)產(chǎn)生pzxid的影響 cversion = 0 //類(lèi)似樂(lè)觀鎖,當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)版本號(hào) dataVersion = 0 //當(dāng)前數(shù)據(jù)內(nèi)容的版本號(hào) aclVersion = 0 //當(dāng)前節(jié)點(diǎn)ACL變更的版本號(hào) ephemeralOwner = 0x0 //綁定當(dāng)前會(huì)話的信息 dataLength = 3 //當(dāng)前數(shù)據(jù)長(zhǎng)度 numChildren = 0 //子節(jié)點(diǎn)數(shù)量 通過(guò)版本號(hào)來(lái)控制并發(fā)情況下的數(shù)據(jù)修改 ACL (access control list) 權(quán)限控制 CREATE/READ/WRITE/DELETE/ADMIN 五種權(quán)限 
 watch機(jī)制 
 zookeeper的應(yīng)用場(chǎng)景 分布式協(xié)調(diào)服務(wù) 配置中心(aoolication.properties,數(shù)據(jù)庫(kù)配置,常量配置等),這個(gè)配置中心統(tǒng)一維護(hù)配置 負(fù)載均衡(知道機(jī)器的狀態(tài),選舉master) 分布式鎖 zookeeper主要是解決分布式環(huán)境下的服務(wù)協(xié)調(diào)問(wèn)題而產(chǎn)生的,如果我們要去實(shí)現(xiàn)一個(gè)zookeeper這樣的中間件,需要做什么? 1.防止單點(diǎn)故障 如果要防止zookeeper這個(gè)中間件的單點(diǎn)故障,那就勢(shì) 必要做集群。而且這個(gè)集群如果要滿(mǎn)足高性能要求的話, 還得是一個(gè)高性能高可用的集群。高性能意味著這個(gè)集 群能夠分擔(dān)客戶(hù)端的請(qǐng)求流量,高可用意味著集群中的 某一個(gè)節(jié)點(diǎn)宕機(jī)以后,不影響整個(gè)集群的數(shù)據(jù)和繼續(xù)提 供服務(wù)的可能性 結(jié)論:這個(gè)中間件需要考慮到集群,還需要分?jǐn)偪蛻?hù)端的請(qǐng)求流量 2.如果要滿(mǎn)足這樣的一個(gè)高 性能集群,我們最直觀的想法應(yīng)該是,每個(gè)節(jié)點(diǎn)都能接 收到請(qǐng)求,并且每個(gè)節(jié)點(diǎn)的數(shù)據(jù)都必須要保持一致。要 實(shí)現(xiàn)各個(gè)節(jié)點(diǎn)的數(shù)據(jù)一致性,就勢(shì)必要一個(gè)leader節(jié)點(diǎn) 負(fù)責(zé)協(xié)調(diào)和數(shù)據(jù)同步操作。這個(gè)我想大家都知道,如果 在這樣一個(gè)集群中沒(méi)有l(wèi)eader節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都可以接收所有請(qǐng)求,那么這個(gè)集群的數(shù)據(jù)同步的復(fù)雜度是非常 大 結(jié)論:所以這個(gè)集群中設(shè)計(jì)到數(shù)據(jù)同步以及會(huì)存在leader節(jié)點(diǎn) 3.如何在這些節(jié)點(diǎn)中選舉出leader節(jié)點(diǎn),以及l(fā)eader掛了以后,如何恢復(fù)? 結(jié)論:zookeeper用了基于paxos理論所衍生出來(lái)的ZAB協(xié)議 4. leader 節(jié)點(diǎn)如何和其他節(jié)點(diǎn)保證數(shù)據(jù)一致性,并且要求 是強(qiáng)一致的。在分布式系統(tǒng)中,每一個(gè)機(jī)器節(jié)點(diǎn)雖然都 能夠明確知道自己進(jìn)行的事務(wù)操作過(guò)程是成功和失敗, 但是卻無(wú)法直接獲取其他分布式節(jié)點(diǎn)的操作結(jié)果。所以 當(dāng)一個(gè)事務(wù)操作涉及到跨節(jié)點(diǎn)的時(shí)候,就需要用到分布 式事務(wù),分布式事務(wù)的數(shù)據(jù)一致性協(xié)議有 2PC 協(xié)議和 3PC協(xié)議。 關(guān)于2PC提交(Two Phase Commitment Protocol)當(dāng)一個(gè)事務(wù)操作需要跨越多個(gè)分布式節(jié)點(diǎn)的時(shí)候,為了保持事務(wù)處理的ACID 特性,就需要引入一個(gè)“協(xié)調(diào)者”(TM)來(lái)統(tǒng)一調(diào)度所有分 布式節(jié)點(diǎn)的執(zhí)行邏輯,這些被調(diào)度的分布式節(jié)點(diǎn)的執(zhí)行邏輯,這些被調(diào)度的分布式節(jié)點(diǎn)被稱(chēng)為AP。 TM負(fù)責(zé)調(diào)度AP的行為,并最終決定這些AP是否要把事 務(wù)真正進(jìn)行提交;因?yàn)檎麄€(gè)事務(wù)是分為兩個(gè)階段提交,所 以叫2pc 
 
 階段一:提交事務(wù)請(qǐng)求(投票)  zookeeper的集群在zookeeper中,客戶(hù)端會(huì)隨機(jī)連接到zookeeper集群中的一個(gè)節(jié)點(diǎn),如果是讀請(qǐng)求,就直接從當(dāng)前節(jié)點(diǎn)中讀取數(shù)據(jù),如果是寫(xiě)請(qǐng)求,那么請(qǐng)求會(huì)被轉(zhuǎn)發(fā)給leader提交事務(wù),然后leader會(huì)廣播事務(wù),只要有超過(guò)半數(shù)節(jié)點(diǎn)寫(xiě)入成功,那么寫(xiě)請(qǐng)求就會(huì)被提交(類(lèi)2PC事務(wù)) 所有的事務(wù)請(qǐng)求必須由一個(gè)全局唯一的服務(wù)器來(lái)協(xié)調(diào)處理,這個(gè)服務(wù)器就是Leader服務(wù)器,其他的服務(wù)器就是follower。leader服務(wù)器把客戶(hù)端的事務(wù)請(qǐng)求轉(zhuǎn)化成一個(gè)事務(wù)(Proposal)提議,并把這個(gè)Proposal分發(fā)給集群中的所有follower服務(wù)器。之后leader服務(wù)器需要等待所有follower服務(wù)器的反饋,一旦超過(guò)半數(shù)的follower服務(wù)器進(jìn)行了正確的反饋,那么leader就會(huì)再次向所有的follower服務(wù)器發(fā)送Commit消息,要求各個(gè)follower節(jié)點(diǎn)對(duì)前面的一個(gè)Proposal進(jìn)行提交 集群角色Leader 角色Leader服務(wù)器是整個(gè)zookeeper集群的核心,主要的工作 任務(wù)有兩項(xiàng) 1. 事物請(qǐng)求的唯一調(diào)度和處理者,保證集群事物處理的順 序性 2. 集群內(nèi)部各服務(wù)器的調(diào)度者 Follower 角色Follower角色的主要職責(zé)是 1. 處理客戶(hù)端非事物請(qǐng)求、轉(zhuǎn)發(fā)事物請(qǐng)求給leader服務(wù)器 2. 參與事物請(qǐng)求 Proposal 的投票(需要半數(shù)以上服務(wù)器 通過(guò)才能通知leader commit數(shù)據(jù); Leader發(fā)起的提案, 要求Follower投票) 3. 參與Leader選舉的投票 Observer 角色Observer 是 zookeeper3.3 開(kāi)始引入的一個(gè)全新的服務(wù)器 角色,從字面來(lái)理解,該角色充當(dāng)了觀察者的角色。 觀察zookeeper集群中的最新?tīng)顟B(tài)變化并將這些狀態(tài)變化 同步到 observer 服務(wù)器上。Observer 的工作原理與 follower 角色基本一致,而它和 follower 角色唯一的不同 在于 observer 不參與任何形式的投票,包括事物請(qǐng)求 Proposal的投票和leader選舉的投票。簡(jiǎn)單來(lái)說(shuō),observer 服務(wù)器只提供非事物請(qǐng)求服務(wù),通常在于不影響集群事物 處理能力的前提下提升集群非事物處理的能力 集群組成通常zookeeper是由2n 1臺(tái)server組成,每個(gè)server都 知道彼此的存在。對(duì)于2n 1臺(tái)server,只要有n 1臺(tái)(大 多數(shù))server可用,整個(gè)系統(tǒng)保持可用。我們已經(jīng)了解到, 一個(gè)zookeeper集群如果要對(duì)外提供可用的服務(wù),那么集 群中必須要有過(guò)半的機(jī)器正常工作并且彼此之間能夠正常 通信,基于這個(gè)特性,如果向搭建一個(gè)能夠允許 F 臺(tái)機(jī)器 down 掉的集群,那么就要部署 2*F 1 臺(tái)服務(wù)器構(gòu)成的 zookeeper 集群。因此 3 臺(tái)機(jī)器構(gòu)成的 zookeeper 集群, 能夠在掛掉一臺(tái)機(jī)器后依然正常工作。一個(gè) 5 臺(tái)機(jī)器集群 的服務(wù),能夠?qū)?2 臺(tái)機(jī)器怪調(diào)的情況下進(jìn)行容災(zāi)。如果一 ZAB協(xié)議ZAB(Zookeeper Atomic Broadcast) 協(xié)議是為分布式協(xié) 調(diào)服務(wù) ZooKeeper 專(zhuān)門(mén)設(shè)計(jì)的一種支持崩潰恢復(fù)的原子 廣播協(xié)議。在 ZooKeeper 中,主要依賴(lài) ZAB 協(xié)議來(lái)實(shí)現(xiàn) 分布式數(shù)據(jù)一致性,基于該協(xié)議,ZooKeeper 實(shí)現(xiàn)了一種 主備模式的系統(tǒng)架構(gòu)來(lái)保持集群中各個(gè)副本之間的數(shù)據(jù)一 致性。 zab協(xié)議介紹 ZAB協(xié)議包含兩種基本模式,分別是 1.崩潰恢復(fù) 2.原子廣播 當(dāng)整個(gè)集群在啟動(dòng)時(shí),或者當(dāng)leader節(jié)點(diǎn)出現(xiàn)網(wǎng)絡(luò)中斷、崩潰等情況時(shí),ZAB協(xié)議就會(huì)進(jìn)入恢復(fù)模式并選舉產(chǎn)生新的leader,當(dāng)leader服務(wù)器選舉出來(lái)后,并集群中有過(guò)半的機(jī)器和該leader節(jié)點(diǎn)完成數(shù)據(jù)同步后(同步指的是數(shù)據(jù)同步,用來(lái)保證集群中過(guò)半的機(jī)器能夠和leader服務(wù)器的數(shù)據(jù)狀態(tài)保持一致),ZAB協(xié)議就會(huì)退出恢復(fù)模式 當(dāng)集群中已經(jīng)有過(guò)半的follower節(jié)點(diǎn)完成了和leader狀態(tài)同步以后,那么整個(gè)集群就進(jìn)入了消息廣播模式。這個(gè)時(shí)候。在leader節(jié)點(diǎn)正常工作時(shí),啟動(dòng) 一臺(tái)新的服務(wù)器加入到集群,那這個(gè)服務(wù)器會(huì)直接進(jìn)入數(shù)據(jù)恢復(fù)模式,和leader節(jié)點(diǎn)進(jìn)行數(shù)據(jù)同步。同步完成后即可正常對(duì)外提供非事務(wù)請(qǐng)求的處理 消息廣播的實(shí)現(xiàn)原理如果大家了解分布式事務(wù)的2pc和3pc協(xié)議的話(不了解 也沒(méi)關(guān)系,我們后面會(huì)講),消息廣播的過(guò)程實(shí)際上是一個(gè) 簡(jiǎn)化版本的二階段提交過(guò)程 1. leader 接收到消息請(qǐng)求后,將消息賦予一個(gè)全局唯一的 64位自增id,叫:zxid,通過(guò)zxid的大小比較既可以實(shí) 現(xiàn)因果有序這個(gè)特征 2. leader為每個(gè)follower準(zhǔn)備了一個(gè)FIFO隊(duì)列(通過(guò)TCP 協(xié)議來(lái)實(shí)現(xiàn),以實(shí)現(xiàn)了全局有序這一個(gè)特點(diǎn))將帶有zxid 3. 當(dāng)follower接收到proposal,先把proposal寫(xiě)到磁盤(pán), 寫(xiě)入成功以后再向leader回復(fù)一個(gè)ack 4. 當(dāng)leader接收到合法數(shù)量(超過(guò)半數(shù)節(jié)點(diǎn))的ACK后, leader就會(huì)向這些follower發(fā)送commit命令,同時(shí)會(huì) 在本地執(zhí)行該消息 5. 當(dāng) follower 收到消息的 commit命令以后,會(huì)提交該消 息  leader 的投票過(guò)程,不需要 Observer 的 ack,也就是 Observer不需要參與投票過(guò)程,但是Observer必須要同 步 Leader 的數(shù)據(jù)從而在處理請(qǐng)求的時(shí)候保證數(shù)據(jù)的一致 性 崩潰恢復(fù)(數(shù)據(jù)恢復(fù))ZAB 協(xié)議的這個(gè)基于原子廣播協(xié)議的消息廣播過(guò)程,在正 常情況下是沒(méi)有任何問(wèn)題的,但是一旦 Leader 節(jié)點(diǎn)崩潰, 或者由于網(wǎng)絡(luò)問(wèn)題導(dǎo)致 Leader 服務(wù)器失去了過(guò)半的 1. 已經(jīng)被處理的消息不能丟失 當(dāng) leader 收到合法數(shù)量 follower 的 ACKs 后,就向 各個(gè) follower 廣播 COMMIT 命令,同時(shí)也會(huì)在本地 執(zhí)行 COMMIT 并向連接的客戶(hù)端返回「成功」。但是如 果在各個(gè) follower 在收到 COMMIT 命令前 leader 就掛了,導(dǎo)致剩下的服務(wù)器并沒(méi)有執(zhí)行都這條消息。 
 leader 對(duì)事務(wù)消息發(fā)起 commit 操作,但是該消息在 follower1 上執(zhí)行了,但是 follower2 還沒(méi)有收到 commit, 就已經(jīng)掛了,而實(shí)際上客戶(hù)端已經(jīng)收到該事務(wù)消息處理成功的回執(zhí)了。所以在zab協(xié)議下需要保證所有機(jī)器都要執(zhí) 行這個(gè)事務(wù)消息 2. 被丟棄的消息不能再次出現(xiàn)  1. 如果 leader 選舉算法能夠保證新選舉出來(lái)的 Leader 服 務(wù)器擁有集群中所有機(jī)器最高編號(hào)(ZXID最大)的事務(wù) Proposal,那么就可以保證這個(gè)新選舉出來(lái)的Leader一 定具有已經(jīng)提交的提案。因?yàn)樗刑岚副?COMMIT 之 前必須有超過(guò)半數(shù)的 follower ACK,即必須有超過(guò)半數(shù) 節(jié)點(diǎn)的服務(wù)器的事務(wù)日志上有該提案的 proposal,因此,只要有合法數(shù)量的節(jié)點(diǎn)正常工作,就必然有一個(gè)節(jié)點(diǎn)保 存了所有被 COMMIT 消息的 proposal 狀態(tài) 另外一個(gè),zxid是64位,高32位是epoch編號(hào),每經(jīng)過(guò) 一次 Leader 選舉產(chǎn)生一個(gè)新的 leader,新的 leader 會(huì)將 epoch 號(hào) 1,低 32 位是消息計(jì)數(shù)器,每接收到一條消息 這個(gè)值 1,新 leader選舉后這個(gè)值重置為0.這樣設(shè)計(jì)的好 處在于老的leader掛了以后重啟,它不會(huì)被選舉為leader, 因此此時(shí)它的 zxid 肯定小于當(dāng)前新的 leader。當(dāng)老的 leader 作為 follower 接入新的 leader 后,新的 leader 會(huì) 讓它將所有的擁有舊的 epoch 號(hào)的未被 COMMIT 的 proposal 清除 關(guān)于 ZXID  epoch :可以理解為當(dāng)前集群所處的年代或者周期,每個(gè) leader 就像皇帝,都有自己的年號(hào),所以每次改朝換代, leader 變更之后,都會(huì)在前一個(gè)年代的基礎(chǔ)上加 1 。這樣 就算舊的 leader 崩 潰 恢 復(fù) 之 后 ,也 沒(méi) 有 人 聽(tīng) 他 的 了 ,因 為 follower 只聽(tīng)從當(dāng)前年代的 leader 的命令。 * 1. 啟動(dòng)一個(gè)zookeeper集群。 2. 在/tmp/zookeeper/VERSION-2 路徑下會(huì)看到一個(gè) currentEpoch文件。文件中顯示的是當(dāng)前的epoch 3. 把 leader 節(jié)點(diǎn)停機(jī),這個(gè)時(shí)候在看 currentEpoch 會(huì)有 變化。 隨著每次選舉新的leader,epoch都會(huì)發(fā)生變化 leader 選舉Leader選舉會(huì)分兩個(gè)過(guò)程  服務(wù)器啟動(dòng)時(shí)的 leader 選舉每個(gè)節(jié)點(diǎn)啟動(dòng)的時(shí)候狀態(tài)都是 LOOKING,處于觀望狀態(tài), 接下來(lái)就開(kāi)始進(jìn)行選主流程  運(yùn)行過(guò)程中的 leader 選舉當(dāng)集群中的 leader 服務(wù)器出現(xiàn)宕機(jī)或者不可用的情況時(shí), 那么整個(gè)集群將無(wú)法對(duì)外提供服務(wù),而是進(jìn)入新一輪的 Leader 選舉,服務(wù)器運(yùn)行期間的 Leader 選舉和啟動(dòng)時(shí)期 的Leader選舉基本過(guò)程是一致的。  事件機(jī)制watcher特性:當(dāng)數(shù)據(jù)發(fā)生變化的時(shí)候,zookeeper會(huì)產(chǎn)生一個(gè)watcher事件,并且會(huì)發(fā)送到客戶(hù)端。但是客戶(hù)端只會(huì)收到一次通知。如果后續(xù)這個(gè)節(jié)點(diǎn)再次發(fā)生變化,那么之前設(shè)置watcher的客戶(hù)端不會(huì)再次收到消息。(watcher是一次性的操作)??梢酝ㄟ^(guò)循環(huán)監(jiān)聽(tīng)去達(dá)到永久監(jiān)聽(tīng)效果 如何注冊(cè)事件機(jī)制通過(guò)這三個(gè)操作來(lái)綁定事件:getData\Exists\getChildren 如何觸發(fā)事件?凡是事務(wù)類(lèi)型的操作,都會(huì)觸發(fā)監(jiān)聽(tīng)事件。create /delete /setDat watcher 事件類(lèi)型None (-1),           客戶(hù)端鏈接狀態(tài)發(fā)生變化的時(shí)候,會(huì)收到 none 的事件  | 
|  | 
來(lái)自: 印度阿三17 > 《開(kāi)發(fā)》