Hadoop學習筆記—14.ZooKeeper環境搭建


從字面上來看,ZooKeeper表示動物園管理員,這是一個十分奇妙的名字,我們又想起了Hadoop生態系統中,許多項目的Logo都采用了動物,比如Hadoop采用了大象的形象,所以我們可以猜測ZooKeeper就是對這些動物進行一些管理工作的。

一、ZooKeeper基礎介紹

1.1 動物園也要保障安全

  zookeeper是hadoop下面的一個子項目,用來協調跟hadoop相關的一些分布式的框架,如hadoop, hive, pig等, 其實他們都是動物,所以叫zookeeper ——“動物園管理員”。動物園里當然有好多的動物,游客可以根據動物園提供的向導圖到不同的場館觀賞各種類型的動物,而不是像走在原始叢林里,心驚膽顫的被動物所觀賞。為了讓各種不同的動物呆在它們應該呆的地方,而不是相互串門,或是相互廝殺,就需要動物園管理員按照動物的各種習性加以分類和管理,這樣我們才能更加放心安全的觀賞動物。

1.2 進程內的協調方法

  在實際應用中,Zookeeper主要是針對大型分布式系統進行高可靠的協調。由這個定義我們知道zookeeper是個協調系統,作用的對象是分布式系統。說到協調,我們可以聯想到的現實生活中很多十字路口的交通協管,他們手握着小紅旗,指揮車輛和行人是不是可以通行。如果我們把車輛和行人比喻成運行在計算機中的單元(線程),那么這個協管是干什么的?很多人都會想到,這不就是鎖么?對,在一個並發的環境里,我們為了避免多個運行單元對共享數據同時進行修改,造成數據損壞的情況出現,我們就必須依賴像鎖這樣的協調機制,讓有的線程可以先操作這些資源,然后其他線程等待。對於進程內的鎖來講,我們使用的各種語言平台都已經給我們准備很多種選擇。例如在C#中,最常用的莫過於借助語法糖lock構造同步塊:

  int Withdraw(int amount)
    {
        if (balance < 0)
        {
            throw new Exception("Negative Balance");
        }

        lock(thisLock)
        {
            if (balance >= amount)
            {
                Console.WriteLine("Balance before Withdrawal :  " + balance);
                Console.WriteLine("Amount to Withdraw        : -" + amount);
                balance = balance - amount;
                Console.WriteLine("Balance after Withdrawal  :  " + balance);
                return amount;
            }
            else
            {
                return 0;
            }
        }
    }

1.3 分布式環境中的協調

  在進程內進行協調我們可以使用語言,平台,操作系統等為我們提供的機制。那么如果我們在一個分布式環境中呢?也就是我們的程序運行在不同的機器上,這些機器可能位於同一個機架,同一個機房又或不同的數據中心。在這樣的環境中,我們要實現協調該怎么辦?那么這就是分布式協調服務要干的事情。

  於是,Google創造了Chubby,而ZooKeeper則是對於Chubby的一個開源實現。

        

Definition:ZooKeeper是一種為分布式應用所設計的高可用、高性能且一致的開源協調服務,它提供了一項基本服務:分布式鎖服務。由於ZooKeeper的開源特性,后來我們的開發者在分布式鎖的基礎上,摸索了出了其他的使用方法:配置維護、組服務、分布式消息隊列分布式通知/協調等。

