Etcd叢集的介紹和選主應用
女主宣言
ETCD作為開源、分散式、高可用、強一致性的key-value儲存系統,提供了配置共享和服務發現等眾多功能。目前已廣泛應用在kubernetes、ROOK、CoreDNS、M3以及openstack等領域。本文作者基於公司內部的場景需求,對etcd進行了介紹,並對選主機制進行了實踐,下來就跟隨作者一起學習下吧。
背景介紹
在實際生產環境中,有很多應用在同一時刻只能啟動一個例項,例如更新資料庫的操作,多個例項同時更新不僅會降低系統效能,還可能導致資料的不一致。但是單點部署也使得系統的容災性減弱,比如程式異常退出。目前程式保活,也有很多方案,如supervisor和systemd。但是,如果宿主機down掉呢?所有的程式保活方法都會無濟於事。本文基於etcd自帶的leader選舉機制,輕鬆的使服務具備了高可用性。
Etcd簡介
Etcd是一個開源的、高度一致的分散式key-value儲存系統。由Go語言實現,具有很好的跨平臺性。主要用於配置共享和服務發現。透過raft演算法維護叢集中各個節點的通訊和資料一致性,節點之間是對等的關係,即使leader節點故障,會很快選舉出新的leader,保證系統的正常執行。目前已廣泛應用在kubernetes、ROOK、CoreDNS、M3、openstack等領域。
介面操作簡單,提供了http+json和grpc介面。 可選的ssl客戶端認證,支援https訪問。 每個例項支援1000的QPS,適用於儲存資料量小但更新和訪問頻繁的資料。 資料按照檔案系統的方式,分層儲存,資料持久化。 監視特定的鍵或目錄的變化,並對值的更改做出響應,適用於訊息的釋出和訂閱。
Etcd架構及工作原理
架構
Etcd的架構如下圖所示,主要分為四部分。HTTP server、Store、Raft和WAL。
HTTP server:為使用者提供的Api請求。 Store:用於處理 etcd 支援的各類功能的事務,包括資料索引、節點狀態變更、監控與反饋、事件處理與執行等等。 Raft:利用raft演算法,保證節點之間資料的強一致性。 WAL:資料儲存方式。透過 WAL 進行資料持久化儲存。Snapshot 儲存資料的狀態快照;Entry 表示儲存的具體日誌內容。
工作原理
ETCD叢集是一個分散式系統,每個ETCD節點都維護了一個狀態機,並且儲存了完整的資料,任意時刻至多存在一個有效的主節點。主節點處理所有來自客戶端的讀寫操作。其中狀態機的狀態轉換規則如下:
ETCD中每個節點的狀態集合為(Follower、Candidate、Leader),叢集初始化時候,每個節點都是Follower角色,當Follower在一定時間內沒有收到來自主節點的心跳,會將自己角色改變為Candidate,併發起一次選主投票;當收到包括自己在內超過半數節點贊成後,選舉成功;當收到票數不足半數選舉失敗,或者選舉超時。若本輪未選出主節點,將進行下一輪選舉。當某個Candidate節點成為Leader後,Leader節點會透過心跳與其他節點同步資料,同時參與競選的Candidate節點進入Follower角色。
Etcd叢集搭建及基本應用
部署環境
一鍵安裝etcd
1、建立安裝指令碼build.sh。
ETCD_VER=v3.4.7# choose either URLGOOGLE_URL={GITHUB_URL}rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gzrm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-testcurl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gztar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gzcp /tmp/etcd-download-test/etcd /usr/binetcd --versioncp /tmp/etcd-download-test/etcdctl /usr/binetcdctl version
2、或者執行以下命令,指令碼已上傳到公網S3儲存。
wget -qO- | bash
etcd配置和systemd保活
1、 建立etcd配置檔案/etc/etcd/etcd.conf。
ETCD_NAME=instance01ETCD_DATA_DIR="/usr/local/etcd/data"ETCD_LISTEN_CLIENT_URLS="
ETCD_NAME:本member的名稱; ETCD_DATA_DIR:儲存資料的目錄; ETCD_LISTEN_CLIENT_URLS:用於監聽客戶端etcdctl或者curl連線; ETCD_ADVERTISE_CLIENT_URLS: 本機地址, 用於通知客戶端,客戶端透過此IPs與叢集通訊; ETCD_INITIAL_ADVERTISE_PEER_URLS:本機地址,用於通知叢集member,與member通訊; ETCD_LISTEN_PEER_URLS:用於監聽叢集中其它member的連線; ETCD_INITIAL_CLUSTER:描述叢集中所有節點的資訊,本member根據此資訊去聯絡其他member; ETCD_INITIAL_CLUSTER_STATE:叢集狀態,新建叢集時候設定為new,若是想加入某個已經存在的叢集設定為existing。
[Unit] Description=Etcd Server After=network.target [Service] Type=simple WorkingDirectory=/var/lib/etcd/ EnvironmentFile=-/etc/etcd/etcd.conf ExecStart=/usr/bin/etcd KillMode=process Restart=always RestartSec=3 LimitNOFILE=655350 LimitNPROC=655350 PrivateTmp=false SuccessExitStatus=143 [Install] WantedBy=multi-user.target
3、 啟動etcd。
systemctl daemon-reload
systemctl enable etcd.service
systemctl start etcd.service
4、 檢視etcd叢集狀態。
HOST_1=10.143.74.108
HOST_2=10.202.253.147
HOST_3=10.202.254.213
ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
etcdctl -w table --endpoints=$ENDPOINTS endpoint status
5、 讀寫以及刪除操作。
6、 watch監聽操作。
至此,在10.143.74.108主機上,我們已經成功安裝、啟動etcd服務,並測試了基本的功能。其他兩臺機器的配置類似,在此不再做介紹。
Etcd選主在Go中的實踐
下來我們一起看下專案中如何利用etcd的選主機制來實現應用的高可用吧。
go get "github.com/coreos/etcd/clientv3"
2、新增常量。
const prefix = "/nanoPing" const prop = "local" var leaderFlag bool
3、編寫client節點競選函式campaign。
func campaign(c *clientv3.Client, election string, prop string) {
for {
//gets the leased session for a client
s, err := concurrency.NewSession(c, concurrency.WithTTL(15))
if err != nil {
log.Println(err)
continue
}
//returns a new election on a given key prefix
e := concurrency.NewElection(s, election)
ctx := context.TODO()
//Campaign puts a value as eligible for the election on the prefix key.
//Multiple sessions can participate in the election for the same prefix,
//but only one can be the leader at a time
if err = e.Campaign(ctx, prop); err != nil {
log.Println(err)
continue
}
log.Println("elect: success")
leaderFlag = true
select {
case <-s.Done():
leaderFlag = false
log.Println("elect: expired")
}
}
}
4、新增競選成功後執行的動作run。
func run() { log.Println("[info] Service master") log.Println("[info] Task start.") }
5、編寫入口函式,建立client節點,參與競選master,競選成功,執行任務。
func Start() {
donec := make(chan struct{})
//create a client
cli, err := clientv3.New(clientv3.Config{Endpoints: g.Config().Etcd.Addr,Username:g.Config().Etcd.User,Password:g.Config().Etcd.Password})
if err != nil {
log.Fatal(err)
}
defer cli.Close()
go campaign(cli, prefix, prop)
go func() {
ticker := time.NewTicker(time.Duration(10) * time.Second)
for {
select {
case <-ticker.C:
{
if leaderFlag == true{
run()
return
}else{
log.Println("[info] Service is not master")
}
}
}
}
}()
<-donec
}
選主失敗的節點輸出:
Master節點程式退出後,之前的非master節點,自動競選為master節點。
總結
透過etcd中的選主機制,我們實現了服務的高可用。同時利用systemd對etcd本身進行了保活,只要etcd服務所在的機器沒有當機,程式就具備了容災性。當然,一個etcd叢集,不僅僅可以對一個服務提供高可用,我們可以將多個服務註冊在一個etcd叢集中,同時利用etcd所提供的共享配置和服務發現,此外,etcd還有很多值得深入研究的技術,比如raft一致性演算法等等,希望和大家能夠一起深入交流。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69966971/viewspace-2687644/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 三千字介紹Redis主從+哨兵+叢集Redis
- etcd叢集搭建
- Mongodb主從複製/ 副本集/分片叢集介紹MongoDB
- less的介紹和應用
- Redis 漸進叢集介紹Redis
- MySQL叢集 NDB 7.5介紹MySql
- Docker + Swarm + etcd 叢集搭建DockerSwarm
- RPM 的介紹和應用
- etcd 常用操作介紹
- solr叢集構建的基本流程介紹Solr
- Redis叢集介紹及測試思路Redis
- Redis 3.0介紹及叢集說明Redis
- nginx主主叢集Nginx
- 用Docker搭建RabbitMq的普通叢集和映象叢集DockerMQ
- 白話多叢集:工具和應用助手
- Redis介紹、使用、資料結構和叢集模式總結Redis資料結構模式
- ELK 在 Spark 叢集的應用Spark
- 叢集的應用例項(zt)
- 徹底搞懂 etcd 系列文章(三):etcd 叢集運維部署運維
- etcd簡介及叢集安裝部署使用
- Linux 下主要叢集 軟體(Cluster) 介紹Linux
- VictoriaMetrics 中文教程(10)叢集版介紹
- kubeadm部署k8s1.9高可用叢集–2搭建etcd叢集K8S
- Kubernetes安裝之三:etcd叢集的配置
- Xcode 文字巨集(Text Macros)的介紹和應用XCodeMacROS
- Spring IO Platform專案的介紹和應用SpringPlatform
- 反問面試官:如何實現叢集內選主面試
- 基於Dokcer搭建Redis叢集(主從叢集)Redis
- k8s介紹及與docker搭建叢集K8SDocker
- 簡單的介紹伺服器和Ajax的應用伺服器
- 災備建設中,跨主機叢集恢復技術應用
- Quartz叢集原理及配置應用quartz
- 應用級叢集系統的設計
- 基於etcd的選主功能實現的主備節點管理
- Sqlite 介紹及應用SQLite
- quay.io/coreos/etcd 基於Docker映象的叢集搭建Docker
- 分散式kv儲存系統之Etcd叢集分散式
- EJB叢集和Webservice叢集的討論Web