Zookeeper 集群部署的那些事兒


簡介

真是一個大聰明

額。。。。, &*$% 淘氣!

ZooKeeper 是 Apache 的一個頂級項目,為分布式應用提供高效、高可用的分布式協調服務。

ZooKeeper本質上是一個分布式的小文件存儲系統。提供類似於文件系統目錄樹方式的數據存儲,並且可以對書中的節點進行有效管理。從而用來維護和監控存儲的數據的狀態變化,通過監控這些數據狀態的變化,實現基於數據的集群管理。

運行模式

ZooKeeper 運行模式有三種:單機模式、偽集群模式、集群模式

有三種運行模式,造嗎

單機模式: ZooKeeper 只運行一台服務器上面,這種模式一般用於開發測試環境,用於節省機器數量,加上開發調試不需要特別好的穩定性

偽集群模式: 這是一種特殊的集群模式,即一台服務器上面部署多個ZooKeeper實例,當然這個時候就需要你這台服務器性能比較好。在這種情況下,我們需要通過不同的端口來啟動ZooKeeper實例,以此來通過集群的方式對外提供服務。

這種模式下,我們只需要修改zoo.cfg下的同一個服務器不同端口連接地址即可

server.1=ip1:2888:3888
server.2=ip1:2889:3889
server.3=ip1:2890:3890

集群模式: Zookeeper集群 運行在一組機器上,一般三台以上的機器就可以組成集群了,組成ZooKeeper集群的每一台機器都會在內存中維護當前服務的狀態,機器之間也會互相保持通信。

只要集群中過半的服務存活,就能正常對外提供服務,如果說當我們的leader掛掉了,在選舉過程中是無法提供服務的,直到leader選舉完成!

這種模式下,我們只需要修改zoo.cfg下的不同服務器的連接地址即可

server.1=ip1:2888:3888
server.2=ip2:2888:3888
server.3=ip3:2888:3888

Zookeeper集群有什么用

ZooKeeper 實現了高性能,高可靠性和有序的訪問。高性能保證了ZooKeeper能應用在大型的分布式系統上,高可靠性保證它不會由於單一節點的故障而造成任何問題。有序的訪問能保證客戶端可以實現較為復雜的同步操作。

負載均衡

這里說的負載均衡是指軟負載均衡。在分布式環境中,為了保證高可用性,通常同一個應用或同一個服務的提供方都會部署多份,來達到高可用。

命名服務

在分布式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或者服務的地址,提供者等信息。被命名的實體通常可以是集群中的機器,提供的服務地址、遠程對象等這些我們可以統稱為Name,其中比較常見的就是一些分布式服務框架中的服務地址列表。通過調用ZooKeeper提供創建節點的API,能夠很容易創建一個全局唯一的Path,這個Path可以作為一個名稱。
阿里巴巴集團開源的分布式服務框架Dubbo中使用ZooKeeper來作為其命名服務,維護全局的服務地址列表,點擊這里查看Dubbo開源項目。

分布式協調

ZooKeeper中特有的Watcher注冊與異步通知機制,能夠實現分布式環境下不同系統之間的通知與協調,實現對數據變更的及時處理,使用方法通常是不同系統都對ZooKeeper同一個Znode進行注冊,監聽Znode的變化。
如果其中一個系統更新了Znode,那么另外系統也能夠收到通知,並做出相應的處理。

集群管理

集群管理主要是包含其中兩點:服務狀態監聽(退出和加入)、master選舉。

服務狀態監聽: 所有機器在父目錄下創建臨時目錄節點,監聽父目錄節點的子節點變化消息,如果有機器掛掉,這個機器與ZooKeeper的連接斷開,這個創建的臨時目錄節點就會被刪除,其他機器收到消息,某個服務下的節點目錄被刪除,就知道這個某個節點宕機。

如果有新的機器或者服務加入,會在該父目錄節點下創建一個臨時子節點,所有服務就會收到通知,有新的目錄產生。

master選舉: master選舉是ZooKeeper中最為經典的應用場景了,在分布式環境中,相同的業務應用分布在不同的機器上,有的業務邏輯,通常只需要其中一台服務完成,然后其他服務共享,這樣可以大幅度減少重復勞動,提高服務性能,比如 HDFS 中 Active NameNode 的選舉。

通常情況下,我們可以選擇常見的關系型數據庫中的主鍵特性來實現,在成為Master的機器都想數據庫中插入一條相同主鍵ID的記錄,數據庫會幫我們進行主鍵沖突檢查,也就是說,只有一台機器能夠插入成功,那么我們就認為向數據庫中插入數據的機器就是Master

但是當我們的Master機器掛掉了,那么誰能夠告訴我們Master掛掉了,關系型數據庫是無法通知我們這個事情的,但是ZooKeeper可以做到。

ZooKeeper能夠保證在分布式高並發情況下節點的創建一定能夠保證全局唯一性,ZooKeeper將會保證客戶端無法創建一個已經存在的數據單元節點。也就是說,如果同時有多個客戶端請求創建同一個臨時節點,那么最終一定只有一個客戶端請求能夠創建成功。利用這個特性,就能很容易的在分布式環境中進行Master選舉了,成功創建該節點的客戶端所在的機器就成為了Master,同時企業沒有成功創建該節點的客戶端,都會在該節點上注冊一個子節點變更的Watcher,用於監控當前的Master機器是否存活,一旦發現當前的Master掛了,那么其他客戶端將會重新進行Master選舉,這樣就實現了Master的動態選舉。

節點存世

ZooKeeper集群必須是奇數?

一個ZooKeeper集群通常由一組機器組成,一般是3台以上就可以組成一個可用的ZooKeeper集群了。只要集群中存在超過一半的機器能夠正常工作,那么ZooKeeper集群就能正常對外提供服務。

ZooKeeper選舉

在這里,有一個誤區,就是為了讓 ZooKeeper 群能夠正確的選舉出 leader 我們必須要把 ZooKeeper 集群服務器的數量設置為奇數,其實任意台的ZooKeeper都可以正常選舉出Leader和運行。

關於集群服務數量中,ZooKeeper官方也給出了奇數的建議,而且基於ZooKeeper 過半以上存活服務可用 的特性,如果ZooKeeper需要對外提供服務,那么至少要保證有過半存活的機器能夠正常工作,如果我們想要搭建一台允許掛點一定數量(N)的集群機器,那我們至少要部署 2*N+1台服務器來搭建ZooKeeper集群。

容錯率

從容錯率來講,我們要保證 過半以上存活的特性

如果我們允許掛掉1台服務,那我們至少要搭建(2*1+1)台服務器,也是就3台服務器(3的半數為1.5,默認向下取整為1,半數以上那就是2)

如果我們允許掛掉2台服務,那我們至少要搭建(2*1+1)台服務器,也是就5台服務器(5的半數為2.5,默認向下取整為2,半數以上那就是3)

同樣我們部署六台機器,那么我們遵循過半以上存活服務可用的特性,同樣也只能掛掉2台服務器,因為如果掛掉3台,無法遵循服務過半的特性

因此,我們可以從上面條件中看到,對於一個由6台服務器構成的ZooKeeper集群來說,和一個用5台服務器構成的ZooKeeper集群,在容災能力上沒有任何的顯著優勢,所以ZooKeeper集群 通常會設置成奇數台服務器即可

下載

下載地址:https://zookeeper.apache.org/releases.html

安裝

ZooKeeper安裝首先需要安裝JDK,ZooKeeper的安裝步驟在上一篇文章中介紹過,大家感興趣的可以看一下:https://muxiaonong.blog.csdn.net/article/details/120543298

修改配置

當我們將conf下的 zoo_sample.cfg 文件復制並重命名為 zoo.cfg 文件后,通過 vim zoo.cfg命令對這個文件進行修改:

m牧小農的ZK服務器配置

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

## Metrics Providers
#
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true

server.1=192.168.5.129:2888:3888
server.2=192.168.5.130:2888:3888
server.3=192.168.5.131:2888:3888

tickTime: 客戶端與服務端或者服務端和服務端之間維持心跳的時間間隔,每隔tickTime時間就會發送一個心跳,通過心跳不僅能夠用來監聽機器的工作狀態,還可以通過心跳來控制follower和Leader的通信時間,默認情況下FL(Follower和Leader)的會話通常是心跳間隔的兩倍,單位為毫秒。

initLimit: 集群中的follower服務器與Leader服務器之間的初始連接時能容忍的最多心跳數量

syncLimit: 急群眾的follower服務器與leader服務器之間的請求和回答最多能容忍的心跳數量

