ZooKeeper :搭建ZooKeeper叢集
本文将介紹如何搭建
ZooKeeper
叢集,部落客準備搭建由三個
ZooKeeper
節點組成的叢集,先需要建立三台虛拟機(
VirtualBox
可以複制虛拟機),系統為
CentOS7
,每台虛拟機配置相同,記憶體
2G
以及磁盤
8G
。如何建立虛拟機請參考這篇部落格:
- VirtualBox安裝CentOS7
還需要使用
XShell
來連接配接虛拟機,畢竟在
VirtualBox
上操作虛拟機比較麻煩。先使用
VirtualBox
進入虛拟機,查詢該虛拟機的
IP
位址(使用
ip addr
或者
ifconfig
指令),然後使用
XShell
來連接配接它。
- ip addr指令介紹
靜态IP位址
為了避免動态配置設定
IP
位址而造成的麻煩,将每台虛拟機的
IP
位址設定為靜态
IP
位址,這樣以後使用
XShell
連接配接虛拟機,就不需要每次使用
VirtualBox
進入虛拟機查詢新配置設定的
IP
位址了。
cd /etc/sysconfig/network-scripts/
該配置檔案對應虛拟機的網卡名,如下圖所示:
先在虛拟機中安裝
vim
,用來編輯這些配置檔案:
yum install -y vim
修改配置檔案,設定靜态
IP
位址:
vim ifcfg-enp0s3
BOOTPROTO="static" # 靜态IP位址,預設為動态配置設定
ONBOOT="yes" # 是否開機啟用
IPADDR=192.168.1.201 # 設定的靜态IP位址
NETMASK=255.255.255.0 # 子網路遮罩
GATEWAY=192.168.1.1 # 網關
DNS1=192.168.1.1 # DNS伺服器
IP
位址就設定成使用
VirtualBox
進入虛拟機查詢到的
IP
位址,子網路遮罩一般都是
24
位(
255.255.255.0
,和本地電腦是一樣的),為了簡單,将
GATEWAY
和
DNS
設定成本地電腦(
Windows10
)的網關即可:
ipconfig
将三台虛拟機都設定靜态
IP
位址之後,就可以将
VirtualBox
上的虛拟機關閉,再使用無界面啟動方式啟動這些虛拟機,然後使用
XShell
連接配接即可。
搭建ZooKeeper叢集
部落客将用
shell
腳本來搭建
ZooKeeper
叢集(腳本的流程使用
echo
指令進行了說明):
#!/bin/bash
# author: itkaven
# input: zookeeper_version ip1 ip2 ip3 quorum_port leader_election_port client_port my_id
# 工具包存放路徑
path="/usr/local"
# JDK解壓後的目錄名、壓縮包名
jdk_work="jdk1.8.0_202"
jdk_file="jdk-8u202-linux-x64.tar.gz"
# Zookeeper版本号、解壓後的目錄名、壓縮包名、資料存儲路徑、日志存儲路徑、用戶端連接配接端口
zookeeper_version="$1"
zookeeper_work="apache-zookeeper-$zookeeper_version-bin"
zookeeper_file="$zookeeper_work.tar.gz"
data_dir="$path/$zookeeper_work/data"
log_dir="$path/$zookeeper_work/log"
# zookeeper叢集的ip位址、quorum端口、leader選舉端口、用戶端連接配接端口以及該虛拟機在zookeeper叢集中的id
ip1="$2"
ip2="$3"
ip3="$4"
quorum_port="$5"
leader_election_port="$6"
client_port="$7"
my_id="$8"
cluster=("server.1=$ip1:$quorum_port:$leader_election_port"
"server.2=$ip2:$quorum_port:$leader_election_port"
"server.3=$ip3:$quorum_port:$leader_election_port")
install_jdk() {
if [ ! -e "$path/$jdk_work" ]; then
echo "沒有安裝JDK,準備安裝JDK($jdk_work)!"
if [ ! -e "$path/$jdk_file" ]; then
echo "請上傳JDK壓縮包($jdk_file)!"
else
echo "JDK壓縮包($jdk_file)已經上傳!"
echo "開始解壓!"
tar -zxvf "$path/$jdk_file" -C "$path"
echo "删除壓縮包!"
rm -f "$path/$jdk_file"
echo "配置JDK環境變量!"
echo "export JAVA_HOME=$path/$jdk_work" >> /etc/profile
source /etc/profile
echo "export CLASSPATH=.:$JAVA_HOME/lib/" >> /etc/profile
echo "export PATH=$JAVA_HOME/bin:$PATH" >> /etc/profile
source /etc/profile
fi
else
echo "已經安裝JDK($jdk_work)!"
fi
}
download_zookeeper() {
if [ -e "$path/$zookeeper_work" ]; then
echo "Zookeeper壓縮包已經存在!"
else
echo "Zookeeper壓縮包不存在,等待下載下傳!"
yum install -y wget
wget -P "$path" --no-check-certificate "https://downloads.apache.org/zookeeper/zookeeper-$zookeeper_version/$zookeeper_file"
echo "Zookeeper壓縮包下載下傳完成!"
echo "開始解壓Zookeeper壓縮包!"
tar -zxvf "$path/$zookeeper_file" -C "$path"
echo "删除Zookeeper壓縮包!"
rm -f "$path/$zookeeper_file"
fi
}
config_and_run_zookeeper() {
# shellcheck disable=SC2164
cd "$path/$zookeeper_work/conf"
echo "copy配置檔案(zoo_sample.cfg -> zoo.cfg)!"
cp "zoo_sample.cfg" "zoo.cfg"
echo "修改zoo.cfg配置檔案(dataDir=$data_dir clientPort=$client_port dataLogDir=$log_dir)!"
sed -i "s#dataDir=.*#dataDir=$data_dir#g" "zoo.cfg"
sed -i "s#clientPort=.*#clientPort=$client_port#g" "zoo.cfg"
echo "dataLogDir=$log_dir" >> "zoo.cfg"
echo "建立檔案夾($data_dir $log_dir)!"
mkdir "$data_dir" "$log_dir"
echo "添加可以使用TTL節點的配置!"
echo "extendedTypesEnabled=true" >> "zoo.cfg"
echo "添加zookeeper叢集配置!"
# shellcheck disable=SC2068
for config in ${cluster[@]} ; do
echo "$config" >> "zoo.cfg"
done
echo "$my_id" > "$data_dir/myid"
echo "為了友善,關閉防火牆!"
systemctl stop firewalld
echo "啟動Zookeeper!"
# shellcheck disable=SC2164
cd "$path/$zookeeper_work/bin"
./zkServer.sh start
}
if [ $# -ne "8" ]; then
echo "請輸入Zookeeper版本号、三台虛拟機的IP位址、quorum端口、leader選舉端口、用戶端連接配接端口以及該虛拟機在Zookeeper叢集中的id!"
else
install_jdk
download_zookeeper
config_and_run_zookeeper
fi
腳本的意圖:
- 安裝
,需要提前将JDK
壓縮包放到虛拟機的JDK
路徑下,部落客不喜歡使用/usr/local/
安裝yum
,但使用JDK
指令下載下傳wget
壓縮包得到的是缺損包,因為JDK
官方有驗證;是以部落客采取了折中的方式,手動上傳Oracle
壓縮包,檔案解壓和配置環境變量就通過腳本完成。JDK
- 下載下傳
(從ZooKeeper
官網),再進行解壓。ZooKeeper
- 配置與運作
,建立配置檔案ZooKeeper
(通過zoo.cfg
官方給的樣例配置檔案copy
),在配置檔案zoo_sample.cfg
中修改資料存儲路徑、日志存儲路徑以及用戶端連接配接端口這三個配置,以及添加可以使用zoo.cfg
節點的配置(TTL
)和extendedTypesEnabled=true
叢集配置(ZooKeeper
),最後建立server.id=ip:quorum_port:leader_election_port
檔案(在myid
資料存儲路徑下),内容為該虛拟機在dataDir
叢集中的ZooKeeper
(如果啟用了擴充功能,例如id
節點,由于内部限制,TTL
必須在id
之間)。關閉防火牆(友善遠端連接配接[1, 254]
以及ZooKeeper
叢集的互相通信),之後啟動ZooKeeper
。ZooKeeper
将下載下傳好的
JDK
壓縮包放到每台虛拟機的
/usr/local/
路徑下:
如果
JDK
版本和部落客不相同,需要修改腳本的這兩個變量:
# JDK解壓後的目錄名、壓縮包名
jdk_work="jdk1.8.0_202"
jdk_file="jdk-8u202-linux-x64.tar.gz"
先将該
shell
腳本複制到三台虛拟機上。
vim zookeeper.sh
儲存後再退出:
- 怎麼儲存退出 vim 編輯
修改
zookeeper.sh
腳本的權限(不然沒有運作權限):
chmod 700 zookeeper.sh
運作
zookeeper.sh
腳本:
./zookeeper.sh 3.6.3 192.168.1.199 192.168.1.200 192.168.1.201 2888 3888 9000 1
./zookeeper.sh 3.6.3 192.168.1.199 192.168.1.200 192.168.1.201 2888 3888 9000 2
./zookeeper.sh 3.6.3 192.168.1.199 192.168.1.200 192.168.1.201 2888 3888 9000 3
3.6.3
是
ZooKeeper
的版本号,三個
IP
位址就是三台虛拟機的
IP
位址,
2888
是
quorum
端口,
3888
是
leader
選舉端口,
9000
是用戶端連接配接端口,
1、2、3
是虛拟機在
ZooKeeper
叢集中的
id
。
server.1=192.168.1.199:2888:3888
server.2=192.168.1.200:2888:3888
server.3=192.168.1.201:2888:3888
等待
zookeeper.sh
腳本執行完成。
zookeeper.sh
腳本執行完成後,配置檔案
zoo.cfg
會被建立,并且添加指定的配置資訊。
這個
myid
檔案裡的内容是虛拟機在
ZooKeeper
叢集中的
id
,要和配置檔案
zoo.cfg
中的叢集配置對應(
server.id=ip:quorum_port:leader_election_port
,
ip
和
id
要對應)。
leader選舉
leader
選舉的原理以後再介紹,這裡隻是示範一下
ZooKeeper
叢集的
leader
選舉,先檢視叢集中每個
ZooKeeper
節點的狀态,現在節點
1
是
leader
節點:
當
ZooKeeper
叢集的
leader
節點當機後,
ZooKeeper
叢集會進行
leader
選舉,選擇新的
leader
節點,先在節點
1
上将
ZooKeeper
服務
stop
(模拟當機):
節點
3
被選舉為了
ZooKeeper
叢集新的
leader
。
資料同步
資料同步的原理以後再介紹,這裡隻是示範一下
ZooKeeper
叢集的資料同步,需要提前準備好
ZooKeeper
檔案(當然也可以在
ZooKeeper
節點上啟動用戶端來連接配接
ZooKeeper
叢集,這裡隻是想示範一下遠端登陸):
先在本地遠端連接配接
ZooKeeper
叢集中任意一個節點(節點
1
):
zkCli.cmd -timeout 5000 -server 192.168.1.199:9000
建立
/kaven
節點:
再在另外一個
ZooKeeper
叢集節點(節點
3
)上查詢是否存在
/kaven
節點: