天天看點

etcdv3 叢集的搭建和使用

   etcd 是一個開源的分布式鍵值對資料庫,他的每一個節點都有一份資料的copy,當有節點故障時保證了高可用性。etcd使用 Raft

算法來保證一緻性。

  第一次接觸etcd是在學習k8s時。k8s用etcd做的服務發現。後來在開發一個分布式系統時需要用到服務發現,就想試一下用etcd做服務發現。效果還是很不錯的。

  這篇講一下etcd叢集的搭建和使用。

叢集的節點個數和容錯

官方推薦

的叢集個數為奇數個,如圖當節點為3個和為4個時的容錯都是1, 節點5個和6個時,容錯為2...

etcdv3 叢集的搭建和使用

  叢集的節點越多,容錯性會越強,但是資料的同步份數也會越多,寫性能會變差一些。合理的叢集大小,就是平衡容錯性和可寫性。

安裝叢集 

  準備三台伺服器  

172.31.43.166      
etcd0
172.31.43.114      
etcd1
172.31.34.237      
etcd2

  分别在三台伺服器上下載下傳etcd。這裡下載下傳的是版本3.3.8

ETCD_VER=v3.3.8

GITHUB_URL=https://github.com/coreos/etcd/releases/download
DOWNLOAD_URL=${GITHUB_URL}

rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

/tmp/etcd-download-test/etcd --version
ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl version      
etcdv3 叢集的搭建和使用
etcdv3 叢集的搭建和使用

   然後将兩個檔案都放到系統可執行目錄 /usr/local/bin/ 或 /usr/bin/

cd /tmp/etcd-download-test
sudo cp etcd* /usr/local/bin/      

   建立一個檔案夾用來儲存etcd的資料

sudo mkdir -p /data/etcd
sudo chown -R root:$(whoami) /data/etcd
sudo chmod -R a+rw /data/etcd      

  在這裡我使用static方式去搭建服務。

  編寫systemd服務檔案,分别在每台機器上編寫服務檔案:

cat > /tmp/etcd0.service <<EOF

[Unit]

Description=etcd

Documentation=https://github.com/coreos/etcd

Conflicts=etcd.service

Conflicts=etcd2.service

[Service]

Type=notify

Restart=always

RestartSec=5s

LimitNOFILE=40000

TimeoutStartSec=0

ExecStart=/usr/local/bin/etcd --name etcd0 \

--data-dir /data/etcd \

--initial-advertise-peer-urls http://172.31.43.166:2380 \

--listen-peer-urls http://172.31.43.166:2380 \

--listen-client-urls http://172.31.43.166:2379,http://127.0.0.1:2379 \

--advertise-client-urls http://172.31.43.166:2379 \

--initial-cluster-token etcd-cluster-pro \

--initial-cluster etcd0=http://172.31.43.166:2380,etcd1=http://172.31.43.114:2380,etcd2=http://172.31.34.237:2380 \

--initial-cluster-state new

[Install]

WantedBy=multi-user.target

EOF

sudo mv /tmp/etcd0.service /etc/systemd/system/etcd0.service

cat > /tmp/etcd1.service <<EOF

ExecStart=/usr/local/bin/etcd --name etcd1 \

--initial-advertise-peer-urls http://172.31.43.114:2380 \

--listen-peer-urls http://172.31.43.114:2380 \

--listen-client-urls http://172.31.43.114:2379,http://127.0.0.1:2379 \

--advertise-client-urls http://172.31.43.114:2379 \

sudo mv /tmp/etcd1.service /etc/systemd/system/etcd1.service

cat > /tmp/etcd2.service <<EOF
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
Conflicts=etcd.service

[Service]
Type=notify
Restart=always
RestartSec=5s
LimitNOFILE=40000
TimeoutStartSec=0

ExecStart=/usr/local/bin/etcd -name etcd2 \
  --data-dir /data/etcd \
  --initial-advertise-peer-urls http://172.31.34.237:2380 \
  --listen-peer-urls http://172.31.34.237:2380 \
  --listen-client-urls http://172.31.34.237:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://172.31.34.237:2379 \
  --initial-cluster-token etcd-cluster-pro \
  --initial-cluster etcd0=http://172.31.43.166:2380,etcd1=http://172.31.43.114:2380,etcd2=http://172.31.34.237:2380 \
  --initial-cluster-state new

[Install]
WantedBy=multi-user.target
EOF
sudo mv /tmp/etcd2.service /etc/systemd/system/etcd2.service      

下面是一些常用配置選項的說明:

--name:友善了解的節點名稱,預設為 default,在叢集中應該保持唯一

--data-dir:服務運作資料儲存的路徑,預設為 ${name}.etcd

--snapshot-count:指定有多少事務(transaction)被送出時,觸發截取快照儲存到磁盤

--heartbeat-interval:leader 多久發送一次心跳到 followers。預設值是 100ms

--eletion-timeout:重新投票的逾時時間,如果follower在該時間間隔沒有收到心跳包,會觸發重新投票,預設為 1000 ms

--listen-peer-urls:和同伴通信的位址,比如 http://ip:2380,如果有多個,使用逗号分隔。需要所有節點都能夠通路,是以不要使用 localhost

--advertise-client-urls:對外公告的該節點用戶端監聽位址,這個值會告訴叢集中其他節點

--listen-client-urls:對外提供服務的位址:比如 http://ip:2379,http://127.0.0.1:2379,用戶端會連接配接到這裡和etcd互動

--initial-advertise-peer-urls:該節點同伴監聽位址,這個值會告訴叢集中其他節點

--initial-cluster:叢集中所有節點的資訊,格式為 node1=http://ip1:2380,node2=http://ip2:2380,…。需要注意的是,這裡的 node1 是節點的--name指定的名字;後面的ip1:2380 是--initial-advertise-peer-urls 指定的值

--initial-cluster-state:建立叢集的時候,這個值為 new;假如已經存在的叢集,這個值為existing

--initial-cluster-token:建立叢集的token,這個值每個叢集保持唯一。這樣的話,如果你要重新建立叢集,即使配置和之前一樣,也會再次生成新的叢集和節點 uuid;否則會導緻多個叢集之間的沖突,造成未知的錯誤

  所有以--init開頭的配置都是在第一次啟動etcd叢集的時候才會用到,後續節點的重新開機會被忽略,如--initial-cluseter參數。是以當成功初始化了一個etcd叢集以後,就不再需要這個參數或環境變量了。

  如果服務已經運作過就要把修改 --initial-cluster-state 為existing

  啟用服務

sudo systemctl daemon-reload
sudo systemctl enable etcd0.service
sudo systemctl start etcd0.service


sudo systemctl daemon-reload
sudo systemctl enable etcd1.service
sudo systemctl start etcd1.service

sudo systemctl daemon-reload
sudo systemctl enable etcd2.service
sudo systemctl start etcd2.service      

 檢視 log:

sudo systemctl status etcd0.service -l --no-pager
sudo journalctl -u etcd0.service -l --no-pager|less
sudo journalctl -f -u etcd0.service


sudo systemctl status etcd1.service -l --no-pager
sudo journalctl -u etcd1.service -l --no-pager|less
sudo journalctl -f -u etcd1service


sudo systemctl status etcd2.service -l --no-pager
sudo journalctl -u etcd2.service -l --no-pager|less
sudo journalctl -f -u etcd2.service      

暫停

sudo systemctl stop etcd0.service
sudo systemctl disable etcd0.service

sudo systemctl stop etcd1.service
sudo systemctl disable etcd1.service

sudo systemctl stop etcd2.service
sudo systemctl disable etcd2.service      

 使用etcd

   我使用的etcd的api為v3版本。在使用指令時需要在前面加上ETCDCTL_API=3 

 如:檢視叢集成員

ETCDCTL_API=3 etcdctl member list      
etcdv3 叢集的搭建和使用

  可以看到有3個節點線上

叢集狀态

ETCDCTL_API=3  etcdctl   --endpoints 172.31.43.166:2379,172.31.34.237:2379,172.31.43.114:2379 endpoint status  --write-out="table"      
etcdv3 叢集的搭建和使用

操作資料

   使用put和get指令可以儲存和得到資料.del删除資料

etcdv3 叢集的搭建和使用

根據字首查詢

ETCDCTL_API=3 etcdctl put test1 a
 ETCDCTL_API=3 etcdctl put test2 b
 ETCDCTL_API=3 etcdctl put test3 c
 ETCDCTL_API=3 etcdctl get --prefix test      
etcdv3 叢集的搭建和使用

查詢所有資料

ETCDCTL_API=3 etcdctl get --from-key ""      
etcdv3 叢集的搭建和使用

 watch 監聽

   watch 會監聽key的變動 有變動時會在輸出。這也正是服務發現需要使用的。

   我們監聽 test鍵,然後對test執行修改和删除操作

ETCDCTL_API=3 etcdctl watch test      
etcdv3 叢集的搭建和使用
ETCDCTL_API=3 etcdctl put test abcde
ETCDCTL_API=3 etcdctl put test aaaa
 ETCDCTL_API=3 etcdctl del test      

lead 租約

   etcd可以為key設定逾時時間,但與redis不同,etcd需要先建立lease,然後使用put指令加上參數–lease=<lease ID>

etcdv3 叢集的搭建和使用

ETCDCTL_API=3 lease grant  ttl    建立lease,傳回lease ID ttl秒

ETCDCTL_API=3 lease revoke  leaseId  删除lease,并删除所有關聯的key 

ETCDCTL_API=3 lease timetolive leaseId 取得lease的總時間和剩餘時間 

ETCDCTL_API=3 lease keep-alive leaseId     keep-alive會不間斷的重新整理lease時間,進而保證lease不會過期。

分布式鎖

 使用lock指令後加鎖名稱 做分布式鎖,如果沒有顯示釋放鎖,其他地方隻能等待。

etcdctl --endpoints=$ENDPOINTS lock mutex1

# 在另一個終端輸入
etcdctl --endpoints=$ENDPOINTS lock mutex1      
etcdv3 叢集的搭建和使用