原理
ZooKeeper是以Fast Paxos算法為基礎的,paxos算法存在活鎖的問題,即當有多個proposer交錯提交時,有可能互相排斥導致沒有一個proposer能提交成功,而Fast Paxos作了一些最佳化,通過選舉產生一個leader,只有leader才能提交propose,具體算法可見Fast Paxos。因此,要想弄懂ZooKeeper首先得對Fast Paxos有所了解。ZooKeeper的基本運轉流程:
1、選舉Leader。
2、同步數據。
3、選舉Leader過程中算法有很多,但要達到的選舉標準是一致的。
4、Leader要具有最高的zxid。
5、集群中大多數的機器得到回響並follow選出的Leader。
特點
在Zookeeper中,znode是一個跟Unix檔案系統路徑相似的節點,可以往這個節點存儲或獲取數據。如果在創建znode時Flag設定為EPHEMERAL,那么當創建這個znode的節點和Zookeeper失去連線後,這個znode將不再存在在Zookeeper里,Zookeeper使用Watcher察覺事件信息。當客戶端接收到事件信息,比如連線逾時、節點數據改變、子節點改變,可以調用相應的行為來處理數據。Zookeeper的Wiki頁面展示了如何使用Zookeeper來處理事件通知,佇列,優先佇列,鎖,共享鎖,可撤銷的共享鎖,兩階段提交。
那么Zookeeper能作什麼事情呢,簡單的例子:假設我們有20個搜尋引擎的伺服器(每個負責總索引中的一部分的搜尋任務)和一個總伺服器(負責向這20個搜尋引擎的伺服器發出搜尋請求併合並結果集),一個備用的總伺服器(負責當總伺服器宕機時替換總伺服器),一個web的cgi(向總伺服器發出搜尋請求)。搜尋引擎的伺服器中的15個伺服器提供搜尋服務,5個伺服器正在生成索引。這20個搜尋引擎的伺服器經常要讓正在提供搜尋服務的伺服器停止提供服務開始生成索引,或生成索引的伺服器已經把索引生成完成可以搜尋提供服務了。使用Zookeeper可以保證總伺服器自動感知有多少提供搜尋引擎的伺服器並向這些伺服器發出搜尋請求,當總伺服器宕機時自動啟用備用的總伺服器。
部署
我需要運行幾個ZooKeeper?
你運行一個zookeeper也是可以的,但是在生產環境中,你最好部署3,5,7個節點。部署的越多,可靠性就越高,當然最好是部署奇數個,偶數個不是不可以的,但是zookeeper集群是以宕機個數過半才會讓整個集群宕機的,所以奇數個集群更佳。你需要給每個zookeeper 1G左右的記憶體,如果可能的話,最好有獨立的磁碟。 (獨立磁碟可以確保zookeeper是高性能的。).如果你的集群負載很重,不要把Zookeeper和RegionServer運行在同一台機器上面。就像DataNodes 和 TaskTrackers一樣。
客戶端
PHP
註:以下代碼依賴於PHP擴展libzookeeper
。
連線集群:
$zc = new ZookeeperClient();
$zc->connect('192.168.0.2:2181, 192.168.0.3:2181');
?>
創建節點:
$zc = new ZookeeperClient();
$zc->connect('localhost:2181');
$zc->create('/new_node', 'node_value');
?>
刪除節點:
$zc = new ZookeeperClient();
$zc->connect('localhost:2181');
$zc->delete('/existing_node');
?>
獲取節點值:
$zc = new ZookeeperClient();
$zc->connect('localhost:2181');
var_dump($zc->get('/existing_node'));
?>
獲取子節點:
$zc = new ZookeeperClient();
$zc->connect('localhost:2181');
$childNodes = $zc->getChildren('/parent_node');
foreach ($childNodes as $nodeName) {
var_dump($nodeName);
}
?>
其他
HBase和ZooKeeper
HBase內置有ZooKeeper,也可以使用外部ZooKeeper。
讓HBase使用一個已有的不被HBase託管的Zookeep集群,需要設定 conf/hbase env sh檔案中的HBASE_MANAGES_ZK 屬性為 false
... # Tell HBase whether it should manage it's own instance of Zookeeper or not. export HBASE_MANAGES_ZK=false
接下來,指明Zookeeper的host和連線埠。可以在 hbase-site.xml中設定, 也可以在HBase的CLASSPATH下面加一個zoo.cfg配置檔案。 HBase 會優先載入 zoo.cfg 裡面的配置,把hbase-site.xml裡面的復蓋掉.
當HBase託管ZooKeeper的時候,Zookeeper集群的啟動是HBase啟動腳本的一部分。但你需要自己去運行。你可以這樣做
${HBASE_HOME}/bin/hbase-daemons sh {start,stop} zookeeper
你可以用這條命令啟動ZooKeeper而不啟動HBase. HBASE_MANAGES_ZK 的值是 false, 如果你想在HBase重啟的時候不重啟ZooKeeper,你可以這樣做
對於獨立Zoopkeeper的問題,你可以在 Zookeeper啟動得到幫助.