1. 程式人生 > >Zookeeper介紹和簡單3臺配置叢集

Zookeeper介紹和簡單3臺配置叢集

.簡介

Zookeeper的官網上有這麼一句話:ZooKeeper is acentralized service for maintaining configuration information, naming,providing distributed synchronization, and providing group services. 

這大概描述了Zookeeper主要可以做以下事情:配置管理,名字服務,提供分散式同步以及叢集管理。

配置管理

在我們的應用中除了程式碼外,還有一些就是各種配置。比如資料庫連線等。一般我們都是使用配置檔案的方式,在程式碼中引入這些配置檔案。但是當我們只有一種配置,只有一臺伺服器,並且不經常修改的時候,使用配置檔案是一個很好的做法,但是如果我們配置非常多,有很多伺服器都需要這個配置,而且還可能是動態的話使用配置檔案就不是個好主意了。這個時候往往需要尋找一種集中管理配置的方法,我們在這個集中的地方修改了配置,所有對這個配置感興趣的都可以獲得變更。比如我們可以把配置放在資料庫裡,然後所有需要配置的服務都去這個資料庫讀取配置。但是,因為很多服務的正常執行都非常依賴這個配置,所以需要這個集中提供配置服務的服務具備很高的可靠性。一般我們可以用一個叢集來提供這個配置服務,但是用叢集提升可靠性,那如何保證配置在叢集中的一致性呢?

這個時候就需要使用一種實現了一致性協議的服務了。Zookeeper就是這種服務,它使用Zab這種一致性協議來提供一致性。現在有很多開源專案使用Zookeeper來維護配置,比如在HBase中,客戶端就是連線一個Zookeeper,獲得必要的HBase叢集的配置資訊,然後才可以進一步操作。還有在開源的訊息佇列Kafka中,也使用Zookeeper來維護broker的資訊。在Alibaba開源的SOA框架Dubbo中也廣泛的使用Zookeeper管理一些配置來實現服務治理。

名字服務

名字服務這個就很好理解了。比如為了通過網路訪問一個系統,我們得知道對方的IP地址,但是IP地址對人非常不友好,這個時候我們就需要使用域名來訪問。但是計算機是不能是別域名的。怎麼辦呢?如果我們每臺機器裡都備有一份域名到

IP地址的對映,這個倒是能解決一部分問題,但是如果域名對應的IP發生變化了又該怎麼辦呢?於是我們有了DNS這個東西。我們只需要訪問一個大家熟知的(known)的點,它就會告訴你這個域名對應的IP是什麼。在我們的應用中也會存在很多這類問題,特別是在我們的服務特別多的時候,如果我們在本地儲存服務的地址的時候將非常不方便,但是如果我們只需要訪問一個大家都熟知的訪問點,這裡提供統一的入口,那麼維護起來將方便得多了。

分散式鎖

Zookeeper是一個分散式協調服務。這樣我們就可以利用Zookeeper來協調多個分散式程序之間的活動。比如在一個分散式環境中,為了提高可靠性,我們的叢集的每臺伺服器上都部署著同樣的服務。但是,一件事情如果叢集中的每個伺服器都進行的話,那相互之間就要協調,程式設計起來將非常複雜。而如果我們只讓一個服務進行操作,那又存在單點。通常還有一種做法就是使用分散式鎖,在某個時刻只讓一個服務去幹活,當這臺服務出問題的時候鎖釋放,立即

fail over到另外的服務。這在很多分散式系統中都是這麼做,這種設計有一個更好聽的名字叫LeaderElection(leader選舉)。比如HBaseMaster就是採用這種機制。但要注意的是分散式鎖跟同一個程序的鎖還是有區別的,所以使用的時候要比同一個程序裡的鎖更謹慎的使用。

叢集管理

在分散式的叢集中,經常會由於各種原因,比如硬體故障,軟體故障,網路問題,有些節點會進進出出。有新的節點加入進來,也有老的節點退出叢集。這個時候,叢集中其他機器需要感知到這種變化,然後根據這種變化做出對應的決策。比如我們是一個分散式儲存系統,有一箇中央控制節點負責儲存的分配,當有新的儲存進來的時候我們要根據現在叢集目前的狀態來分配儲存節點。這個時候我們就需要動態感知到叢集目前的狀態。還有,比如一個分散式的SOA架構中,服務是一個叢集提供的,當消費者訪問某個服務時,就需要採用某種機制發現現在有哪些節點可以提供該服務(這也稱之為服務發現,比如Alibaba開源的SOA框架Dubbo就採用了Zookeeper作為服務發現的底層機制)。還有開源的Kafka佇列就採用了Zookeeper作為Cosnumer的上下線管理。

.基本配置

Zookeeper的安裝和配置十分簡單, 既可以配置成單機模式, 也可以配置成叢集模式. 下面將分別進行介紹.

單機模式

下載zookeeper的安裝包之後, 解壓到合適目錄. 進入zookeeper目錄下的conf子目錄, 建立zoo.cfg:

1.   tickTime=2000    

2.   dataDir=/Users/apple/zookeeper/data    

3.   dataLogDir=/Users/apple/zookeeper/logs    

4.   clientPort=4180   

引數說明:

·        tickTime: zookeeper中使用的基本時間單位, 毫秒值.

·        dataDir: 資料目錄. 可以是任意目錄.

·        dataLogDir: log目錄, 同樣可以是任意目錄. 如果沒有設定該引數, 將使用和dataDir相同的設定.

·        clientPort: 監聽client連線的埠號.

至此, zookeeper的單機模式已經配置好了. 啟動server只需執行指令碼:

1.   bin/zkServer.sh start  

 Server啟動之後, 就可以啟動client連線server了, 執行指令碼:

1.   bin/zkCli.sh -server localhost:4180  

偽叢集模式

所謂偽叢集, 是指在單臺機器中啟動多個zookeeper程序, 並組成一個叢集. 以啟動3zookeeper程序為例.

zookeeper的目錄拷貝2:

1.   |--zookeeper0  

2.   |--zookeeper1  

3.   |--zookeeper2  

更改zookeeper0/conf/zoo.cfg檔案為:

1.   tickTime=2000    

2.   initLimit=5    

3.   syncLimit=2    

4.   dataDir=/Users/apple/zookeeper0/data    

5.   dataLogDir=/Users/apple/zookeeper0/logs    

6.   clientPort=4180  

7.   server.0=127.0.0.1:8880:7770    

8.   server.1=127.0.0.1:8881:7771    

9.   server.2=127.0.0.1:8882:7772  

新增了幾個引數, 其含義如下:

·        initLimit: zookeeper叢集中的包含多臺server, 其中一臺為leader, 叢集中其餘的serverfollower. initLimit引數配置初始化連線時, followerleader之間的最長心跳時間. 此時該引數設定為5, 說明時間限制為5tickTime, 5*2000=10000ms=10s.

·        syncLimit: 該引數配置leaderfollower之間傳送訊息, 請求和應答的最大時間長度. 此時該引數設定為2, 說明時間限制為2tickTime, 4000ms.

·        server.X=A:B:C 其中X是一個數字, 表示這是第幾號server. A是該server所在的IP地址. B配置該server和叢集中的leader交換訊息所使用的埠. C配置選舉leader時所使用的埠. 由於配置的是偽叢集模式, 所以各個serverB, C引數必須不同.

參照zookeeper0/conf/zoo.cfg, 配置zookeeper1/conf/zoo.cfg,zookeeper2/conf/zoo.cfg檔案. 只需更改dataDir, dataLogDir, clientPort引數即可.

在之前設定的dataDir中新建myid檔案, 寫入一個數字, 該數字表示這是第幾號server. 該數字必須和zoo.cfg檔案中的server.X中的X一一對應.
/Users/apple/zookeeper0/data/myid
檔案中寫入0,/Users/apple/zookeeper1/data/myid檔案中寫入1,/Users/apple/zookeeper2/data/myid檔案中寫入2.

分別進入/Users/apple/zookeeper0/bin, /Users/apple/zookeeper1/bin,/Users/apple/zookeeper2/bin三個目錄, 啟動server.
任意選擇一個server目錄, 啟動客戶端:

1.   bin/zkCli.sh -server localhost:4180  

叢集模式

叢集模式的配置和偽叢集基本一致.
由於叢集模式下, server部署在不同的機器上, 因此各serverconf/zoo.cfg檔案可以完全一樣.
下面是一個示例:

1.   tickTime=2000    

2.   initLimit=5    

3.   syncLimit=2    

4.   dataDir=/home/zookeeper/data    

5.   dataLogDir=/home/zookeeper/logs    

6.   clientPort=4180  

7.   server.43=10.1.39.43:2888:3888  

8.   server.47=10.1.39.47:2888:3888    

9.   server.48=10.1.39.48:2888:3888  

示例中部署了3zookeeperserver, 分別部署在10.1.39.43, 10.1.39.47, 10.1.39.48. 需要注意的是, serverdataDir目錄下的myid檔案中的數字必須不同.

10.1.39.43servermyid43, 10.1.39.47servermyid47, 10.1.39.48servermyid48.