Zookeeper--Zookeeper是什麼

Google的三篇論文影響了很多很多人,也影響了很多很多系統。這三篇論文一直是分佈式領域傳閱的經典。根據MapReduce,於是我們有了Hadoop;根據GFS,於是我們有了HDFS;根據BigTable,於是我們有了HBase。而在這三篇論文裏都提及Google的一個lock service---Chubby,哦,於是我們有了Zookeeper。

隨着大數據的火熱,Hxx們已經變得耳熟能詳,現在作爲一個開發人員如果都不知道這幾個名詞出門都好像不好意思跟人打招呼。但實際上對我們這些非大數據開發人員而言,Zookeeper是比Hxx們可能接觸到更多的一個基礎服務。但是,無奈的是它一直默默的位於二線,從來沒有Hxx們那麼耀眼。那麼到底什麼是Zookeeper呢?Zookeeper可以用來幹什麼?我們將如何使用Zookeeper?Zookeeper又是怎麼實現的?

伴隨着Zookeeper有兩篇論文:一篇是Zab,就是介紹Zookeeper背後使用的一致性協議的(Zookeeper atomic broadcast protocol),還有一篇就是介紹Zookeeper本身的。在這兩篇論文裏都提到Zookeeper是一個分佈式協調服務(a service for coordinating processes of distributed applications)。那分佈式協調服務又是個什麼東西呢?首先我們來看“協調”是什麼意思。

說到協調,我首先想到的是北京很多十字路口的交通協管,他們手握着小紅旗,指揮車輛和行人是不是可以通行。如果我們把車輛和行人比喻成運行在計算機中的單元(線程),那麼這個協管是幹什麼的?很多人都會想到,這不就是鎖麼?對,在一個併發的環境裏,我們爲了避免多個運行單元對共享數據同時進行修改,造成數據損壞的情況出現,我們就必須依賴像鎖這樣的協調機制,讓有的線程可以先操作這些資源,然後其他線程等待。對於進程內的鎖來講,我們使用的各種語言平臺都已經給我們準備很多種選擇。就拿Java來說,有最普通不過的同步方法或同步塊:

public synchronized void sharedMethod(){   //對共享數據進行操作}

使用了這種方式後,多個線程對sharedMethod進行操作的時候,就會協調好步驟,不會對sharedMethod裏的資源進行破壞,產生不一致的情況。這個最簡單的協調方法,但有的時候我們可能需要更復雜的協調。比如我們常常爲了提高性能,我們使用讀寫鎖。因爲大部分時候我們對資源是讀取多而修改少,而如果不管三七二十一全部使用排他的寫鎖,那麼性能有可能就會受到影響。還是用java舉例:

複製代碼

public class SharedSource{   private ReadWriteLock rwlock = new ReentrantReadWriteLock();   private Lock rlock = rwlock.readLock();   private Lock wlock = rwlock.writeLock();   public void read(){
      rlock.lock();      try{         //讀取資源
      }finally{
         rlock.unlock();
      }
   }   
   public void write(){
     wlock.lock();     try{        //寫資源
     }finally{
        wlock.unlock();
     }
   }

}

複製代碼

我們在進程內還有各種各樣的協調機制(一般我們稱之爲同步機制)。現在我們大概瞭解了什麼是協調了,但是上面介紹的協調都是在進程內進行協調。在進程內進行協調我們可以使用語言,平臺,操作系統等爲我們提供的機制。那麼如果我們在一個分佈式環境中呢?也就是我們的程序運行在不同的機器上,這些機器可能位於同一個機架,同一個機房又或不同的數據中心。在這樣的環境中,我們要實現協調該怎麼辦?那麼這就是分佈式協調服務要乾的事情。

ok,可能有人會講,這個好像也不難。無非是將原來在同一個進程內的一些原語通過網絡實現在分佈式環境中。是的,表面上是可以這麼說。但分佈式系統中,說往往比做容易得多。在分佈式系統中,所有同一個進程內的任何假設都不存在:因爲網絡是不可靠的。

比如,在同一個進程內,你對一個方法的調用如果成功,那就是成功(當然,如果你的代碼有bug那就另說了),如果調用失敗,比如拋出異常那就是調用失敗。在同一個進程內,如果這個方法先調用先執行,那就是先執行。但是在分佈式環境中呢? 由於網絡的不可靠,你對一個服務的調用失敗了並不表示一定是失敗的,可能是執行成功了,但是響應返回的時候失敗了。還有,A和B都去調用C服務,在時間上A還先調用一些,B後調用,那麼最後的結果是不是一定A的請求就先於B到達呢? 這些本來在同一個進程內的種種假設我們都要重新思考,我們還要思考這些問題給我們的設計和編碼帶來了哪些影響。還有,在分佈式環境中爲了提升可靠性,我們往往會部署多套服務,但是如何在多套服務中達到一致性,這在同一個進程內很容易解決的問題,但在分佈式環境中確實一個大難題。

所以分佈式協調遠遠比同一個進程裏的協調複雜得多,所以類似Zookeeper這類基礎服務就應運而生。這些系統都在各個系統久經考驗,它的可靠性,可用性都是經過理論和實踐的驗證的。所以我們在構建一些分佈式系統的時候,就可以以這類系統爲起點來構建我們的系統,這將節省不少成本,而且bug也將更少。

本篇文章試圖從外圍介紹一下Zookeeper是一個什麼樣子的服務和我們爲什麼需要這樣一種服務。在後面的文章中會介紹Zookeeper到底能幹些什麼。


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