etcd api 接口


etcd api接口

  基本操作api: https://github.com/coreos/etcd/blob/6acb3d67fbe131b3b2d5d010e00ec80182be4628/Documentation/v2/api.md

  集群配置api: https://github.com/coreos/etcd/blob/6acb3d67fbe131b3b2d5d010e00ec80182be4628/Documentation/v2/members_api.md

  鑒權認證api: https://github.com/coreos/etcd/blob/6acb3d67fbe131b3b2d5d010e00ec80182be4628/Documentation/v2/auth_api.md

  配置項:https://github.com/coreos/etcd/blob/master/Documentation/op-guide/configuration.md

  

  https://coreos.com/etcd/docs/latest/runtime-configuration.html

  https://coreos.com/etcd/docs/latest/clustering.html

  https://coreos.com/etcd/docs/latest/runtime-configuration.html

  https://coreos.com/etcd/docs/latest/

  https://coreos.com/etcd/docs/latest/admin_guide.html#disaster-recovery

  采用標准的restful 接口,支持http 和 https 兩種協議。

運行單機etcd服務

1 ./bin/etcd

 

 監聽localhost和從IANA分配的端口,2379用於同client通訊,2389用於server與server直接的通訊。

 

獲取版本  /version

1 [root@vStack ~]# curl http://127.0.0.1:2379/version | python -m json.tool
2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
3                                  Dload  Upload   Total   Spent    Left  Speed
4 100    44  100    44    0     0  14093      0 --:--:-- --:--:-- --:--:-- 22000
5 {
6     "etcdcluster": "2.3.0",
7     "etcdserver": "2.3.7"
8 }

  

etcd 的基本API是一個分層的key空間。key空間由通常被稱為"nodes"(節點)的keys和目錄組成。

對datastore的訪問,即通過 /version/keys 端點(endpoint) 訪問key空間。

1. PUT 為etcd存儲的鍵賦值, 即創建 message 鍵值,賦值為"Hello world"

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/message -X PUT -d value="Hello world" | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   119  100   102  100    17  38230   6371 --:--:-- --:--:-- --:--:-- 51000
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 30,
 9         "key": "/message",
10         "modifiedIndex": 30,
11         "value": "Hello world"
12     }
13 }

  Response body返回值中的:

  action:   請求接口進行的動作名稱。 通過 http  PUT方法修改node.key的值,對應的action值為:"set“。  PUT方法中,請求body中存在 prevExist=true時, action為update; prevExist=false時,action為create; 其他為set

  node.createIndex:  etcd每次變化時創建的,唯一的,單調遞增的、整數值作為索引。這個特定的索引值反映了在etcd狀態成員里創建了一個給定key。除了用戶請求外,etcd內部運行(如啟動服務,重啟服務、集群信息變化:添加、刪除、同步服務等)也可能會因為對節點有變動而引起該值的變化。所以即使我們首次請求,此值也不是從1開始。update、get action不引起 node.createIndex值的變化。

       node.key:  在請求的HTTP路徑中,作為操作對象key。etcd使用一個類似文件系統的方式來反映鍵值存儲的內容, 因此所有的key都是以‘/’開始 。

      node.modifiedIndex:  像 node.createIndex, 這個屬性也是etcd的索引。 引起這個值變化的Actions包括:setdeleteupdatecreatecompareAndSwapcompareAndDelete。因為 get watchcommands 在存儲中不修改狀態,所以這兩個action不會修改mode.modifiedIndex值, 也不會修改 node.createIndex的值。 重啟服務等也會修改此屬性值。

      node.value:  處理完請求后的key值。 在上面的實例中,成功請求后,修改節點的值為 Hello world。

 

      Response header返回值中:

  在responses中包括一些的HTTP 的headers部,在header中提供了一些關於etcd集群的全部信息,集群提供服務請求。

1 X-Etcd-Cluster-Id: 7e27652122e8b2ae
2 X-Etcd-Index: 93
3 X-Raft-Index: 223696
4 X-Raft-Term: 8

    X-Etcd-Cluster-Id:  etcd 集群id。

  X-Etcd-Index:   當前etcd的索引,像前面的解釋。當在key空間進行watch時,watch開始時,X-Etcd-Index是當前etcd的索引值,這意味着watched事件可能發生在X-Etcd-Index之后。

  X-Raft-Index:   與X-Etcd-Index索引類似,是raft協議的索引。

  X-Raft-Term:    是一個在集群中發生master election時,將增長的整數。如果這個值增長的非常快,需要調優這個election超時。詳見 tuning 部分。

 

2. GET 查詢etcd某個鍵存儲的值

[root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/message | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   102  100   102    0     0  64110      0 --:--:-- --:--:-- --:--:--   99k
{
    "action": "get",
    "node": {
        "createdIndex": 19,
        "key": "/message",
        "modifiedIndex": 19,
        "value": "Hello world"
    }
}

 

3. PUT 修改鍵值:與創建新值幾乎相同,但是反饋時會有一個prevNode值反應了修改前存儲的內容。

  -d value=xxxx

[root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/message -X PUT -d value="RECREATE" | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   202  100   188  100    14  57108   4252 --:--:-- --:--:-- --:--:-- 62666
{
    "action": "set",
    "node": {
        "createdIndex": 33,
        "key": "/message",
        "modifiedIndex": 33,
        "value": "RECREATE"
    },
    "prevNode": {
        "createdIndex": 32,
        "key": "/message",
        "modifiedIndex": 32,
        "value": "Hello world"
    }
}

  Respone中新的字段 "prevNode", 這個字段表示當前請求完成前的請求節點的狀態。 prevNode的格式與node相同, 在訪問的節點沒有前面狀態時將被忽略。

 

 

4. DELETE 刪除一個值 

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/message -X DELETE | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   177  100   177    0     0  73261      0 --:--:-- --:--:-- --:--:--  172k
 5 {
 6     "action": "delete",
 7     "node": {
 8         "createdIndex": 19,
 9         "key": "/message",
10         "modifiedIndex": 29
11     },
12     "prevNode": {
13         "createdIndex": 19,
14         "key": "/message",
15         "modifiedIndex": 28,
16         "value": "test createIndex"
17     }
18 }

 

5. PUT 對一個鍵進行定時刪除:etcd中對鍵進行定時刪除,設定一個ttl值,當這個值到期時鍵就會被刪除。反饋的內容會給出expiration項告知超時時間,ttl項告知設定的時長。

    在設定一個key時,設定其ttl(time to live), ttl時間后,自動刪除。

  -d ttl=xxx

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/foo  -XPUT -d value=bar -d ttl=5 | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   159  100   144  100    15  60453   6297 --:--:-- --:--:-- --:--:-- 72000
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 34,
 9         "expiration": "2016-04-23T12:01:57.992249507Z",
10         "key": "/foo",
11         "modifiedIndex": 34,
12         "ttl": 5,
13         "value": "bar"
14     }
15 }

   在repsonse中有兩個新的字段:

  expiration:key的有效截至日期。  

  ttl:         key的ttl值,單位秒。

     注意|:

    key只有被cluster header設定過期,如果一個memeber 脫離的集群,它里面的key將沒有過期,直到重新加入后才有過期功能。

 

6. PUT 取消定時刪除任務

  -d ttl=

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -d ttl= -d prevExist=true | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   254  100   225  100    29  98944  12752 --:--:-- --:--:-- --:--:--  219k
 5 {
 6     "action": "update",
 7     "node": {
 8         "createdIndex": 38,
 9         "key": "/foo",
10         "modifiedIndex": 39,
11         "value": "bar"
12     },
13     "prevNode": {
14         "createdIndex": 38,
15         "expiration": "2016-04-23T12:07:05.415596297Z",
16         "key": "/foo",
17         "modifiedIndex": 38,
18         "ttl": 78,
19         "value": "bar"
20     }
21 }

 

7. PUT 刷新key的 ttl 

  ttl 到刪除key和重新設置ttl,都會觸發watcher。通過在請求的body中增加 refresh=true,更新ttl(必須存在),不引起觸發watcher事件。

  -d refresh=true

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/message -XPUT -d ttl=100 -d refresh=true | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   304  100   284  100    20  46973   3307 --:--:-- --:--:-- --:--:-- 56800
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 145,
 9         "expiration": "2016-12-28T06:58:20.426383304Z",
10         "key": "/message",
11         "modifiedIndex": 145,
12         "ttl": 100,
13         "value": ""
14     },
15     "prevNode": {
16         "createdIndex": 144,
17         "expiration": "2016-12-28T06:57:55.628682326Z",
18         "key": "/message",
19         "modifiedIndex": 144,
20         "ttl": 76,
21         "value": ""
22     }
23 }

 

 

8. GET 對鍵值修改進行監控:etcd提供的這個API通過long polling(輪詢)讓用戶可以監控一個值或者遞歸式(recursive=true 在url path中作為參數)地監控一個目錄及其子目錄的值,當目錄或值發生變化時,etcd會主動通知。

  ?wait=true        監聽當前節點

      ?recursive=true    遞歸監聽當前節點和子目錄

      ?waitIndex=xxx   監聽過去已經發生的。過去值的查詢或監聽, 必選與wait一起使用。

 1 [root@vStack ~]# curl 'http://127.0.0.1:2379/v2/keys/message?wait=true&waitIndex=2230'  | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   183    0   183    0     0   131k      0 --:--:-- --:--:-- --:--:--  178k
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 2230,
 9         "key": "/message",
10         "modifiedIndex": 2230,
11         "value": "123"
12     },
13     "prevNode": {
14         "createdIndex": 2229,
15         "key": "/message",
16         "modifiedIndex": 2229,
17         "value": "123"
18     }
19 }

 

  watch 一個ttl自刪除的key時,收到如下 “expire” action。

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/message?wait=true | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   215    0   215    0     0     19      0 --:--:--  0:00:10 --:--:--    45
 5 {
 6     "action": "expire",
 7     "node": {
 8         "createdIndex": 2223,
 9         "key": "/message",
10         "modifiedIndex": 2224
11     },
12     "prevNode": {
13         "createdIndex": 2223,
14         "expiration": "2016-12-28T09:25:00.028597482Z",
15         "key": "/message",
16         "modifiedIndex": 2223,
17         "value": ""
18     }
19 }

 

 

9. GET 對過去的鍵值操作進行查詢:類似上面提到的監控,在其基礎上指定過去某次修改的索引編號,就可以查詢歷史操作。默認可查詢的歷史記錄為1000條。

  ? waitIndex=xxx   監聽過去已經發生的。 這個在確保在watch命令中,沒有丟失事件非常有用。例如:我們反復watch 我們得到節點的 modifiedIndex+1。

  因為 node 的modifiedIndex的值是不連續,如果waitIndex的值沒有相應modifiedIndex,返回最大的modifedIndex的節點信息 如果大於節點中所有的modifiedIndex,等待,直到節點的modifiedIndex值大於等於waitIndex的值。

  即使刪除key后,也可以查詢歷史數據。

  store中有一個全局的currentIndex,每次變更,index會加1.然后每個event都會關聯到currentIndex.

  當客戶端調用watch接口(參數中增加 wait參數)時,如果請求參數中有waitIndex,並且waitIndex 小於 currentIndex,則從 EventHistroy 表中查詢index小於等於waitIndex,並且和watch key 匹配的 event,如果有數據,則直接返回。如果歷史表中沒有或者請求沒有帶   waitIndex,則放入WatchHub中,每個key會關聯一個watcher列表。 當有變更操作時,變更生成的event會放入EventHistroy表中,同時通知和該key相關的watcher。

  注意:

    1. 必須與 wait 一起使用;

           2. curl 中url需要使用引號。

           3. etcd 僅僅保留系統中所有key最近的1000條event,建議將獲取到的response發送到另一個線程處理,而不是處理response而阻塞watch。

           4. 如果watch超出了etcd保存的最近1000條,建議get后使用response header中的 X-Etcd-Index + 1進行重新watch,而不是使用node中的modifiedIndex+1. 因為  X-Etcd-Index  永遠大於等於modifiedIndex, 使用modifiedIndex可能會返回401錯誤碼,同樣超出。

           5. long polling可能會被服務器關閉,如超時或服務器關閉。導致僅僅收到header 200OK,body為空,此時應重新watch。

 1 [root@vStack ~]# curl 'http://127.0.0.1:2379/v2/keys/foo?wait=true&waitIndex=2' | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   144    0   144    0     0   102k      0 --:--:-- --:--:-- --:--:--  140k
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 34,
 9         "expiration": "2016-04-23T12:01:57.992249507Z",
10         "key": "/foo",
11         "modifiedIndex": 34,
12         "ttl": 5,
13         "value": "bar"
14     }
15 }

 如果超出了etcd保留的最近1000條,返回 401錯誤碼

 1 [root@vStack ~]# curl 'http://127.0.0.1:2379/v2/keys/message?wait=true&waitIndex=8' | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   154  100   154    0     0  56163      0 --:--:-- --:--:-- --:--:--  150k
 5 {
 6     "cause": "the requested history has been cleared [1186/8]",
 7     "errorCode": 401,
 8     "index": 2185,
 9     "message": "The event in requested index is outdated and cleared"
10 }

 

  

10. PUT 創建目錄

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/dir -XPUT -d dir=true | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100    95  100    87  100     8  21260   1955 --:--:-- --:--:-- --:--:-- 29000
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 63,
 9         "dir": true,
10         "key": "/dir",
11         "modifiedIndex": 63
12     }
13 }

 

11. GET 列出目錄下所有的節點信息,最后以/結尾(不是必須的)。還可以通過recursive參數遞歸列出所有子目錄信息。 沒有recursive,返回第二級。后面不在返回。

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/dir1/ | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   167  100   167    0     0  65234      0 --:--:-- --:--:-- --:--:-- 83500
 5 {
 6     "action": "get",
 7     "node": {
 8         "createdIndex": 67,
 9         "dir": true,
10         "key": "/dir1",
11         "modifiedIndex": 67,
12         "nodes": [
13             {
14                 "createdIndex": 67,
15                 "dir": true,
16                 "key": "/dir1/dir2",
17                 "modifiedIndex": 67
18             }
19         ]
20     }
21 }

 

12. POST 自動在目錄下創建有序鍵。在對創建的目錄使用POST參數,會自動在該目錄下創建一個以global etcd index值為鍵的值,這樣就相當於根據創建時間的先后進行了嚴格排序。該API對分布式隊列這類場景非常有用

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/queue  -XPOST -d value=Job1 | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   127  100   117  100    10  31655   2705 --:--:-- --:--:-- --:--:-- 39000
 5 {
 6     "action": "create",
 7     "node": {
 8         "createdIndex": 47,
 9         "key": "/queue/00000000000000000047",
10         "modifiedIndex": 47,
11         "value": "Job1"
12     }
13 }

 

13. GET 按順序列出所有創建的有序鍵

  ? sorted=true

  ? recursive=true

 1 [root@vStack ~]# curl -s 'http://127.0.0.1:2379/v2/keys/queue?sorted=true' | python -m json.tool
 2 {
 3     "action": "get",
 4     "node": {
 5         "createdIndex": 46,
 6         "dir": true,
 7         "key": "/queue",
 8         "modifiedIndex": 46,
 9         "nodes": [
10             {
11                 "createdIndex": 46,
12                 "key": "/queue/00000000000000000046",
13                 "modifiedIndex": 46,
14                 "value": ""
15             },
16             {
17                 "createdIndex": 47,
18                 "key": "/queue/00000000000000000047",
19                 "modifiedIndex": 47,
20                 "value": "Job1"
21             },
22             {
23                 "createdIndex": 48,
24                 "key": "/queue/00000000000000000048",
25                 "modifiedIndex": 48,
26                 "value": "aaaa"
27             },
28             {
29                 "createdIndex": 49,
30                 "key": "/queue/00000000000000000049",
31                 "modifiedIndex": 49,
32                 "value": "aaaa"
33             },
34             {
35                 "createdIndex": 50,
36                 "key": "/queue/00000000000000000050",
37                 "modifiedIndex": 50,
38                 "value": "aaaa"
39             },
40             {
41                 "createdIndex": 51,
42                 "key": "/queue/00000000000000000051",
43                 "modifiedIndex": 51,
44                 "value": "aaaa"
45             }
46         ]
47     }
48 }

 

14. DELETE 刪除目錄:默認情況下只允許刪除空目錄,如果要刪除有內容的目錄需要加上recursive=true參數。

  ?dir=true        刪除目錄 

  ?recursive=true      刪除非空目錄

      刪除非空目錄必須使用 recursive=true 參數,刪除空目錄,dir=truerecursive=true至少有一個。

 1 [root@vStack ~]# curl 'http://127.0.0.1:2379/v2/keys/dir1?dir=true' -XDELETE | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100    77  100    77    0     0  38557      0 --:--:-- --:--:-- --:--:-- 77000
 5 {
 6     "cause": "/dir1",
 7     "errorCode": 108,
 8     "index": 67,
 9     "message": "Directory not empty"
10 }
11 [root@vStack ~]# curl 'http://127.0.0.1:2379/v2/keys/dir1?dir=true&recursive=true' -XDELETE | python -m json.tool
12   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
13                                  Dload  Upload   Total   Spent    Left  Speed
14 100   166  100   166    0     0  62032      0 --:--:-- --:--:-- --:--:-- 83000
15 {
16     "action": "delete",
17     "node": {
18         "createdIndex": 67,
19         "dir": true,
20         "key": "/dir1",
21         "modifiedIndex": 68
22     },
23     "prevNode": {
24         "createdIndex": 67,
25         "dir": true,
26         "key": "/dir1",
27         "modifiedIndex": 67
28     }
29 }

 

15. PUT 創建定時刪除的目錄:就跟定時刪除某個鍵類似。如果目錄因為超時被刪除了,其下的所有內容也自動超時刪除。

      如果目錄存在,創建時,返回 102 錯誤碼

      -d ttl=xx

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/dir  -XPUT -d ttl=30 -d dir=true | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   157  100   142  100    15  22873   2416 --:--:-- --:--:-- --:--:-- 28400
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 52,
 9         "dir": true,
10         "expiration": "2016-04-23T13:37:51.502289114Z",
11         "key": "/dir",
12         "modifiedIndex": 52,
13         "ttl": 30
14     }
15 }

 

16. PUT 設置刷新目錄超時時間   開始創建時,沒有設置ttl, 或刷新已設置ttl的目錄的ttl的值。

  -d ttl=xxx      設置或刷新的ttl值。 ttl為空是,取消ttl。

  -d prevExist=true    必選參數,否者報錯102錯誤碼

  會觸發watcher事件。

 1 [root@vStack ~]# curl http://127.0.0.1:2379/v2/keys/dir -XPUT -d ttl=30 -d dir=true -d prevExist=true | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   304  100   274  100    30  60392   6612 --:--:-- --:--:-- --:--:-- 91333
 5 {
 6     "action": "update",
 7     "node": {
 8         "createdIndex": 56,
 9         "dir": true,
10         "expiration": "2016-04-23T13:42:56.395923381Z",
11         "key": "/dir",
12         "modifiedIndex": 61,
13         "ttl": 30
14     },
15     "prevNode": {
16         "createdIndex": 56,
17         "dir": true,
18         "expiration": "2016-04-23T13:42:46.225222674Z",
19         "key": "/dir",
20         "modifiedIndex": 56,
21         "ttl": 20
22     }
23 }

  當ttl時間到后,watcher將收到一個"expire" action.   

 1 [root@vStack ~]# curl  http://127.0.0.1:2379/v2/keys/dir?wait=true | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   207    0   207    0     0     16      0 --:--:--  0:00:12 --:--:--    43
 5 {
 6     "action": "expire",
 7     "node": {
 8         "createdIndex": 2219,
 9         "key": "/dir",
10         "modifiedIndex": 2220
11     },
12     "prevNode": {
13         "createdIndex": 2219,
14         "dir": true,
15         "expiration": "2016-12-28T09:22:35.853484071Z",
16         "key": "/dir",
17         "modifiedIndex": 2219
18     }
19 }

  

17. 創建一個隱藏節點:命名時名字以下划線_開頭的key或目錄,默認就是隱藏鍵。

      list目錄下時,將不顯示。可以顯示使用。

 1 [root@vStack ~]#  curl http://127.0.0.1:2379/v2/keys/_message  -XPUT -d value="Hello hidden world" | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   134  100   110  100    24  46948  10243 --:--:-- --:--:-- --:--:--  107k
 5 {
 6     "action": "set",
 7     "node": {
 8         "createdIndex": 69,
 9         "key": "/_message",
10         "modifiedIndex": 69,
11         "value": "Hello hidden world"
12     }
13 }

  

注意:

      1. api url 區分大小寫,包括其中的參數。 

  2. 如果key存在,通過 curl http://IP:PORT/v2/keys/message001 -XPUT -d dir=true , 將會把key調整為dir屬性,value值為None; 增加 -d prevExist=false,將報105錯誤碼。 修改為dir后,無法在恢復為key。

     3. 不能對一個dir進行賦值,即 curl http://127.0.0.1:2379/v2/keys/message001 -XPUT -d value=123    , 返回錯誤碼 102, “Not a file”

     4. key相當於文件系統中的文件,可以賦值即向文件寫內容。dir相當於文件系統的目錄或路徑,內容包括dir和key, 即文件系統中的目錄和文件。

     5. 在api url中的path,體現了存儲結構。如果目錄不存在,直接創建。如:curl http://127.0.0.1:2379/v2/keys/fst/sec/thr -XPUT -d value=123  中的fst、sec會自動創建為dir。 

     6. 創建dir與key的區別,即在 curl的body中是否有 dir=true,有即為dir, 否認則key; dir存在時,value無效。 創建key時,value可以不存在。

     7. 不能在key下創建dir或可以,否者報錯誤碼:104,“Not a directory”

     8. 目錄不能重復創建,即 curl -v http://127.0.0.1:2379/v2/keys/message -XPUT -d dir=true  如果 message 目錄已經已經存在,返回錯誤碼:102, “Not a file”

     9. 刪除一個非空目錄,返回錯誤碼:102. 通過在url中增加 recursive=true 參數,可以參數非空目錄。

 

Statistics  統計接口

  etcd 集群記錄大量的統計數據,包括:延時(latency),帶寬和正常運行時間。統計功能通過統計端點(/stats)去理解一個集群的內部健康狀態。

  An etcd cluster keeps track of a number of statistics including latency, bandwidth and uptime. These are exposed via the statistics endpoint to understand the internal health of a cluster.

Leader Statistics 領導點統計

 

 1 [root@localhost testectd]# curl http://127.0.0.1:2379/v2/stats/self | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 119   357  119   357    0     0   274k      0 --:--:-- --:--:-- --:--:--  348k
 5 {
 6     "id": "45b967575ff25cb2", 
 7     "leaderInfo": {
 8         "leader": "45b967575ff25cb2", 
 9         "startTime": "2016-12-29T20:15:13.811259537+08:00", 
10         "uptime": "8m19.603722077s"
11     }, 
12     "name": "infra0", 
13     "recvAppendRequestCnt": 18, 
14     "sendAppendRequestCnt": 3670, 
15     "sendBandwidthRate": 123950.52498801574, 
16     "sendPkgRate": 7.5456304767920797, 
17     "startTime": "2016-12-29T20:14:29.300999352+08:00", 
18     "state": "StateLeader"
19 }

 

 

 1 [root@localhost testectd]# curl http://127.0.0.1:2379/v2/stats/leader | python -m json.tool 
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 132   398  132   398    0     0   133k      0 --:--:-- --:--:-- --:--:--  388k
 5 {
 6     "followers": {
 7         "3c828782a67e0043": {
 8             "counts": {
 9                 "fail": 1211, 
10                 "success": 0
11             }, 
12             "latency": {
13                 "average": 0, 
14                 "current": 0, 
15                 "maximum": 0, 
16                 "minimum": 9.2233720368547758e+18, 
17                 "standardDeviation": 0
18             }
19         }, 
20         "b26f1b9a6c735437": {
21             "counts": {
22                 "fail": 0, 
23                 "success": 3231
24             }, 
25             "latency": {
26                 "average": 0.0073246419065304607, 
27                 "current": 0.0032520000000000001, 
28                 "maximum": 1.713633, 
29                 "minimum": 0.0012520000000000001, 
30                 "standardDeviation": 0.035654606550540036
31             }
32         }
33     }, 
34     "leader": "45b967575ff25cb2"
35 }

 

Memeber API

1. List members

  返回http 200 OK response,顯示在 etcd 集群中的所有成員。

 1 [root@vStack ~]# curl http://192.168.10.150:2379/v2/members | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   138  100   138    0     0  73287      0 --:--:-- --:--:-- --:--:--  134k
 5 {
 6     "members": [
 7         {
 8             "clientURLs": [
 9                 "http://192.168.10.150:2379"
10             ],
11             "id": "8e9e05c52164694d",
12             "name": "default",
13             "peerURLs": [
14                 "http://localhost:2380"
15             ]
16         }
17     ]
18 }

 

[root@vStack ~]# curl http://127.0.0.1:2379/v2/members | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   181  100   181    0     0   138k      0 --:--:-- --:--:-- --:--:--  176k
{
    "members": [
        {
            "clientURLs": [
                "http://localhost:2379",
                "http://localhost:4001"
            ],
            "id": "ce2a822cea30bfca",
            "name": "default",
            "peerURLs": [
                "http://localhost:2380",
                "http://localhost:7001"
            ]
        }
    ]
}

 

 1 [root@vStack ~]# curl http://192.168.10.150:2379/v2/members | python -m json.tool
 2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 3                                  Dload  Upload   Total   Spent    Left  Speed
 4 100   227  100   227    0     0   116k      0 --:--:-- --:--:-- --:--:--  221k
 5 {
 6     "members": [
 7         {
 8             "clientURLs": [],
 9             "id": "755ef544f1926e2e",
10             "name": "",
11             "peerURLs": [
12                 "http://127.0.0.1:2380"
13             ]
14         },
15         {
16             "clientURLs": [
17                 "http://192.168.10.150:2379"
18             ],
19             "id": "8e9e05c52164694d",
20             "name": "default",
21             "peerURLs": [
22                 "http://localhost:2380"
23             ]
24         }
25     ]
26 }

 

2. Add a member

  成功時返回 HTTP 201 response 狀態碼,及新建入成員的信息,對新加入的成員生成一個成員id。 失敗時,返回失敗狀態的字符描述。

  

 Returns an HTTP 201 response code and the representation of added member with a newly generated a memberID when successful. Returns a string describing the failure condition when unsuccessful.

If the POST body is malformed an HTTP 400 will be returned. If the member exists in the cluster or existed in the cluster at some point in the past an HTTP 409 will be returned. If any of the given peerURLs exists in the cluster an HTTP 409 will be returned. If the cluster fails to process the request within timeout an HTTP 500 will be returned, though the request may be processed later.

 

1 curl http://10.0.0.10:2379/v2/members -XPOST \
2 -H "Content-Type: application/json" -d '{"peerURLs":["http://10.0.0.10:2380"]}'

 

  1.  需要在header中設置 Content-Type: application/json, 否則會報 405 錯誤 Unsupported Media Type

  2.  如果已經存在相同的peerURLs,直接返回當前存在相同peerURLs的member。

      3. 如果添加一個無法使用的peerURLs,導致服務掛掉,無法操作。重啟也無法使用。解決方法刪除物理文件,但這個會刪除記錄的數據,導致持久數據的就丟失。需要進一步尋求解決方法。

    集群信息會記錄到持久化信息文件中,重啟問題依舊。除非使用不同的name或改變數據目錄。

  

 

3. Delete a member

  從集群中刪除一個memeber。 member ID 必須是一個64位整數的16位編碼的字符串。成功時,返回 204 狀態碼和沒有內容。失敗時,返回404狀態碼和字符描述的失敗情況。

  從集群中刪除一個不存在的member,返回500錯誤。集群處理失敗請求,包括超時,返回一個500錯誤碼。即使請求可能后面會處理。

1 [root@localhost testectd]# curl http://192.168.10.150:2379/v2/members/2ae1ee131894262b -XDELETE | python -m json.tool
2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
3                                  Dload  Upload   Total   Spent    Left  Speed
4   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
5 No JSON object could be decoded

 

  1. 刪除成員后,etcd使用的data-dir必須被刪除。如下是刪除最后一個member,etcd給出的輸出,服務退出。

    2016-12-29 16:10:59.544409 E | etcdserver: the member has been permanently removed from the cluster

    2016-12-29 16:10:59.544480 I | etcdserver: the data-dir used by this member must be removed.

  2. 通過etcdctl 刪除一個成員后,服務會退出。通過 etcdctl重新加入,顯示為unstart。 

   如果需要重新加入集群,先用命令加入,再啟動,否則啟動時報 the member has been permanently removed from the cluster

   加入后,啟動前,需要刪除其存儲的數據(member id發生了改變,會將使用磁盤記錄的id,與新加入的ID不一致)。並設置 --initial-cluster-state existing 不能設置為 new

   注意 cluster版本要一致。cluster{"etcdserver":"3.0.15","etcdcluster":"3.0.0"} 可以。

                   {"etcdserver":"2.3.7","etcdcluster":"2.3.0"}

               出現: {"etcdserver":"3.0.15","etcdcluster":"2.3.0"}  在集群系統中出現不同版本的member

   以上刪除重新加入的操作,高版本的可以,單低版本的不支持,報  failed to find member 3c828782a67e0043 in cluster 34b660d543ad1445 無法發現其他member

 

   

   

        即 在集群中,成員的版本不同。低版本的成員失敗退出,重啟啟動可以重新加入集群。通過接口,被動從集群中移除,再次加入,只能停止所有的成員,刪除其中磁盤數據,重新構建。導致數據的丟失,如何恢復? 高版本的成員沒有此問題。

    即 在集群中,成員的版本不同。集群版本降低為 低版本 如:{"etcdserver":"3.0.15","etcdcluster":"2.3.0"}, 低版本的成員退出后,集群版本升級為高版本:{"etcdserver":"3.0.15","etcdcluster":"3.0.0"}                

 

        其版本的首先啟動時,使用--initial-cluster-state new;  高版本的在啟動時 --initial-cluster-state existing 會報 集群版本不兼容。需要使用 --initial-cluster-state new。 再次啟動高版本的可以使用 existing 。

    構建集群時,采用就低版本,在高版本加入時,需要使用 --initial-cluster-state new 或 不設置, 使用existing ,報集群不兼容。

 

 

 1 [root@centos7mini etcd]# ./etcdctl member remove 45b967575ff25cb2
 2 Removed member 45b967575ff25cb2 from cluster
 3 
 4 [root@centos7mini etcd]# ./etcdctl member add infra0 http://192.168.10.150:2380
 5 Added member named infra0 with ID 700fb7bf97791e71 to cluster
 6 
 7 ETCD_NAME="infra0"
 8 ETCD_INITIAL_CLUSTER="infra3=http://192.168.10.184:2380,infra0=http://192.168.10.150:2380,infra1=http://192.168.10.231:2380"
 9 ETCD_INITIAL_CLUSTER_STATE="existing"
10 
11 [root@centos7mini etcd]# ./etcdctl member list
12 3c828782a67e0043: name=infra3 peerURLs=http://192.168.10.184:2380 clientURLs=http://192.168.10.184:2379 isLeader=true
13 700fb7bf97791e71[unstarted]: peerURLs=http://192.168.10.150:2380
14 b26f1b9a6c735437: name=infra1 peerURLs=http://192.168.10.231:2380 clientURLs=http://192.168.10.231:2379 isLeader=false
15 [root@centos7mini etcd]# 

 

4. Change the peer urls of a member

  修改已存在成員的peer urls。成員ID必須是一個64位整數的16進制顯示的字符串。成功時,返回204狀態碼,空內容。失敗時,返回失敗狀態字符描述。

  修改的成員不存在,返回400 錯誤碼。 如果提供的peerlURL存在,將返回409錯誤碼。500錯誤: 集群處理超時。

  

 1 [root@localhost etcd-v3.0.15-linux-amd64]# ./etcdctl member list
 2 3c828782a67e0043: name=infra3 peerURLs=http://192.168.10.184:2380 clientURLs=http://192.168.10.184:2379 isLeader=false
 3 45b967575ff25cb2: name=infra0 peerURLs=http://192.168.10.150:2380 clientURLs=http://192.168.10.150:2379 isLeader=true
 4 b26f1b9a6c735437: name=infra1 peerURLs=http://192.168.10.231:2380 clientURLs=http://192.168.10.231:2379 isLeader=false
 5 [root@localhost etcd-v3.0.15-linux-amd64]# 
 6 [root@localhost etcd-v3.0.15-linux-amd64]# curl http://192.168.10.150:2379/v2/members/b26f1b9a6c735437 -XPUT -H "Content-Type: application/json" -d '{"peerURLs":["http://127.0.0.1:2380"]}'
 7 [root@localhost etcd-v3.0.15-linux-amd64]# 
 8 [root@localhost etcd-v3.0.15-linux-amd64]# ./etcdctl member list
 9 3c828782a67e0043: name=infra3 peerURLs=http://192.168.10.184:2380 clientURLs=http://192.168.10.184:2379 isLeader=false
10 45b967575ff25cb2: name=infra0 peerURLs=http://192.168.10.150:2380 clientURLs=http://192.168.10.150:2379 isLeader=true
11 b26f1b9a6c735437: name=infra1 peerURLs=http://127.0.0.1:2380 clientURLs=http://192.168.10.231:2379 isLeader=false
12 [root@localhost etcd-v3.0.15-linux-amd64]# 

 

 

 

  在啟動etcd設置 --listen-client-urls 值時,請將localhost:2379或127.0.0.1:2379 設置,否者 本地etcdctl會報錯如下

1 [root@centos7mini etcd]# ./etcdctl member list
2 Error: client: etcd cluster is unavailable or misconfigured
3 error #0: dial tcp 127.0.0.1:4001: getsockopt: connection refused
4 error #1: dial tcp 127.0.0.1:2379: getsockopt: connection refused

 

 

一個節點斷開后,成為candicate,向其他member發起vote,重新選准 master/leader。

2016-12-29 19:43:15.767905 I | raft: b26f1b9a6c735437 became candidate at term 146
2016-12-29 19:43:15.767932 I | raft: b26f1b9a6c735437 received vote from b26f1b9a6c735437 at term 146
2016-12-29 19:43:15.767961 I | raft: b26f1b9a6c735437 [logterm: 101, index: 688] sent vote request to 45b967575ff25cb2 at term 146
2016-12-29 19:43:17.266905 I | raft: b26f1b9a6c735437 is starting a new election at term 146

 

將一個memeber加入兩個集群時,出現 cluster id 匹配問題。以下是靜態創建cluster。

 1 # etcd --name infra1 --initial-advertise-peer-urls http://192.168.10.231:2380 \
 2   --listen-peer-urls http://192.168.10.231:2380 \
 3   --listen-client-urls http://192.168.10.231:2379,http://127.0.0.1:2379 \
 4   --advertise-client-urls http://192.168.10.231:2379 \
 5   --initial-cluster-token etcd-cluster-1 \
 6   --initial-cluster infra0=http://192.168.10.150:2380,infra1=http://192.168.10.231:2380,infra3=http://192.168.10.184:2380 \
 7   --initial-cluster-state new
 8 
 9 # ./etcd --debug --name infra3 --initial-advertise-peer-urls http://192.168.10.184:2380  \
10   --listen-peer-urls http://192.168.10.184:2380 --initial-cluster infra3=http://192.168.10.184:2380 \
11   --listen-client-urls http://192.168.10.184:2379 --advertise-client-urls http://192.168.10.184:2379 \
12   --initial-cluster-state new --initial-cluster-token etcd-cluster-1

 

 2016-12-30 11:47:30.939730 E | rafthttp: request sent was ignored (cluster ID mismatch: remote[3c828782a67e0043]=625ac7f9082c643, local=34b660d543ad1445)

2016-12-30 11:47:30.977766 E | rafthttp: request sent was ignored (cluster ID mismatch: remote[3c828782a67e0043]=625ac7f9082c643, local=34b660d543ad1445)

 

 

如下建立集群后,--debug 提示:150上的iptables防火牆導致。

2016-12-30 12:07:19.479241 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 12:07:19.914614 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:20.781345 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:21.216792 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:21.885187 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 12:07:22.518689 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:22.620358 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 12:07:23.187832 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:23.925031 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:24.490547 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:24.592188 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 12:07:25.226673 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:25.696521 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 12:07:26.528616 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:26.630548 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 12:07:27.000087 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:27.932728 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:28.302774 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 12:07:28.404591 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: getsockopt: no r

如下調試信息是在leader 上的。 由於iptables防火牆的原因導致。

2016-12-30 14:03:10.838829 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 14:03:11.353601 W | etcdserver: failed to reach the peerURL(http://192.168.10.150:2380) of member 45b967575ff25cb2 (Get http://192.168.10.150:2380/version: dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 14:03:11.353640 W | etcdserver: cannot get the version of member 45b967575ff25cb2 (Get http://192.168.10.150:2380/version: dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 14:03:11.672262 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 14:03:12.140697 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 14:03:12.974912 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 14:03:13.445167 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 14:03:13.547340 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 14:03:14.278497 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 14:03:14.380259 D | rafthttp: failed to dial 45b967575ff25cb2 on stream MsgApp v2 (dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 14:03:14.850132 D | rafthttp: failed to dial 45b967575ff25cb2 on stream Message (dial tcp 192.168.10.150:2380: i/o timeout)
2016-12-30 14:03:15.358565 W | etcdserver: failed to reach the peerURL(http://192.168.10.150:2380) of member 45b967575ff25cb2 (Get http://192.168.10.150:2380/version: dial tcp 192.168.10.150:2380: getsockopt: no route to host)
2016-12-30 14:03:15.358613 W | etcdserver: cannot get the version of member 45b967575ff25cb2 (Get http://192.168.10.150:2380/version: dial tcp 192.168.10.150:2380: getsockopt: no route to host)

如下調試信息,是由於 192.168.10.231:2380 無法訪問, b26f1b9a6c735437 為member id。

2016-12-30 21:38:43.130791 D | rafthttp: failed to dial b26f1b9a6c735437 on stream Message (dial tcp 192.168.10.231:2380: getsockopt: connection refused)
2016-12-30 21:38:43.191227 D | rafthttp: failed to dial b26f1b9a6c735437 on stream MsgApp v2 (dial tcp 192.168.10.231:2380: getsockopt: connection refused)
2016-12-30 21:38:43.232280 D | rafthttp: failed to dial b26f1b9a6c735437 on stream Message (dial tcp 192.168.10.231:2380: getsockopt: connection refused)
2016-12-30 21:38:43.292289 D | rafthttp: failed to dial b26f1b9a6c735437 on stream MsgApp v2 (dial tcp 192.168.10.231:2380: getsockopt: connection refused)
2016-12-30 21:38:43.334129 D | rafthttp: failed to dial b26f1b9a6c735437 on stream Message (dial tcp 192.168.10.231:2380: getsockopt: connection refused)
2016-12-30 21:38:43.393576 D | rafthttp: failed to dial b26f1b9a6c735437 on stream MsgApp v2 (dial tcp 192.168.10.231:2380: getsockopt: connection refused)

 

2016-12-30 14:18:36.328628 W | rafthttp: the clock difference against peer 3c828782a67e0043 is too high [2.00405135s > 1s]
2016-12-30 14:19:06.329559 W | rafthttp: the clock difference against peer 3c828782a67e0043 is too high [2.003973758s > 1s]
2016-12-30 14:19:36.331189 W | rafthttp: the clock difference against peer 3c828782a67e0043 is too high [2.004098356s > 1s]

 

2016-12-30 21:38:22.857546 W | rafthttp: the clock difference against peer 3c828782a67e0043 is too high [7h59m58.924003117s > 1s]

2016-12-30 21:38:22.892541 W | rafthttp: health check for peer b26f1b9a6c735437 failed
2016-12-30 21:38:22.892848 W | rafthttp: the clock difference against peer b26f1b9a6c735437 is too high [7h59m56.920465483s > 1s]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM