etcd 集羣搭建及常用場景分析

概述
etcd 是一個分佈式一致性k-v存儲系統,可用於服務註冊發現與共享配置,具有以下優點。
  • 簡單 : 相比於晦澀難懂的paxos算法,etcd基於相對簡單且易實現的raft算法實現一致性,並通過gRPC提供接口調用
  • 安全:支持TLS通信,並可以針對不同的用戶進行對key的讀寫控制
  • 高性能:10,000 /秒的寫性能
1. etcd單機模式
單機模式的etcd運行很簡單,只需到官網下載最新的二進制文件,執行即可
./bin/etcd
以上將使用默認配置運行etcd,監聽本地的2379端口,用於與client端交互,監聽2380用於etcd內部交互,當然,這裏單機不會使用到。
./etcdctl set hello world
world

./etcdctl get hello
world
通過etcdctl工具進行測試,以上表示單機可以工作。
2.etcd集羣模式
這裏的集羣模式是指完全集羣模式,當然也可以在單機上通過不同的端口,部署僞集羣模式,只是那樣做只適合測試環境,生產環境考慮到可用性的話需要將etcd實例分佈到不同的主機上,這裏集羣搭建有三種方式,分佈是靜態配置,etcd發現,dns發現
下面將在以下三臺主機上搭建etcd集羣,
infra0 10.0.1.111
infra1 10.0.1.109
infra2 10.0.1.110

2.1 配置項說明
--name
etcd集羣中的節點名,這裏可以隨意,可區分且不重複就行  
--listen-peer-urls
監聽的用於節點之間通信的url,可監聽多個,集羣內部將通過這些url進行數據交互(如選舉,數據同步等)
--initial-advertise-peer-urls 
建議用於節點之間通信的url,節點間將以該值進行通信。
--listen-client-urls
監聽的用於客戶端通信的url,同樣可以監聽多個。
--advertise-client-urls
建議使用的客戶端通信url,該值用於etcd代理或etcd成員與etcd節點通信。
--initial-cluster-token etcd-cluster-1
節點的token值,設置該值後集羣將生成唯一id,併爲每個節點也生成唯一id,當使用相同配置文件再啓動一個集羣時,只要該token值不一樣,etcd集羣就不會相互影響。
--initial-cluster
也就是集羣中所有的initial-advertise-peer-urls 的合集
--initial-cluster-state new
新建集羣的標誌

2.2 靜態配置
靜態配置主要預先將集羣的配置信息分配好,然後將集羣分佈啓動,集羣將根據配置信息組成集羣。這裏按如下的配置信息分別啓動三個etcd。
./etcd --name infra0 --initial-advertise-peer-urls http://10.0.1.111:2380 \
  --listen-peer-urls http://10.0.1.111:2380 \
  --listen-client-urls http://10.0.1.111:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://10.0.1.111:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=http://10.0.1.111:2380,infra1=http://10.0.1.109:2380,infra2=http://10.0.1.110:2380 \
  --initial-cluster-state new
./etcd --name infra1 --initial-advertise-peer-urls http://10.0.1.109:2380 \
  --listen-peer-urls http://10.0.1.109:2380 \
  --listen-client-urls http://10.0.1.109:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://10.0.1.109:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=http://10.0.1.111:2380,infra1=http://10.0.1.109:2380,infra2=http://10.0.1.110:2380 \
  --initial-cluster-state new
./etcd --name infra2 --initial-advertise-peer-urls http://10.0.1.110:2380 \
  --listen-peer-urls http://10.0.1.110:2380 \
  --listen-client-urls http://10.0.1.110:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://10.0.1.110:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=http://10.0.1.111:2380,infra1=http://10.0.1.109:2380,infra2=http://10.0.1.110:2380 \
  --initial-cluster-state new
按如上配置分別啓動集羣,啓動集羣后,將會進入集羣選舉狀態,若出現大量超時,則需要檢查主機的防火牆是否關閉,或主機之間是否能通過2380端口通信,集羣建立後通過以下命令檢查集羣狀態。

查看集羣成員
[root@localhost etcd-v2.3.4]# ./etcdctl  member list
4057b0d6df067950: name=infra0 peerURLs=http://10.0.1.111:2380 clientURLs=http://10.0.1.111:2379 isLeader=false
dca0fb8da20901bc: name=infra2 peerURLs=http://10.0.1.110:2380 clientURLs=http://10.0.1.110:2379 isLeader=true
dcdce7909200f701: name=infra1 peerURLs=http://10.0.1.109:2380 clientURLs=http://10.0.1.109:2379 isLeader=false

檢查集羣健康狀態
[root@localhost etcd-v2.3.4]# ./etcdctl cluster-health
member 4057b0d6df067950 is healthy: got healthy result from http://10.0.1.111:2379
member dca0fb8da20901bc is healthy: got healthy result from http://10.0.1.110:2379
member dcdce7909200f701 is healthy: got healthy result from http://10.0.1.109:2379
cluster is healthy
如上集羣搭建成功。

2.3 etcd發現
靜態配置前提是在搭建集羣之前已經提前知道各節點的信息,而實際應用中可能存在預先並不知道各節點ip的情況,這時可通過已經搭建的etcd來輔助搭建新的etcd集羣,具體過程如下,

首先需要在已經搭建的etcd中創建用於發現的url
curl -X PUT http://10.0.1.33:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/_config/size -d value=3

返回:
{"action":"set","node":{"key":"/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/_config/size","value":"3","modifiedIndex":170010,"createdIndex":170010}}
如上表示創建一個集羣大小爲3的etcd發現url,創建成功後按如下配置啓動各節點
./etcd --name infra0 --initial-advertise-peer-urls http://10.0.1.111:2380 \
  --listen-peer-urls http://10.0.1.111:2380 \
  --listen-client-urls http://10.0.1.111:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://10.0.1.111:2379 \ --discovery http://10.0.1.33:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83 ./etcd --name infra1 --initial-advertise-peer-urls http://10.0.1.109:2380 \
  --listen-peer-urls http://10.0.1.109:2380 \
  --listen-client-urls http://10.0.1.109:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://10.0.1.109:2379 \
 --discovery http://10.0.1.33:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83

./etcd --name infra2 --initial-advertise-peer-urls http://10.0.1.110:2380 \
  --listen-peer-urls http://10.0.1.110:2380 \
  --listen-client-urls http://10.0.1.110:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://10.0.1.110:2379 \
  --discovery http://10.0.1.33:2379/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83

如上當所有etcd均註冊到用於發現的url後,獨立的各節點將形成集羣。

另一方面,如果沒有搭建好的etcd集羣用於註冊和發現,可使用etcd公有服務來進行服務註冊發現。

在公有etcd服務上創建用於發現的url:
$curl https://discovery.etcd.io/new?size=3 

返回
https://discovery.etcd.io/5a2e5485d3579557f1a29d0e6ebe3bfb
將返回的url替換上面的 --discovery部分,啓動各個節點etcd,建立集羣。

2.4 dns發現
dns 發現主要通過dns服務來記錄集羣中各節點的域名信息,各節點到dns服務中獲取相互的地址信息,從而建立集羣。etcd各節點通過--discovery-serv配置來獲取域名信息,節點間將獲取以下域名下的各節點域名,
  • _etcd-server-ssl._tcp.example.com
  • _etcd-server._tcp.example.com
如果_etcd-server-ssl._tcp.example.com下有值表示節點間將使用ssl協議,相反則使用非ssl。
  • _etcd-client._tcp.example.com
  • _etcd-client-ssl._tcp.example.com
另一方面,client端將獲取以上域名下的節點域名,用於client端與etcd通信,ssl與非ssl的使用取決於以上那個域名下有值。

創建dns記錄
$ dig +noall +answer SRV _etcd-server._tcp.example.com
_etcd-server._tcp.example.com. 300 IN  SRV  0 0 2380 infra0.example.com.
_etcd-server._tcp.example.com. 300 IN  SRV  0 0 2380 infra1.example.com.
_etcd-server._tcp.example.com. 300 IN  SRV  0 0 2380 infra2.example.com.

$ dig +noall +answer SRV _etcd-client._tcp.example.com
_etcd-client._tcp.example.com. 300 IN SRV 0 0 2379 infra0.example.com.
_etcd-client._tcp.example.com. 300 IN SRV 0 0 2379 infra1.example.com.
_etcd-client._tcp.example.com. 300 IN SRV 0 0 2379 infra2.example.com.


$ dig +noall +answer infra0.example.com infra1.example.com infra2.example.com
infra0.example.com.  300  IN  A  10.0.1.111
infra1.example.com.  300  IN  A  10.0.1.109
infra2.example.com.  300  IN  A  10.0.1.110

然後啓動各個節點
$ etcd --name infra0 \
--discovery-srv example.com \
--initial-advertise-peer-urls http://infra0.example.com:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster-state new \
--advertise-client-urls http://infra0.example.com:2379 \
--listen-client-urls http://infra0.example.com:2379 \
--listen-peer-urls http://infra0.example.com:2380

$ etcd --name infra1 \
--discovery-srv example.com \
--initial-advertise-peer-urls http://infra1.example.com:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster-state new \
--advertise-client-urls http://infra1.example.com:2379 \
--listen-client-urls http://infra1.example.com:2379 \
--listen-peer-urls http://infra1.example.com:2380

$ etcd --name infra2 \
--discovery-srv example.com \
--initial-advertise-peer-urls http://infra2.example.com:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster-state new \
--advertise-client-urls http://infra2.example.com:2379 \
--listen-client-urls http://infra2.example.com:2379 \
--listen-peer-urls http://infra2.example.com:2380

3.etcd接口訪問

目前etcd已經支持很多語言的client端,目測主流語言均有對應的庫, 具體見https://github.com/coreos/etcd/blob/master/Documentation/libraries-and-tools.md,不同語言只需要導入相應的庫即可進行開發。

4. etcd使用場景簡述

說完etcd的搭建,這裏簡單的描述兩個常用的etcd使用場景,服務註冊發現以及共享配置
4.1 服務註冊與發現
隨着近來微服務概念的提出,服務的分解必然引入大量的服務之間的相互調用,而傳統的服務調用一般通過配置文件讀取ip進行調用,這裏有諸多限制,如不靈活,無法感知服務的狀態,實現服務調用負載均衡複雜等缺點,而引入etcd後,問題將大大化簡,這裏劃分爲幾個步驟



  • 服務啓動後向etcd註冊,並上報自己的監聽的端口以及當前的權重因子等信息,且對該信息設置ttl值。
  • 服務在ttl的時間內週期性上報權重因子等信息。
  • client端調用服務時向etcd獲取信息,進行調用,同時監聽該服務是否變化(通過watch方法實現)。
  • 當新增服務時watch方法監聽到變化,將服務加入代用列表,當服務掛掉時ttl失效,client端檢測到變化,將服務踢出調用列表,從而實現服務的動態擴展。
  • 另一方面,client端通過每次變化獲取到的權重因子來進行client端的加權調用策略,從而保證後端服務的負載均衡。
4.2 共享配置
一般服務啓動時需要加載一些配置信息,如數據庫訪問地址,連接配置,這些配置信息每個服務都差不多,如果通過讀取配置文件進行配置會存在要寫多份配置文件,且每次更改時這些配置文件都要更改,且更改配置後,需要重啓服務後才能生效,這些無疑讓配置極不靈活,如果將配置信息放入到etcd中,程序啓動時進行加載並運行,同時監聽配置文件的更改,當配置文件發生更改時,自動將舊值替換新值,這樣無疑簡化程序配置,更方便於服務部署。

5. 總結
本文講解了etcd集羣的搭建,以及簡述了一些應用場景,相比於zookeeper內部使用paxos算法保證一致性,而etcd則使用更簡單的raft算法。另一方面,相比zookeeper, etcd算是新興項目,因而在知名度及使用量來說和zookeeper有一定差距,不過,隨着越來越多的知名項目在逐漸使用etcd(如docker),相信etcd將會在未來更多的出現在各種服務體系中。目前我們已經在生產環境中大量使用etcd,從使用效果來看,穩定性還是不錯的,目前還沒遇到什麼大坑。

6.參考資料
https://coreos.com/etcd/
https://github.com/coreos/etcd

轉載於:http://blog.csdn.net/u010511236/article/details/52386229
發佈了0 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章