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