1.4 ZooKeeper的應用場景

  (1)統一命名服務

  有一組服務器向客戶端提供某種服務(例如:使用LVS技術構建的Web網站集群,就是由N台服務器組成的集群,為用戶提供Web服務),我們希望客戶端每次請求服務端都可以找到服務端集群中某一台服務器,這樣服務端就可以向客戶端提供客戶端所需的服務。對於這種場景,我們的程序中一定有一份這組服務器的列表,每次客戶端請求時候,都是從這份列表里讀取這份服務器列表。那么這分列表顯然不能存儲在一台單節點的服務器上,否則這個節點掛掉了,整個集群都會發生故障,我們希望這份列表時高可用的。高可用的解決方案是:這份列表是分布式存儲的,它是由存儲這份列表的服務器共同管理的,如果存儲列表里的某台服務器壞掉了,其他服務器馬上可以替代壞掉的服務器,並且可以把壞掉的服務器從列表里刪除掉,讓故障服務器退出整個集群的運行,而這一切的操作又不會由故障的服務器來操作,而是集群里正常的服務器來完成。這是一種主動的分布式數據結構,能夠在外部情況發生變化時候主動修改數據項狀態的數據機構。Zookeeper框架提供了這種服務。這種服務名字就是:統一命名服務,它和javaEE里的JNDI服務很像。

  (2)分布式鎖服務

  當分布式系統操作數據,例如:讀取數據、分析數據、最后修改數據。在分布式系統里這些操作可能會分散到集群里不同的節點上,那么這時候就存在數據操作過程中一致性的問題,如果不一致,我們將會得到一個錯誤的運算結果,在單一進程的程序里,一致性的問題很好解決,但是到了分布式系統就比較困難,因為分布式系統里不同服務器的運算都是在獨立的進程里,運算的中間結果和過程還要通過網絡進行傳遞,那么想做到數據操作一致性要困難的多。Zookeeper提供了一個鎖服務解決了這樣的問題,能讓我們在做分布式數據運算時候,保證數據操作的一致性。

  (3)配置管理

  在分布式系統里,我們會把一個服務應用分別部署到n台服務器上,這些服務器的配置文件是相同的(例如:我設計的分布式網站框架里,服務端就有4台服務器,4台服務器上的程序都是一樣,配置文件都是一樣),如果配置文件的配置選項發生變化,那么我們就得一個個去改這些配置文件,如果我們需要改的服務器比較少,這些操作還不是太麻煩,如果我們分布式的服務器特別多,比如某些大型互聯網公司的hadoop集群有數千台服務器,那么更改配置選項就是一件麻煩而且危險的事情。這時候zookeeper就可以派上用場了,我們可以把zookeeper當成一個高可用的配置存儲器,把這樣的事情交給zookeeper進行管理,我們將集群的配置文件拷貝到zookeeper的文件系統的某個節點上,然后用zookeeper監控所有分布式系統里配置文件的狀態,一旦發現有配置文件發生了變化,每台服務器都會收到zookeeper的通知,讓每台服務器同步zookeeper里的配置文件,zookeeper服務也會保證同步操作原子性,確保每個服務器的配置文件都能被正確的更新。

  可以看出,zookeeper是一個典型的觀察者模式的應用。

  (4)集群管理

  集群管理是很困難的,在分布式系統里加入了zookeeper服務,能讓我們很容易的對集群進行管理。集群管理最麻煩的事情就是節點故障管理,zookeeper可以讓集群選出一個健康的節點作為master,master節點會知道當前集群的每台服務器的運行狀況,一旦某個節點發生故障,master會把這個情況通知給集群其他服務器,從而重新分配不同節點的計算任務。Zookeeper不僅可以發現故障,也會對有故障的服務器進行甄別,看故障服務器是什么樣的故障,如果該故障可以修復,zookeeper可以自動修復或者告訴系統管理員錯誤的原因讓管理員迅速定位問題,修復節點的故障。大家也許還會有個疑問,master故障了,那怎么辦了?zookeeper也考慮到了這點,zookeeper內部有一個“選舉領導者的算法”,master可以動態選擇,當master故障時候,zookeeper能馬上選出新的master對集群進行管理。

PS:關於Master的選舉,可以瀏覽Suddenly的這篇:http://www.cnblogs.com/sunddenly/p/4033574.html,其文章有一部分叫做分布式鎖應用場景,對於Master選舉有一個詳細的介紹。