dataDir: 目錄地址,用來存放myid信息和一些版本、日志、服務器唯一ID等信息

clientPort: 監聽客戶端連接的端口

server.n=127.0.0.1:2888:3888

n:代表的是一個數字,表示這個服務器的標號
127.0.0.1:IP服務器地址
2888:ZooKeeper服務器之間的通信端口
3888:Leader選舉的端口

兩個需要修改的點:

  1. 修改的是目錄結構(dataDir),不要用它默認的
  2. 添加server.1 集群服務器配置信息

官方參考文檔:https://zookeeper.apache.org/doc/r3.5.8/zookeeperStarted.html

創建服務器ID

在這里我們需要創建一個 myid 的文件,我們需要在 dataDir 指定的目錄下,手動創建這個目錄。

創建命令:mkdir -p /tmp/zookeeper

然后在myid 文件里面添加對應的server.1中的 “1” 這個數字,如下所示

[root@VM-0-7-centos zookeeper]# more myid 
1

后面的機器,依次在 dataDir 指定的目錄下(/tmp/zookeeper),創建 myid 文件,寫上相應配置的數字,比如我們在zoo.cfg后面寫的是server.1,那么當前myid的文件就寫一個數字1就可以了

server.1=192.168.5.129:2888:3888
server.2=192.168.5.130:2888:3888
server.3=192.168.5.131:2888:3888

配置環境變量

為了方便我們可以在全局使用ZooKeeper命令,我們需要配置ZooKeeper的環境變量。

通過命令:vi /etc/profile

添加ZooKeeper的環境變量。

export JAVA_HOME=/usr/local/java/jdk1.8.0_261
export ZK_HOME=/usr/local/java/apache-zookeeper-3.7.0-bin/
export PATH=$PATH:$JAVA_HOME/bin:$ZK_HOME/bin

變量生效:source /etc/profile

關閉防火牆

在這里大家記得,如果是生產或者正式的,需要開放對應的端口進行通信。

如果是我們測試用的服務器,需要關閉防火牆,不然會有攔截,無法進行服務之間的通信,在這里我們是測試,關閉防火牆即可。
這里我使用的服務是CentOS 7.0,默認使用的是firewall作為防火牆。

防火牆設置

查看防火牆狀態:firewall-cmd --state

立即關閉防火牆,重啟失效:systemctl stop firewalld.service

禁止開機啟動防火牆:systemctl disable firewalld.service

端口設置

開放2888端口:firewall-cmd --zone=public --add-port=2888/tcp --permanent

關閉2888端口:firewall-cmd --zone=public --remove-port=2888/tcp --permanent

啟動服務

查看日志啟動命令:zkServer.sh start-foreground

后台啟動命令:zkServer.sh start

停止命令:zkServer.sh stop

查看狀態命令:zkServer.sh status

我們分別用 zkServer.sh status命令查看節點狀態,三台機器中,有兩台成為了 follower,一台成為了Leader節點。

一台服務器(follower)
兩台服務器(leader)
s三台服務器(follower)

使用命名查看ZooKeeper端口情況:netstat -natp | egrep '(2888|3888)'

查看服務器端口狀態
查看服務器端口狀態
查看服務器端口狀態

端口說明

3888:是選舉用的
2888:是leader接受write請求

因此我們可以看到130這一台機器出了有 130:2888以外還有130:3888 端口對自身進行監聽,這個是保證leader可以進行write操作的命令,具體通信如下所示:

集群通信

注意事項

如果搭建中出現問題,首先我們需要排查的問題,包含以下幾點

  1. 防火牆有沒有關閉
  2. zoo.cfg 下的文件路徑 dataDir 的目錄有沒有創建,不是自動創建的,需要我們進行手動創建,創建命令mkdir -p /tmp/zookeeper
  3. 我們可以通過 zkServer.sh start-foreground啟動過程的報錯信息

總結

到這里,關於ZooKeeper的集群就講解完畢了,主要介紹了ZooKeepe集群的作用和安裝部署,以及原理,今天的ZooKeeper集群到這里就講完了,下期精彩持續更新中。

碼字不易,感興趣的小伙伴記得點贊關注~

我是牧小農,怕什么真理無窮,進一步有進一步的歡喜,大家加油!


免責聲明!

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



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