zookeeper之於分佈式系統的意義

分佈式系統中普遍存在的問題 

  • 可用性

        現在很多時候我們的服務需要7*24小時工作,假如一臺機器掛了,我們希望能有其它機器頂替它繼續工作。此類問題現在多采用master-salve模式,也就是常說的主從模式,正常情況下主機提供服務,備機負責監聽主機狀態,當主機異常時,可以自動切換到備機繼續提供服務(這裏有點兒類似於數據庫主庫跟備庫,備機正常情況下只監聽,不工作),這個切換過程中選出下一個主機的過程就是master選舉。

 

 

        舉個栗子,比如我們利用nginx作爲代理服務器,把用戶的訪問代理到Web服務器上,如下圖:

試想,nginx綁定了一個VIP(虛擬IP地址),然後把用戶請求代理到Web服務器上,那麼如果nginx出現了故障,不能轉發客戶請求給Web服務器了,於是整個系統就無法對外處理用戶的請求了,系統處於一種不可用的狀態,這就是稱之爲單點故障。面臨這種單點故障,我們應該怎麼解決呢?也就是我們必須對外提供高可用(High Availability)的服務。一種解決辦法就是nginx部署多臺(例如2臺)服務器,當一臺故障後另一臺對外提供服務,這就是經典的Master-Slave的機制。如下圖,他們之間使用一個PING/PONG機制,去探測對方是否存在,如果收不到對方的PING或者PONG信息,那麼就認爲對端掛掉了,比如Slave收不到PONG消息,則認爲對端掛了,此時Slave的nginx則設置VIP,然後對外提供服務,看起來十分完美,但是如果是因爲網絡問題而收不到PONG消息呢?這個時候Slave也會認爲Master斷開了,Slave nginx也會自我選舉成爲一個Master nginx,於是系統中就出現了兩個Master同時對外提供服務,這就會亂套了,像這麼一個情況,我們稱之爲腦裂。那如何解決這種腦裂問題呢?其實,上面我們依賴了一種PING/PONG的機制在選舉Master,這種選舉機制有缺陷,那麼比較好的辦法就是引入一個第三方,比如zookeeper,去選舉Master。那如何利用zookeeper去做呢?預知後事如何,且聽下文分解!

 

 

  • 服務發現上的負載均衡

        先來看一個例子,比如在我們的一個遊戲服務系統是一個分佈式的系統,系統結構如下圖所示:

 

 

        裏面的GameServer在處理業務時需要調用DataServer的接口update數據。也就是說GameServer必須知道DataServer的IP地址和端口號,慣用做法把IP、port寫入配置文件,比如:

<?xml version="1.0" encoding="UTF-8"?>

<root version="1.0">

  <!--gameserver監聽端口-->

    <HostServer type="1" id="1">

      <bind ip="192.168.1.134" port="8500" type="0"/>

      <register ip="192.168.1.134" />

    </HostServer>



  <!--連接datacenter的端口-->

  <DataServer>

    <connect ip="192.168.1.135" port="8600" type="0" />

  </DataServer>

  

  <RecvBuffer>

    <buf msgHeadLen="12" clientBuf="40960" serverBuf="1024000" />

  </RecvBuffer>

</root>

 

        咋一看,並不會有什麼問題,其實這種方式有很大問題:

        問題一:GameServer啓動的時候就去連接DataServer,連接並去發送消息可能沒有什麼問題,如果DataServer啓動時端口是監聽起來了,可是啓動後,發現處理業務消息的某個模塊不可用。此時GameServer並不知情這個這個情況,反正已經開始發送業務消息給DataServer了。像這麼一種情況,我們可以稱之爲優雅發佈問題

        問題二:遊戲服務整體已經可用了,但是研發內部說要整治下服務,需要重新梳理各個系統的IP配置,我們慣用做法還是去更新這個配置文件中的ip的值,然後重啓GameServer使之生效,在這個過程中勢必導致GameServer的短暫不可用。這樣一種情況,我們稱之爲優雅更新配置問題,當然增加DataServer的部署也會導致這個問題。

        問題三:比如,在遊戲過程中,突然DataServer宕機了,或者DataServer應用崩潰了,導致對外不可用,那麼GameServer如何感知到,並且不再發送請求到DataServer呢?這個問題其實就是服務健康檢查,比如nginx也提供了健康檢查。

        上面三個問題我們可以用服務發現的機制去解決的,那麼什麼叫做服務主動發現以及如何設計並實現呢?而且如果DataServer是一種異構的服務配置,也就是說他們的硬件配置不一樣,這樣GameServer就必須通過權重配比的方式去發送請求給多個DataServer。那利用zookeeper是怎麼做呢?

 

當然,除了可用性和服務發現問題外,還有自動化配置,數據發佈訂閱,分佈式隊列,分佈式鎖等等,以及zookeeper內部是如何設計,以至於它能解決這些問題。還有zookeeper對外提供可用性,那麼它自己又是如何保障可用性的呢,如果是集羣的話,那麼它們又是如何確保數據的一致性的呢?還有很多分佈式常見的問題,就不一一細數了。