二、ZooKeeper集群模式環境搭建

2.1 ZooKeeper集群模式典型架構

  (1)典型架構圖如下所示:

  (2)本次試驗架構圖如下所示:

2.2 ZooKeeper集群模式搭建步湊

注意:ZooKeeper服務器集群規模不小於3個節點,要求各服務器之間系統時間要保持一致;

  (1)通過FTP工具上傳ZooKeeper安裝包,我這里使用的是3.4.5版本:

  下載地址:http://pan.baidu.com/s/1qWyoFhU

  (2)解壓ZooKeeper安裝包,並將解壓后的文件夾名稱改為zookeeper:

  ①tar -zvxf zookeeper-3.4.5.tar.gz

  ②mv zookeeper-3.4.5 zookeeper

  (3)修改環境變量:vim /etc/profile

  增加一行:export ZOOKEEPER_HOME=/usr/local/zookeeper

  修改PATH:export PATH=.:$HADOOP_HOME/bin:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$PATH

  ③使配置生效:source /etc/profile

  (4)進入zookeeper的conf目錄下,修改文件名:mv zoo_sample.cfg  zoo.cfg

  (5)編輯zoo.cfg:vim zoo.cfg

  修改dataDir=/usr/local/zookeeper/data
  新增server.0=hadoop-master:2888:3888
      server.1=hadoop-slave1:2888:3888
      server.2=hadoop-slave2:2888:3888

  (6)創建data文件夾,並創建myid文件:

  新建data文件夾:mkdir /usr/local/zookeeper/data

  新建myid文件:vim myid,並設置第一台server為0。

  (7)復制zookeeper目錄至其余兩台服務器中:

  ①scp /usr/local/zookeeper hadoop-slave1:/usr/local/

  scp /usr/local/zookeeper hadoop-slave2:/usr/local/

  (8)復制環境變量配置文件至其余兩台服務器中:

  ①scp /etc/profile hadoop-slave1:/etc

  scp /etc/profile hadoop-slave2:/etc

  (9)在其余兩台服務器中修改myid文件:設置為1和2;

  (10)啟動ZooKeeper,分別在三個節點中執行命令:zkServer.sh start

  (11)檢驗ZooKeeper集群節點角色狀態,分別在三個節點中執行命令:zkServer.sh status

Role:ZooKeeper中包含以下角色:

領導者(leader),負責進行投票的發起和決議,更新系統狀態;
學習者(learner),包括跟隨者(follower)和觀察者(observer),follower用於接受客戶端請求並想客戶端返回結果,在選主過程中參與投票;observer可以接受客戶端連接,將寫請求轉發給leader,但observer不參加投票過程,只同步leader的狀態,observer的目的是為了擴展系統,提高讀取速度;

三、ZooKeeper簡單測試

  搭建好集群環境后,就可以進行簡單的讀寫一致性測試了,這里我們通過進入zookeeper的bin目錄下的zkCli.sh來完成下面的操作:

  (1)在其中一個節點192.168.80.100上執行一個寫操作:create /MyTest test

  (2)在其他兩個節點上執行讀操作:get /MyTest

  TIP:可以在一個節點中通過zkCli.sh -server hadoop-slave1:2181來遠程登錄

  (3)在其中一個節點192.168.80.101上執行一個修改操作:

  (4)在其他兩個節點上執行讀操作:

參考資料

(1)張善友,《zookeeper分布式鎖服務》:http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html

(2)夏天的森林,《分布式網站架構后續:zookeeper技術淺析》:http://www.cnblogs.com/sharpxiajun/archive/2013/06/02/3113923.html

(3)橫刀天笑,《Zookeeper—Zookeeper是什么?》:http://www.cnblogs.com/yuyijq/p/3391945.html

(4)Suddenly,《Hadoop日志Day20—ZooKeeper》:http://www.cnblogs.com/sunddenly/p/4033574.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM