網(wǎng)站開發(fā)的技術(shù)指標(biāo)企業(yè)網(wǎng)站建設(shè)規(guī)劃
目錄
etcd介紹:
etcd工作原理
選舉
復(fù)制日志
安全性
etcd工作場景
服務(wù)發(fā)現(xiàn)
etcd基本術(shù)語
etcd安裝(centos)
設(shè)置:etcd后臺運行
etcd 是云原生架構(gòu)中重要的基礎(chǔ)組件,由 CNCF 孵化托管。etcd 在微服務(wù)和 Kubernates 集群中不僅可以作為服務(wù)注冊與發(fā)現(xiàn),還可以作為 key-value 存儲的中間件
etcd介紹:
etcd 是 CoreOS 團(tuán)隊于 2013 年 6 月發(fā)起的開源項目,它的目標(biāo)是構(gòu)建一個高可用的分布式鍵值(key-value)數(shù)據(jù)庫。具有以下特點:
-
簡單:安裝配置簡單,而且提供了
HTTP API
進(jìn)行交互,使用也很簡單用curl
curl www.baidu.com
-
鍵值對存儲:將數(shù)據(jù)存儲在分層組織的目錄中,如同在標(biāo)準(zhǔn)文件系統(tǒng)中
-
監(jiān)測變更:監(jiān)測特定的鍵或目錄以進(jìn)行更改,并對值的更改做出反應(yīng)
-
安全:支持 SSL 證書驗證
-
快速:根據(jù)官方提供的 benchmark 數(shù)據(jù),單實例支持每秒 2k+ 讀操作
-
可靠:采用 raft 算法,實現(xiàn)分布式系統(tǒng)數(shù)據(jù)的可用性和一致性
etcd 采用 Go 語言編寫,它具有出色的跨平臺支持,很小的二進(jìn)制文件和強(qiáng)大的社區(qū)。 etcd 機(jī)器之間的通信通過 Raft 算法處理。
etcd 是一個高度一致的分布式鍵值存儲
,它提供了一種可靠的方式來存儲需要由分布式系統(tǒng)或機(jī)器集群訪問的數(shù)據(jù)。它可以優(yōu)雅地處理網(wǎng)絡(luò)分區(qū)期間的 leader 選舉
,以應(yīng)對機(jī)器的故障,即使是在 leader 節(jié)點發(fā)生故障時。
從簡單的 Web 應(yīng)用程序到 Kubernetes 集群,任何復(fù)雜的應(yīng)用程序都可以從 etcd 中讀取數(shù)據(jù)或?qū)?shù)據(jù)寫入 etcd。
etcd工作原理
etcd集群本身是一個分布式系統(tǒng),由多個節(jié)點相互通信構(gòu)成整體對外服務(wù)
,每個節(jié)點都存儲了完整的數(shù)據(jù),并且通過Raft協(xié)議保證每個節(jié)點維護(hù)的數(shù)據(jù)是一致的,在ETCD集群中任意時刻至多存在一個有效的主節(jié)點,由主節(jié)點處理所有來自客戶端寫操作,通過Raft協(xié)議保證寫操作對狀態(tài)機(jī)的改動會可靠的同步到其他節(jié)點,Raft協(xié)議如下圖所示:
Raft協(xié)議主要分為三個部分:選舉,復(fù)制日志,安全性
選舉
Raft協(xié)議是用于維護(hù)一組服務(wù)節(jié)點數(shù)據(jù)一致性的協(xié)議。這一組服務(wù)節(jié)點構(gòu)成一個集群,并且有一個主節(jié)點來對外提供服務(wù)。當(dāng)集群初始化,或者主節(jié)點掛掉后,面臨一個選舉問題。集群中每個節(jié)點,任意時刻處于Leader、Follower、Candidate
這三個角色之一,選舉特點如下:
-
當(dāng)集群初始化時候,每個節(jié)點都是Follower角色。
-
集群中存在至多1個有效的主節(jié)點,
通過心跳與其他節(jié)點同步數(shù)據(jù);
-
當(dāng)Follower在一定時間內(nèi)沒有收到來自主節(jié)點的心跳,會將自己角色改變?yōu)镃andidate,并
發(fā)起一次選舉投票。
-
當(dāng)收到
包括自己在內(nèi)超過半數(shù)節(jié)點贊成后,選舉成功
。 -
當(dāng)收到票數(shù)不足半數(shù)
選舉失敗,或者選舉超時
。 -
若本輪未選出主節(jié)點,
將進(jìn)行下一輪選舉(出現(xiàn)這種情況,是由于多個節(jié)點同時選舉,所有節(jié)點均為獲得過半選票)
。
-
-
Candidate節(jié)點收到來自主節(jié)點的信息
后,會立即終止
選舉過程,進(jìn)入Follower角色
。
為了避免陷入選舉失敗循環(huán),每個節(jié)點未收到心跳發(fā)起選舉的時間是一定范圍內(nèi)的隨機(jī)值,這樣能夠避免2個節(jié)點同時發(fā)起選舉。
復(fù)制日志
日志復(fù)制是指主節(jié)點將每次操作形成日志條目,并持久化到本地磁盤,然后通過網(wǎng)絡(luò)IO發(fā)送給其他節(jié)點
。其他節(jié)點根據(jù)日志的邏輯時鐘(TERM)和日志編號(INDEX)來判斷是否將該日志記錄持久化到本地
。當(dāng)主節(jié)點收到包括自己在內(nèi)超過半數(shù)節(jié)點成功返回
,那么認(rèn)為該日志是可提交的(committed),并將日志輸入到狀態(tài)機(jī),將結(jié)果返回給客戶端。
這里需要注意的是,每次選舉都會形成一個唯一的TERM編號,相當(dāng)于邏輯時鐘,每一條日志都有全局唯一的編號。
主節(jié)點通過網(wǎng)絡(luò)IO向其他節(jié)點追加日志。若某節(jié)點收到日志追加的消息,首先判斷該日志的TERM是否過期,以及該日志條目的INDEX是否比當(dāng)前以及提交的日志的INDEX跟早。若已過期,或者比提交的日志更早,那么就拒絕追加,并返回該節(jié)點當(dāng)前的已提交的日志的編號。否則將日志追加,并返回成功。
當(dāng)主節(jié)點收到其他節(jié)點關(guān)于日志追加的回復(fù)后,若發(fā)現(xiàn)有拒絕,則根據(jù)該節(jié)點返回的已提交日志編號,發(fā)生其編號下一條日志。
主節(jié)點向其他節(jié)點同步日志,還作了擁塞控制。主節(jié)點發(fā)現(xiàn)日志復(fù)制的目標(biāo)節(jié)點拒絕了某次日志追加消息,將進(jìn)入日志探測階段,一條一條發(fā)送日志,直到目標(biāo)節(jié)點接受日志,然后進(jìn)入快速復(fù)制階段,可進(jìn)行批量日志追加。
按照日志復(fù)制的邏輯,我們可以看到,集群中慢節(jié)點不影響整個集群的性能。另外一個特點是,數(shù)據(jù)只從主節(jié)點復(fù)制到Follower節(jié)點,這樣大大簡化了邏輯流程。Raft日志復(fù)制路程如下圖所示:
安全性
選舉和復(fù)制日志并不能保證節(jié)點間數(shù)據(jù)一致。當(dāng)一個某個節(jié)點掛掉了,一段時間后再次重啟,并剛好當(dāng)選為主節(jié)點。而在其掛掉這段時間內(nèi),集群若有超過半數(shù)節(jié)點存活,集群會正常工作,那么會有日志提交,這些提交的日志無法傳遞給掛掉的節(jié)點。當(dāng)掛掉的節(jié)點再次當(dāng)選舉節(jié)點,它將缺失部分已提交的日志。在這樣場景下,按Raft協(xié)議,它將自己日志復(fù)制給其他節(jié)點,會將集群已經(jīng)提交的日志給覆蓋掉,這顯然是不可接受的,對于出現(xiàn)這種問題解決辦法:
-
其他協(xié)議解決這個問題的辦法是,新當(dāng)選的主節(jié)點會詢問其他節(jié)點,和自己數(shù)據(jù)對比,確定出集群已提交數(shù)據(jù),然后將缺失的數(shù)據(jù)同步過來。這個方案有明顯缺陷,增加了集群恢復(fù)服務(wù)的時間(集群在選舉階段不可服務(wù)),并且增加了協(xié)議的復(fù)雜度。
-
Raft解決的辦法是,在選舉邏輯中,對能夠成為主節(jié)點加以限制,確保選出的節(jié)點已定包含了集群已經(jīng)提交的所有日志。如果新選出的主節(jié)點已經(jīng)包含了集群所有提交的日志,那就不需要從和其他節(jié)點比對數(shù)據(jù)了,簡化了流程,縮短了集群恢復(fù)服務(wù)的時間。
為什么只要仍然有超過半數(shù)節(jié)點存活,一定能夠選出包含所有日志數(shù)據(jù)的節(jié)點作為主節(jié)點呢?因為已經(jīng)提交的日志必然被集群中超過半數(shù)節(jié)點持久化,顯然前一個主節(jié)點提交的最后一條日志也被集群中大部分節(jié)點持久化。當(dāng)主節(jié)點掛掉后,集群中仍有大部分節(jié)點存活,那這存活的節(jié)點中一定存在一個節(jié)點包含了已經(jīng)提交的日志了,因此要求etcd集群節(jié)點數(shù)量為奇數(shù)(3,5,7,9……)
etcd工作場景
服務(wù)發(fā)現(xiàn)
ETCD服務(wù)發(fā)現(xiàn)示意圖如下圖所示:
服務(wù)發(fā)現(xiàn)是分布式系統(tǒng)中最常見的需要解決的問題之一,即在同一個分布式集群中的進(jìn)程或服務(wù),客戶端通過名字就可以查找和連接服務(wù)端。要解決服務(wù)發(fā)現(xiàn)的問題,需要有下面三點:
-
一個強(qiáng)一致性、高可用的服務(wù)存儲目錄。基于Raft算法的etcd天生就是這樣一個強(qiáng)一致性高可用的服務(wù)存儲目錄。
-
一種注冊服務(wù)和監(jiān)控服務(wù)健康狀態(tài)的機(jī)制。用戶可以在etcd中注冊服務(wù),并且對注冊的服務(wù)設(shè)置key TTL,定時保持服務(wù)的心跳以達(dá)到監(jiān)控健康狀態(tài)的效果。
-
一種查找和連接服務(wù)的機(jī)制。通過在etcd指定的主題快速找到服務(wù)地址。
etcd基本術(shù)語
Raft:etcd所采用的保證分布式系統(tǒng)強(qiáng)一致性的算法。
Node:一個Raft狀態(tài)機(jī)實例。
Member: 一個etcd實例。它管理著一個Node,并且可以為客戶端請求提供服務(wù)。
Cluster:由多個Member構(gòu)成可以協(xié)同工作的etcd集群。
Peer:對同一個etcd集群中另外一個Member的稱呼。
Client: 向etcd集群發(fā)送HTTP請求的客戶端。
WAL:預(yù)寫式日志,etcd用于持久化存儲的日志格式。
snapshot:etcd防止WAL文件過多而設(shè)置的快照,存儲etcd數(shù)據(jù)狀態(tài)。
Proxy:etcd的一種模式,為etcd集群提供反向代理服務(wù)。
Leader(領(lǐng)導(dǎo)者):Raft算法中通過競選而產(chǎn)生的處理所有數(shù)據(jù)提交的節(jié)點。
Follower(跟隨者):競選失敗的節(jié)點作為Raft中的從屬節(jié)點,為算法提供強(qiáng)一致性保證。
Candidate:當(dāng)Follower超過一定時間接收不到Leader的心跳時轉(zhuǎn)變?yōu)镃andidate開始Leader競選。
Term:某個節(jié)點成為Leader到下一次競選開始的時間周期,稱為一個Term。
lndex:數(shù)據(jù)項編號。Raft中通過Term和Index來定位數(shù)據(jù)。
etcd安裝(centos)
上傳etcd解壓安裝包(網(wǎng)絡(luò)下載太慢了)
tar -zxvf etcd-v3.4.3-linux-amd64.tar.gz
?
?
etcd:服務(wù)
?
etcdctl:操作命令
切換至etcd根目錄,將etcd和etcdctl二進(jìn)制文件復(fù)制到/usr/local/bin目錄這樣系統(tǒng)中可以直接調(diào)用etcd/etcdctl這兩個程序
cp etcd etcdctl /usr/local/bin
查看etcd版本
etcd --version
輸入命令etcd,即可啟動一個單節(jié)點的etcd服務(wù)
,ctrl+c即可停止服務(wù)
運行:
輸出內(nèi)容
?name表示節(jié)點名稱,默認(rèn)為default。
?data-dir 保存日志和快照的目錄,默認(rèn)為當(dāng)前工作目錄default.etcd/目錄下。
?在http://localhost:2380和集群中其他節(jié)點通信。
?在http://localhost:2379提供客戶端交互。
?heartbeat為100ms,該參數(shù)的作用是leader多久發(fā)送一次心跳到followers,默認(rèn)值是100ms。
?election為1000ms,該參數(shù)的作用是重新投票的超時時間,如果follow在該時間間隔沒有收到心跳包,會觸發(fā)重新投票,默認(rèn)為1000ms。
?snapshot count為10000,該參數(shù)的作用是指定有多少事務(wù)被提交時,觸發(fā)截取快照保存到磁盤
設(shè)置:etcd后臺運行
-
建立etcd相關(guān)目錄(即數(shù)據(jù)文件和配置文件的保存位置)
mkdir -p /var/lib/etcd/ && mkdir -p /etc/etcd/
-
創(chuàng)建etcd配置文件
vim /etc/etcd/etcd.conf
-
創(chuàng)建systemd配置文件
vim /etc/systemd/system/etcd.service
service內(nèi)容
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
?
[Service]
User=root
Type=notify
WorkingDirectory=/var/lib/etcd/
## 根據(jù)實際情況修改EnvironmentFile和ExecStart這兩個參數(shù)值
## 1.EnvironmentFile即配置文件的位置,注意“-”不能少
EnvironmentFile=-/etc/etcd/etcd.conf
## 2.ExecStart即etcd啟動程序位置
ExecStart=/usr/local/bin/etcd
Restart=on-failure
LimitNOFILE=65536
?
[Install]
WantedBy=multi-user.target
-
啟動/停止/查看etcd服務(wù)
systemctl daemon-reload 刷新服務(wù)
systemctl enable etcd 設(shè)置開機(jī)自啟
systemctl start etcd 啟動
systemctl status etcd 查看狀態(tài)
編輯配置文件
查看etcd狀態(tài) 默認(rèn)關(guān)閉 systemctl status etcd
啟動etcd systemctl start etcd
查看etcd指令內(nèi)容 etcdctl -h
put 放
etcdctl put name 內(nèi)容
get 拿
etcdctl get name
del 刪除數(shù)據(jù)
清空數(shù)據(jù)
etcdctl del / --prefix
刪除所有/test前綴的節(jié)點
etcdctl del /test --prefix
watch,監(jiān)測一個鍵值的變化,一旦鍵值發(fā)生更新,就會輸出最新的值并退出
etcdctl watch key1
👌👌👌👌👌👌👌👌👌👌👌👌👌👌👌🎆🎇🧨