etcd簡介
etcd是一個(gè)高可用的分布式鍵值(key-value)數(shù)據(jù)庫霸琴。etcd內(nèi)部采用raft協(xié)議作為一致性算法扑浸,etcd基于Go語言實(shí)現(xiàn)。
etcd是一個(gè)服務(wù)發(fā)現(xiàn)系統(tǒng),具備以下的特點(diǎn):
簡單:安裝配置簡單哮洽,而且提供了HTTP API進(jìn)行交互揖盘,使用也很簡單
安全:支持SSL證書驗(yàn)證
快速:根據(jù)官方提供的benchmark數(shù)據(jù)甩挫,單實(shí)例支持每秒2k+讀操作
可靠:采用raft算法吁断,實(shí)現(xiàn)分布式系統(tǒng)數(shù)據(jù)的可用性和一致性
etcd應(yīng)用場景
用于服務(wù)發(fā)現(xiàn),服務(wù)發(fā)現(xiàn)(ServiceDiscovery)要解決的是分布式系統(tǒng)中最常見的問題之一槐壳,即在同一個(gè)分布式集群中的進(jìn)程或服務(wù)如何才能找到對方并建立連接然低。
要解決服務(wù)發(fā)現(xiàn)的問題,需要具備下面三種必備屬性务唐。
一個(gè)強(qiáng)一致性雳攘、高可用的服務(wù)存儲(chǔ)目錄。
基于Ralf算法的etcd天生就是這樣一個(gè)強(qiáng)一致性枫笛、高可用的服務(wù)存儲(chǔ)目錄吨灭。
一種注冊服務(wù)和健康服務(wù)健康狀況的機(jī)制。用戶可以在etcd中注冊服務(wù)刑巧,并且對注冊的服務(wù)配置key TTL沃于,定時(shí)保持服務(wù)的心跳以達(dá)到監(jiān)控健康狀態(tài)的效果。
一種查找和連接服務(wù)的機(jī)制海诲。
通過在etcd指定的主題下注冊的服務(wù)業(yè)能在對應(yīng)的主題下查找到。為了確保連接檩互,我們可以在每個(gè)服務(wù)機(jī)器上都部署一個(gè)proxy模式的etcd特幔,這樣就可以確保訪問etcd集群的服務(wù)都能夠互相連接。
etcd安裝
etcd在生產(chǎn)環(huán)境中一般推薦集群方式部署闸昨。在這里蚯斯,主要講講單節(jié)點(diǎn)安裝和基本使用薄风。
因?yàn)閑tcd是go語言編寫的,安裝只需要下載對應(yīng)的二進(jìn)制文件拍嵌,并放到合適的路徑就行遭赂。
下載軟件包
$ wget https://github.com/coreos/etcd/releases/download/v3.1.5/etcd-v3.1.5-linux-amd64.tar.gz
$ tar xzvf etcd-v3.1.5-linux-amd64.tar.gz
$ mv etcd-v3.1.5-linux-amd64 /opt/etcd
這里可以嘗試直接打開https://github.com/coreos/etcd/releases/download/v3.1.5/etcd-v3.1.5-linux-amd64.tar.gz 進(jìn)行下載,經(jīng)測試?yán)胓it工具下載比通過谷歌下載慢横辆,可能是我谷歌翻墻的原因撇他。
解壓后的文件如下所示:
root@rice:/opt/etcd# ls
Documentation etcd etcdctl README-etcdctl.md README.md READMEv2-etcdctl.md
其中etcd是server端,etcdctl是客戶端狈蚤,操作之后會(huì)生成一個(gè)default.etcd困肩,主要用來存儲(chǔ)etct數(shù)據(jù)。
啟動(dòng)一個(gè)單節(jié)點(diǎn)的etcd服務(wù)脆侮,只需要運(yùn)行etcd命令就行锌畸。不過有可能會(huì)出現(xiàn)以下問題:
root@rice:/opt/etcd# ./etcd
bash: ./etcd: 權(quán)限不夠
這個(gè)時(shí)候需要提高文件的權(quán)限,采用如下方法:
root@rice:/opt/etcd# chmod 777 etcd
再次啟動(dòng)etcd靖避,成功后可以看見以下提示:
root@rice:/opt/etcd# ./etcd
2017-08-02 10:41:26.241044 I | etcdmain: etcd Version: 3.1.5
2017-08-02 10:41:26.241150 I | etcdmain: Git SHA: 20490ca
2017-08-02 10:41:26.241170 I | etcdmain: Go Version: go1.7.5
2017-08-02 10:41:26.241187 I | etcdmain: Go OS/Arch: linux/amd64
2017-08-02 10:41:26.241205 I | etcdmain: setting maximum number of CPUs to 4, total number of available CPUs is 4
2017-08-02 10:41:26.241230 W | etcdmain: no data-dir provided, using default data-dir ./default.etcd
2017-08-02 10:41:26.241730 I | embed: listening for peers on http://localhost:2380
2017-08-02 10:41:26.241883 I | embed: listening for client requests on localhost:2379
2017-08-02 10:41:26.246016 I | etcdserver: name = default
2017-08-02 10:41:26.246058 I | etcdserver: data dir = default.etcd
2017-08-02 10:41:26.246078 I | etcdserver: member dir = default.etcd/member
2017-08-02 10:41:26.246095 I | etcdserver: heartbeat = 100ms
2017-08-02 10:41:26.246110 I | etcdserver: election = 1000ms
2017-08-02 10:41:26.246127 I | etcdserver: snapshot count = 10000
2017-08-02 10:41:26.246153 I | etcdserver: advertise client URLs = http://localhost:2379
2017-08-02 10:41:26.246173 I | etcdserver: initial advertise peer URLs = http://localhost:2380
2017-08-02 10:41:26.246201 I | etcdserver: initial cluster = default=http://localhost:2380
2017-08-02 10:41:26.252215 I | etcdserver: starting member 8e9e05c52164694d in cluster cdf818194e3a8c32
2017-08-02 10:41:26.252400 I | raft: 8e9e05c52164694d became follower at term 0
2017-08-02 10:41:26.252455 I | raft: newRaft 8e9e05c52164694d [peers: [], term: 0, commit: 0, applied: 0, lastindex: 0, lastterm: 0]
2017-08-02 10:41:26.252492 I | raft: 8e9e05c52164694d became follower at term 1
2017-08-02 10:41:26.268040 I | etcdserver: starting server... [version: 3.1.5, cluster version: to_be_decided]
2017-08-02 10:41:26.268837 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32
2017-08-02 10:41:26.553047 I | raft: 8e9e05c52164694d is starting a new election at term 1
2017-08-02 10:41:26.553127 I | raft: 8e9e05c52164694d became candidate at term 2
2017-08-02 10:41:26.553144 I | raft: 8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at term 2
2017-08-02 10:41:26.553159 I | raft: 8e9e05c52164694d became leader at term 2
2017-08-02 10:41:26.553170 I | raft: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2
2017-08-02 10:41:26.553336 I | etcdserver: setting up the initial cluster version to 3.1
2017-08-02 10:41:26.555447 N | etcdserver/membership: set the initial cluster version to 3.1
2017-08-02 10:41:26.555481 I | etcdserver/api: enabled capabilities for version 3.1
2017-08-02 10:41:26.555506 I | embed: ready to serve client requests
2017-08-02 10:41:26.555636 I | etcdserver: published {Name:default ClientURLs:[http://localhost:2379]} to cluster cdf818194e3a8c32
2017-08-02 10:41:26.555852 N | embed: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
從上面的輸出中潭枣,我們可以看到很多信息。以下是幾個(gè)比較重要的信息:
2017-08-02 10:41:26.246016 I | etcdserver: name = default
name表示節(jié)點(diǎn)名稱幻捏,默認(rèn)為default盆犁。
2017-08-02 10:41:26.246058 I | etcdserver: data dir = default.etcd
data-dir 保存日志和快照的目錄,默認(rèn)為當(dāng)前工作目錄default.etcd/目錄下粘咖。
2017-08-02 10:41:26.246201 I | etcdserver: initial cluster = default=http://localhost:2380
在http://localhost:2380和集群中其他節(jié)點(diǎn)通信蚣抗。
2017-08-02 10:41:26.246153 I | etcdserver: advertise client URLs = http://localhost:2379
在http://localhost:2379提供HTTP API服務(wù),供客戶端交互瓮下。
2017-08-02 10:41:26.246095 I | etcdserver: heartbeat = 100ms
heartbeat為100ms翰铡,該參數(shù)的作用是leader多久發(fā)送一次心跳到followers,默認(rèn)值是100ms讽坏。
2017-08-02 10:41:26.246110 I | etcdserver: election = 1000ms
election為1000ms锭魔,該參數(shù)的作用是重新投票的超時(shí)時(shí)間,如果follow在該時(shí)間間隔沒有收到心跳包路呜,會(huì)觸發(fā)重新投票迷捧,默認(rèn)為1000ms。
2017-08-02 10:41:26.246127 I | etcdserver: snapshot count = 10000
snapshot count為10000胀葱,該參數(shù)的作用是指定有多少事務(wù)被提交時(shí)漠秋,觸發(fā)截取快照保存到磁盤。
集群和每個(gè)節(jié)點(diǎn)都會(huì)生成一個(gè)uuid抵屿。
啟動(dòng)的時(shí)候會(huì)運(yùn)行raft庆锦,選舉出leader。
采用這種方式啟動(dòng)的etcd只是一個(gè)程序轧葛,如果啟動(dòng)etcd的窗口被關(guān)閉的話則etcd便會(huì)被關(guān)閉
搂抒,所以如果要長期使用的話最好是為etcd開啟一個(gè)服務(wù)艇搀,此處便不提供開啟服務(wù)的方法,如果有需要讀者可以自行百度求晶。
打開另一個(gè)窗口輸入:
root@rice:/opt/etcd# ./etcd -version
可以看到etcd等的版本信息
etcd Version: 3.1.5
Git SHA: 20490ca
Go Version: go1.7.5
Go OS/Arch: linux/amd64
那么etcd如何使用呢?
etcd廠商為我們提供提供了一個(gè)命令行客戶端---etcdctl焰雕,供用戶直接跟etcd服務(wù)打交道,而無需基于 HTTP API方式芳杏【仄ǎ可以方便我們在對服務(wù)進(jìn)行測試或者手動(dòng)修改數(shù)據(jù)庫內(nèi)容。
etcdctl支持的命令大體上分為數(shù)據(jù)庫操作和非數(shù)據(jù)庫操作兩類蚜锨。
可以使用 ./etcdctl -h 查看etcdctl的用法:
root@rice:/opt/etcd# ./etcdctl -h 查看etcdctl的用法:
NAME:
etcdctl - A simple command line client for etcd.
USAGE:
etcdctl [global options] command [command options] [arguments...]
VERSION:
3.1.5
COMMANDS:
backup backup an etcd directory
cluster-health check the health of the etcd cluster
mk make a new key with a given value
mkdir make a new directory
rm remove a key or a directory
rmdir removes the key if it is an empty directory or a key-value pair
get retrieve the value of a key
ls retrieve a directory
set set the value of a key
setdir create a new directory or update an existing directory TTL
update update an existing key with a given value
updatedir update an existing directory
watch watch a key for changes
exec-watch watch a key for changes and exec an executable
member member add, remove and list subcommands
user user add, grant and revoke subcommands
role role add, grant and revoke subcommands
auth overall auth controls
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--debug output cURL commands which can be used to reproduce the request
--no-sync don't synchronize cluster information before sending request
--output simple, -o simple output response in the given format (simple, `extended` or `json`) (default: "simple")
--discovery-srv value, -D value domain name to query for SRV records describing cluster endpoints
--insecure-discovery accept insecure SRV records describing cluster endpoints
--peers value, -C value DEPRECATED - "--endpoints" should be used instead
--endpoint value DEPRECATED - "--endpoints" should be used instead
--endpoints value a comma-delimited list of machine addresses in the cluster (default: "http://127.0.0.1:2379,http://127.0.0.1:4001")
--cert-file value identify HTTPS client using this SSL certificate file
--key-file value identify HTTPS client using this SSL key file
--ca-file value verify certificates of HTTPS-enabled servers using this CA bundle
--username value, -u value provide username[:password] and prompt if password is not supplied.
--timeout value connection timeout per request (default: 2s)
--total-timeout value timeout for the command execution (except watch) (default: 5s)
--help, -h show help
--version, -v print the version
數(shù)據(jù)庫操作圍繞對鍵值和目錄的CRUD完整生命周期的管理档插。
etcd在鍵的組織上采用了層次化的空間結(jié)構(gòu)(類似于文件系統(tǒng)中目錄的概念),用戶指定的鍵可以為單獨(dú)的名字亚再,如:testkey郭膛,此時(shí)實(shí)際上放在根目錄/下面,也可以為指定目錄結(jié)構(gòu)氛悬,如/cluster1/node2/testkey则剃,則將創(chuàng)建相應(yīng)的目錄結(jié)構(gòu)。
set
指定某個(gè)鍵的值如捅。
-ttl '0' 該鍵值的超時(shí)時(shí)間(單位為秒)棍现,不配置(默認(rèn)為0)則永不超時(shí)
--swap-with-value value 若該鍵現(xiàn)在的值是value,則進(jìn)行設(shè)置操作
--swap-with-index '0' 若該鍵現(xiàn)在的索引值是指定索引镜遣,則進(jìn)行設(shè)置操作
get
獲取指定鍵的值
例如:
root@rice:/opt/etcd# ./etcdctl set --ttl '5' key "Hello world"
Hello world
root@rice:/opt/etcd# ./etcdctl get key
Hello world
root@rice:/opt/etcd# ./etcdctl get key
Error: 100: Key not found (/key) [14]
第一個(gè)get是5秒內(nèi)的操作己肮,第二get是5秒后的操作,此刻key的值已經(jīng)消失了悲关。
update
對指定鍵進(jìn)行修改
--ttl '0' 超時(shí)時(shí)間(單位為秒)谎僻,不配置(默認(rèn)為 0)則永不超時(shí)。
root@rice:/opt/etcd# ./etcdctl update key "Hello world2"
Hello world2
root@rice:/opt/etcd# ./etcdctl get key
Hello world2
rm
刪除某個(gè)鍵值寓辱。
--dir 如果鍵是個(gè)空目錄或者鍵值對則刪除
--recursive 刪除目錄和所有子鍵
--with-value 檢查現(xiàn)有的值是否匹配
--with-index '0'檢查現(xiàn)有的index是否匹配
例如
root@rice:/opt/etcd# ./etcdctl rm key
PrevNode.Value: Hello world2
root@rice:/opt/etcd# ./etcdctl get key
Error: 100: Key not found (/key) [17]
mk
如果給定的鍵不存在艘绍,則創(chuàng)建一個(gè)新的鍵值。
--ttl '0' 超時(shí)時(shí)間(單位為秒)秫筏,不配置(默認(rèn)為 0)诱鞠。則永不超時(shí)
例如:
root@rice:/opt/etcd# ./etcdctl mk /test/key "Hello world"
Hello world
當(dāng)鍵存在的時(shí)候,執(zhí)行該命令會(huì)報(bào)錯(cuò)这敬,例如:
root@rice:/opt/etcd#./etcdctl mk /testdir/testkey "Hello world"
Error: 105: Key already exists (/testdir/testkey) [8]
mkdir
--ttl '0' 超時(shí)時(shí)間(單位為秒)航夺,不配置(默認(rèn)為0)則永不超時(shí)。
如果給定的鍵目錄不存在崔涂,則創(chuàng)建一個(gè)新的鍵目錄敷存。
例如:
root@rice:/opt/etcd#./etcdctl mkdir dir2
當(dāng)鍵目錄存在的時(shí)候,執(zhí)行該命令會(huì)報(bào)錯(cuò),例如:
root@rice:/opt/etcd#./etcdctl mkdir dir2
Error: 105: Key already exists (/dir2) [9]
setdir
創(chuàng)建一個(gè)鍵目錄锚烦。如果目錄不存在就創(chuàng)建,如果目錄存在更新目錄TTL帝雇。
--ttl '0' 超時(shí)時(shí)間(單位為秒)涮俄,不配置(默認(rèn)為0)則永不超時(shí)。
例如:
root@rice:/opt/etcd#./etcdctl setdir dir3
updatedir
更新一個(gè)已經(jīng)存在的目錄尸闸。
--ttl '0' 超時(shí)時(shí)間(單位為秒)彻亲,不配置(默認(rèn)為0)則永不超時(shí)。
例如:
root@rice:/opt/etcd#./etcdctl updatedir dir2
rmdir
刪除一個(gè)空目錄吮廉,或者鍵值對苞尝。
例如:
root@rice:/opt/etcd#./etcdctl setdir dir2
root@rice:/opt/etcd#./etcdctl rmdir dir2
若目錄不空會(huì)報(bào)錯(cuò),例如:
root@rice:/opt/etcd#./etcdctl set /dir/key hi
hi
root@rice:/opt/etcd#./etcdctl rmdir /dir
Error: 108: Directory not empty (/dir) [17]
ls
列出目錄(默認(rèn)為根目錄)下的鍵或者子目錄宦芦,默認(rèn)不顯示子目錄中內(nèi)容宙址。
--sort 將輸出結(jié)果排序
--recursive 如果目錄下有子目錄,則遞歸輸出其中的內(nèi)容
-p 對于輸出為目錄调卑,在最后添加/進(jìn)行區(qū)分
例如:
root@rice:/opt/etcd#./etcdctl ls
/dir
/dir2
/dir
例如:
root@rice:/opt/etcd#./etcdctl ls dir
/dir/key
非數(shù)據(jù)庫操作抡砂,非數(shù)據(jù)庫操作包括:備份、監(jiān)測恬涧、節(jié)點(diǎn)管理等
backup
備份etcd的數(shù)據(jù)注益。
--data-dir etcd的數(shù)據(jù)目錄
--backup-dir 備份到指定路徑
例如:
root@rice:/opt/etcd#./etcdctl backup --data-dir default.etcd --backup-dir /xx/xx
watch
監(jiān)測一個(gè)鍵值的變化,一旦鍵值發(fā)生更新溯捆,就會(huì)輸出最新的值并退出丑搔。
--forever 一直監(jiān)測直到用戶按CTRL+C退出
--after-index '0' 在指定index之前一直監(jiān)測
--recursive 返回所有的鍵值和子鍵值
例如:用戶更新key鍵值為test。
root@rice:/opt/etcd#./etcdctl set key "Hello world"
Hello world
root@rice:/opt/etcd#./etcdctl watch key
如圖提揍,窗口一直在監(jiān)控
當(dāng)我開啟另一窗口啤月,更新key的值后:
之前的監(jiān)控界面便打印出test,然后退出碳锈,如圖:
exec-watch
監(jiān)測一個(gè)鍵值的變化顽冶,一旦鍵值發(fā)生更新,就執(zhí)行給定命令售碳。
--after-index '0' 在指定 index 之前一直監(jiān)測
--recursive 返回所有的鍵值和子鍵值
例如:采用exec-watch設(shè)置如果key值被更新則啟動(dòng)ls命令:
root@rice:/opt/etcd# ./etcdctl exec-watch key -- sh -c 'ls'
當(dāng)我在另一個(gè)窗口update key的值之后强重,監(jiān)控的窗口打印出以下數(shù)據(jù),且監(jiān)控不會(huì)退出:
root@rice:/opt/etcd# ./etcdctl exec-watch key -- sh -c 'ls'
default.etcd etcd README-etcdctl.md READMEv2-etcdctl.md
Documentation etcdctl README.md
default.etcd etcd README-etcdctl.md READMEv2-etcdctl.md
Documentation etcdctl README.md
有興趣的可以試試贸人,哈哈哈间景!
root@rice:/opt/etcd# ./etcdctl exec-watch key -- sh -c './etcdctl update key '5''
member
list 列出etcd實(shí)例
add 添加etcd實(shí)例
remove 刪除etcd實(shí)例
查看集群中存在的節(jié)點(diǎn),例如:
root@rice:/opt/etcd# ./etcdctl member list
8e9e05c52164694d: name=default peerURLs=http://localhost:2380 clientURLs=http://localhost:2379 isLeader=true
刪除集群中存在的節(jié)點(diǎn)艺智,例如:
root@rice:/opt/etcd# ./etcdctl member remove 8e9e05c52164694d
Removed member 8e9e05c52164694d from cluster
向集群中新加節(jié)點(diǎn)倘要,例如:
root@rice:/opt/etcd# ./etcdctl member add etcd3 http://192.168.1.100:2380
Added member named etcd3 with ID 8e9e05c52164694d to cluster