什麼是Zookeeper?(動態的服務註冊和發現、Master選舉、分散式鎖)
轉自:碼農翻身(微訊號:coderising)
張大胖所在的公司這幾年發展得相當不錯,業務激增,人員也迅速擴充套件,轉眼之間,張大胖已經成為公司的“資深”員工了,更重要的是,經過這些年的不懈努力,他終於坐上了架構師的寶座。
但是大胖很快發現,這架構師真不是好當的,技術選型、架構設計,尤其是大家搞不定的技術難點,最終都得自己扛起來。溝通、說服、妥協、甚至爭吵都是家常便飯,比自己之前單純做開發的時候難多了。
公司的IT系統早已經從單機轉向了分散式,分散式系統帶來了巨大的挑戰。這週一剛上班,張大胖的郵箱裡已經塞滿了緊急郵件。
1、小梁的郵件
小梁的郵件裡說了一個RPC呼叫的問題,本來公司的架構組開發了一個RPC框架讓各個組去使用,但是各開發小組紛紛抱怨:這個RPC框架不支援動態的服務註冊和發現。
張大胖一看這個圖就明白怎麼回事了,為了支援高併發,OrderService被部署了4份,每個客戶端都儲存了一份服務提供者的列表,但是這個列表是靜態的(在配置檔案中寫死的),如果服務的提供者發生了變化,例如有些機器down了,或者又新增了OrderService的例項,客戶端根本不知道,可能還在傻乎乎地嘗試那些已經壞掉的例項呢!
想要得到最新的服務提供者的URL列表,必須得手工更新配置檔案才行,確實很不方便。
對於這樣的問題,大胖馬上就意識到,這就是客戶端和服務提供者的緊耦合啊。
想解除這個耦合,非得增加一箇中間層不可!
張大胖想到,應該有個註冊中心,首先給這些服務命名(例如orderService),其次那些OrderService 都可以在這裡註冊一下,客戶端就到這裡來查詢,只需要給出名稱orderService,註冊中心就可以給出一個可以使用的url, 再也不怕服務提供者的動態增減了。
不知道是不是下意識的行為, 張大胖把這個註冊中心的資料結構設計成為了一個樹形結構:
/orderService 表達了一個服務的概念, 下面的每個節點表示了一個服務的例項。 例如/orderService/node2表示的order service 的第二個例項, 每個節點上可以記錄下該例項的url , 這樣就可以查詢了。
當然這個註冊中心必須得能和各個服務例項通訊,如果某個服務例項不幸down掉了,那它在樹結構中對於的節點也必須刪除, 這樣客戶端就查詢不到了。
嗯,可以在註冊中心和各個服務例項直接建立Session, 讓各個服務例項定期地傳送心跳,如果過了特定時間收不到心跳,就認為這個服務例項掛掉了,Session 過期, 把它從樹形結構中刪除。
張大胖把自己的想法回覆了小梁,接著看小王的郵件。
2、小王的Master選舉
小王郵件中說的是三個Batch Job的協調問題,這三個Batch Job 部署在三臺機器上,但是這三個Batch Job同一個時刻只能有一個執行,如果其中某個不幸down掉,剩下的兩個就需要做個選舉,選出來的那個Batch Job 需要“繼承遺志”,繼續工作。
其實這就是一個Master的選舉問題,張大胖一眼就看出了本質。
只是為了選舉出Master, 這三個Batch Job 需要互通有無,互相協調才行,這就麻煩了!
要不弄個資料庫表? 利用資料庫表主鍵不能衝突的特性,讓這三個Batch Job 都向同一個表中插入同樣的資料,誰先成功誰就是Master !
可是如果搶到Master的那個Batch Job掛掉了,別人永遠就搶不到了! 因為記錄已經存在了, 別的Batch Job 沒法插入資料了!
嗯,還得加上定期更新的機制,如果一段時間內沒有更新就認為Master死掉了,別的Batch Job可以繼續搶..... 不過這麼做好麻煩!
換個思路,讓他們也去一個註冊中心去大吼一聲:“我是master!”, 誰的聲音大誰是Master 。
其實不是吼一聲,三個Batch Job啟動以後,都去註冊中心爭搶著去建立一個樹的節點(例如/master ),誰建立成功誰就是Master ( 當然註冊中心必須保證只能建立成功一次,其他請求就失敗了),其他兩個Batch Job就對這個節點虎視眈眈地監控,如果這個節點被刪除,就開始新一輪爭搶,去建立那個/master節點。
什麼時候節點會被刪除呢? 對,就是當前Master的機器down掉了 ! 很明顯,註冊中心也需要和各個機器通訊,看看他們是否活著。
等等,這裡還有一個複雜的情況, 如果機器1並沒有死掉,只是和註冊中心長時間連線不上,註冊中心會發現Session超時,會把機器1建立的/master刪除。 讓機器2和機器3去搶,如果機器3成為了master, 開始執行Batch Job, 但是機器1並不知道自己被解除了Master的職務, 還在努力的執行Batch Job,這就衝突了!
看來機器1必須得能感知到和註冊中心的連線斷開了,需要停止Batch Job才行,等到和註冊中心再次連線上以後,才知道自己已經不是master了,老老實實地等下一次機會吧。
無論哪種方案,實現起來都很麻煩,這該死的分散式!
先把思路給小王回覆一下吧。接著看小蔡的郵件。
3、小蔡的分散式鎖
小蔡的郵件裡說的問題更加麻煩,有多個不同的系統(當然是分佈在不同的機器上!),要對同一個資源操作。
這要是在一個機器上,使用某個語言內建的鎖就可以搞定,例如Java的synchronized , 但是現在是分散式啊,程式都跑在不同機器的不同程式中, synchcronized一點用都沒有了!
這是個分散式鎖的問題啊!
能不能考慮下Master選舉問題中的方式,讓大家去搶? 誰能搶先在註冊中心建立一個
/distribute_lock的節點就表示搶到這個鎖了,然後讀寫資源,讀寫完以後就把
/distribute_lock節點刪除,大家再來搶。
可是這樣的話某個系統可能會多次搶到,不太公平。
如果讓這些系統在註冊中心的/distribute_lock下都建立子節點, 然後給每個系統一個編號,會是這個樣子:
然後各個系統去檢查自己的編號,誰的編號小就認為誰持有了鎖, 例如系統1。
系統1持有了鎖,就可以對共享資源進行操作了, 操作完成以後process_01這個節點刪除, 再建立一個新的節點(編號變成process_04了):
其他系統一看,編號為01的刪除了,再看看誰是最小的吧,是process_02,那就認為系統2持有了鎖,可以對共享資源操作了。 操作完成以後也要把process_02節點刪除,建立新的節點。這時候process_03就是最小的了,可以持有鎖了。
這樣迴圈往復下去...... 分散式鎖就可以實現了!
看看,我設計的這個集中式的樹形結構很不錯吧,能解決各種各樣的問題! 張大胖不由得意起來。
好,先把這個想法告訴小蔡,實現細節下午開個會討論。
4、Zookeeper
正準備回覆小蔡的時候,大胖突然意識到,自己漏了一個重要的點,那就是 註冊中心的高可用性,如果註冊中心只有那麼一臺機器,一旦掛掉,整個系統就玩完了。
這個註冊中心也得有多臺機器來保證高可用性,那個自己頗為得意的樹形結構也需要在多個機器之間同步啊,要是有機器掛掉怎麼辦? 通訊超時怎麼辦? 樹形結構的資料怎麼在各個機器之間保證強一致性?
小王、小梁、小蔡的原始問題沒有解決,單單是這個註冊中心就要了命了。 以自己公司的技術實力,搞出一套這樣的註冊中心簡直是Mission Impossible !
大胖趕緊上網搜尋,看看有沒有類似的解決方案,讓大胖感到萬分幸運的是,果然有一個,叫做 Zookeeper !
Zookeeper 所使用的樹形結構和自己想象的非常類似,更重要的是,人家實現了樹形結構資料在多臺機器之間的可靠複製,達到了資料在多臺機器之間的一致性。並且這多臺機器中如果有部分掛掉了/或者由於網路原因無法連線上了, 整個系統還可以工作。
大胖趕快去看Zookeeper的關鍵概念和API:
-
Session : 表示某個客戶系統(例如Batch Job)和ZooKeeper之間的連線會話, Batch Job連上ZooKeeper以後會週期性地傳送心跳資訊, 如果Zookeepr在特定時間內收不到心跳,就會認為這個Batch Job已經死掉了, Session 就會結束。
-
znode : 樹形結構中的每個節點叫做znode, 按型別可以分為 永久的znode(除非主動刪除,否則一直存在), 臨時的znode(Session結束就會刪除)和 順序znode(就是小蔡的分散式鎖中的process_01,process_02…)。
-
Watch : 某個客戶系統(例如Batch Job)可以監控znode, znode節點的變化(刪除,修改資料等)都可以通知Batch Job, 這樣Batch Job可以採取相應的動作,例如爭搶著去建立節點。
嗯,這些概念和介面應該可以滿足我們的要求了, 就是它了,下午召集大家開會開始學習Zookeeper吧。
後記:本文從使用者的角度描述了Zookeeper有什麼用處,至於它內部是如何工作,那是另外一個Big topic了,我們以後再講。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69947338/viewspace-2656389/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Zookeeper實現服務註冊/發現
- 什麼是微服務架構?什麼是服務註冊與發現微服務架構
- 分散式(一) 搞定服務註冊與發現分散式
- Web Api 基於Zookeeper的服務註冊與發現WebAPI
- 【分散式】Zookeeper的Leader選舉分散式
- 分散式鎖為什麼要選擇Zookeeper而不是Redis?分散式Redis
- 什麼是分散式鎖?分散式
- 【分散式鎖的演化】什麼是鎖?分散式
- ZooKeeper分散式鎖的實現分散式
- 使用redis和zookeeper實現分散式鎖Redis分散式
- 服務註冊與發現的原理和實現
- 【zookeeper】zookeeper分散式鎖分散式
- 分散式中幾種服務註冊與發現元件的原理與比較分散式元件
- Dubbo+zookeeper實現分散式服務框架分散式框架
- 分散式鎖之Zookeeper實現分散式
- 分散式鎖實現(二):Zookeeper分散式
- 6 zookeeper實現分散式鎖分散式
- 我是服務的執政官-服務發現和註冊工具consul簡介
- Dubbo+Nacos實現服務註冊和發現
- 用 etcd 實現服務註冊和發現
- zookeeper分散式鎖分散式
- ZooKeeper 分散式鎖分散式
- 十九、Redis分散式鎖、Zookeeper分散式鎖Redis分散式
- Nacos服務註冊與發現
- zookeeper分散式鎖,你用php是如何實現的呀分散式PHP
- 基於redis和zookeeper的分散式鎖實現方式Redis分散式
- zookeeper 分散式鎖的原理及實現分散式
- 基於 Zookeeper 的分散式鎖實現分散式
- 聊聊微服務的服務註冊與發現!微服務
- NodeJs服務註冊與服務發現實現NodeJS
- 動態註冊和靜態註冊
- 靜態註冊和動態註冊
- oracle的靜態註冊和動態註冊Oracle
- 微服務4:服務註冊與發現微服務
- 【微服務之Eureka服務註冊發現】微服務
- Nacos服務註冊與發現的原理
- go微服務系列(二) - 服務註冊/服務發現Go微服務
- 微服務之服務註冊和發現的可行性方案微服務