ZooKeeper是什麼的簡介 

  • ZooKeeper 的由來

        下面這段內容摘自《從Paxos到Zookeeper 》第四章第一節的某段內容,推薦大家閱讀以下:

Zookeeper最早起源於雅虎研究院的一個研究小組。在當時,研究人員發現,在雅虎內部很多大型系統基本都需要依賴一個類似的系統來進行分佈式協調,但是這些系統往往都存在分佈式單點問題。所以,雅虎的開發人員就試圖開發一個通用的無單點問題的分佈式協調框架,以便讓開發人員將精力集中在處理業務邏輯上。

關於“ZooKeeper”這個項目的名字,其實也有一段趣聞。在立項初期,考慮到之前內部很多項目都是使用動物的名字來命名的(例如著名的Pig項目),雅虎的工程師希望給這個項目也取一個動物的名字。時任研究院的首席科學家RaghuRamakrishnan開玩笑地說:“在這樣下去,我們這兒就變成動物園了!”此話一出,大家紛紛表示就叫動物園管理員吧一一一因爲各個以動物命名的分佈式組件放在一起,雅虎的整個分佈式系統看上去就像一個大型的動物園了,而Zookeeper正好要用來進行分佈式環境的協調一一於是,Zookeeper的名字也就由此誕生了。

  • ZooKeeper是什麼

        ZooKeeper 是一個開源的分佈式協調服務,ZooKeeper框架最初是在“Yahoo!"上構建的,用於以簡單而穩健的方式訪問他們的應用程序。 後來,Apache ZooKeeper成爲Hadoop,HBase和其他分佈式框架使用的有組織服務的標準。 例如,Apache HBase使用ZooKeeper跟蹤分佈式數據的狀態。ZooKeeper 的設計目標是將那些複雜且容易出錯的分佈式一致性服務封裝起來,構成一個高效可靠的原語集,並以一系列簡單易用的接口提供給用戶使用。

原語: 操作系統或計算機網絡用語範疇。是由若干條指令組成的,用於完成一定功能的一個過程。具有不可分割性·即原語的執行必須是連續的,在執行過程中不允許被中斷。

        ZooKeeper 是一個典型的分佈式數據一致性解決方案,分佈式應用程序可以基於 ZooKeeper 實現諸如數據發佈/訂閱負載均衡服務發現分佈式協調/通知集羣管理Master 選舉分佈式鎖分佈式隊列等功能。

        Zookeeper 一個最常用的使用場景就是用於擔任服務生產者和服務消費者的註冊中心。 服務生產者將自己提供的服務註冊到Zookeeper中心,服務的消費者在進行服務調用的時候先到Zookeeper中查找服務,獲取到服務生產者的詳細信息之後,再去調用服務生產者的內容與數據。如下圖所示,使用 Zookeeper 擔任了註冊中心這一角色。

 

 

  • zookeeper內部的數據模型

 

        在zookeeper內部維護了一個樹的結構,如下圖所示,跟unix的文件目錄類似,但是它的每一個節點下還有很多的屬性,這一點在接下來的內容中會分享的。

  • ZooKeeper是集羣化部署的

        zookeeper可以單點部署,也可以集羣化部署,集羣部署後有多個服務對外提供創建、更新和刪除節點的服務。

爲什麼要學習zookeeper? 

  • ZooKeeper的特點

    • 順序一致性: 從同一客戶端發起的事務請求,最終將會嚴格地按照順序被應用到 ZooKeeper 中去。

    • 原子性: 所有事務請求的處理結果在整個集羣中所有機器上的應用情況是一致的,也就是說,要麼整個集羣中所有的機器都成功應用了某一個事務,要麼都沒有應用。

    • 單一系統映像 : 無論客戶端連到哪一個 ZooKeeper 服務器上,其看到的服務端數據模型都是一致的。

    • 可靠性: 一旦一次更改請求被應用,更改的結果就會被持久化,直到被下一次更改覆蓋,即使在這個過程中,即使有一些zookeeper服務掛掉了。

        我們可以利用這些特點,在系統中提供數據發佈/訂閱負載均衡服務發現分佈式協調/通知集羣管理Master 選舉分佈式鎖分佈式隊列等功能,那麼這些功能實現原理是什麼,並且如何編碼的?

        在使用zookeeper過程中,可能會遇到很多的坑,這些坑又如何避免呢?

        我們很多人可能僅僅把zookeeper當作一個服務組件,僅僅是瞭解如何使用它,但是這不夠,我們更應該瞭解它的一些機制,不如順序一致性是怎麼做到的?原子性操作又是如何做到的,集羣時對外提供了可靠性的服務,那麼這種可靠性是怎麼實現的呢?如果學習了它的這些處理機制後,我們就可以借它山之石,去攻自己的玉,也就是應用到自己的系統架構設計中。

        大家在閱讀這篇文章時,可能會覺得我提了太多問題了,但是會問問題的就是會思考的,希望通過這些問題去意識到zookeeper的重要性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章