<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://www.infoq.com/cn/articles/coreos-analyse-etcd/


    【編者按】CoreOS是一個基于Docker的輕量級容器化Linux發行版,專為大型數據中心而設計,旨在通過輕量的系統架構和靈活的應用程序部署能力簡化數據中心的維護成本和復雜度。CoreOS作為Docker生態圈中的重要一員,日益得到各大云服務商的重視,目前已經完成了A輪融資,發展風頭正勁。InfoQ希望《CoreOS實戰》系列文章能夠幫助讀者了解CoreOS以及相關的使用方法。如果說Docker是下一代的虛擬機,那CoreOS就應該是下一代的服務器Linux,InfoQ愿和您一起探索這個新生事物。另外,歡迎加入InfoQ Docker技術交流群,QQ群號:272489193。

    1. 概述

    etcd 是一個應用在分布式環境下的 key/value 存儲服務。利用 etcd 的特性,應用程序可以在集群中共享信息、配置或作服務發現,etcd 會在集群的各個節點中復制這些數據并保證這些數據始終正確。etcd 無論是在 CoreOS 還是 Kubernetes 體系中都是不可或缺的一環。筆者由于項目的原因對 etcd 進行了一些了解,也已經使用了一段時間。同時在與同行的交流中常被問到 etcd 是什么、與 ZooKeeper 有什么不同。那么借著 etcd 0.5.0 即將發布的機會,向感興趣的讀者介紹一下 etcd,希望可以幫助讀者了解 etcd 的工作原理以及具體實現,同時也作為 CoreOS 實戰的第二部分內容為后面相關的部分進行鋪墊。

    隨著 etcd 0.5.0 alpha (本文完稿時為 etcd 0.5.0 alpha.3)版發布,etcd 將在未來幾周內迎來一次重要的更新。在 0.5.0 版里除了修復現有穩定版中的一系列 Bug 之外,一些新的特性和變更也將隨之發布。這些變化將提升 etcd 服務安全性、可靠性和可維護性。

    新的特性包括

    • 規范詞匯表;
    • 新的 raft 算法實現;
    • 新增 etcd node 身份標記;
    • WAL (Write-ahead logging) 增加 CRC 校驗;
    • API 中新增 member {list, add, remove} 接口,原來的 list machines 接口將被移除,未來 etcd 集群中將不存在 machine 的稱呼;
    • 兩個主要端口變更為 2379 (for client) 與 2380 (for peer/raft) 并成為 IANA 的注冊端口。

    重要的變更包括

    • 運行時重構 (runtime reconfiguration)。用戶不需要重啟 etcd 服務即可實現對 etcd 集群結構進行變更。
    • 摒棄通過配置文件配置 etcd 屬性的方式,轉而以 CLI (command-line interface) flags 或環境變量的方式實現 etcd 節點的配置。
    • 每個節點可監聽多個廣播地址。監聽的地址由原來的一個擴展到多個,用戶可以根據需求實現更加復雜的集群環境,如搭建一個混合了私有云與公有云服務的 etcd 集群。
    • 新增 proxy mode。

    2. 規范詞匯表

    etcd 0.5.0 版首次對 etcd 代碼、文檔及 CLI 中使用的術語進行了定義。

    2.1. node

    node 指一個 raft 狀態機實例。每個 node 都具有唯一的標識,并在處于 leader 狀態時記錄其它節點的步進數。

    2.2. member

    member 指一個 etcd 實例。member 運行在每個 node 上,并向這一 node 上的其它應用程序提供服務。

    2.3. Cluster

    Cluster 由多個 member 組成。每個 member 中的 node 遵循 raft 共識協議來復制日志。Cluster 接收來自 member 的提案消息,將其提交并存儲于本地磁盤。

    2.4. Peer

    同一 Cluster 中的其它 member。

    2.5. Client

    Client 指調用 Cluster API 的對象。

    3. Raft 共識算法

    etcd 集群的工作原理基于 raft 共識算法 (The Raft Consensus Algorithm)。etcd 在 0.5.0 版本中重新實現了 raft 算法,而非像之前那樣依賴于第三方庫 go-raft 。raft 共識算法的優點在于可以在高效的解決分布式系統中各個節點日志內容一致性問題的同時,也使得集群具備一定的容錯能力。即使集群中出現部分節點故障、網絡故障等問題,仍可保證其余大多數節點正確的步進。甚至當更多的節點(一般來說超過集群節點總數的一半)出現故障而導致集群不可用時,依然可以保證節點中的數據不會出現錯誤的結果。

    3.1. 集群建立與狀態機

    raft 集群中的每個節點都可以根據集群運行的情況在三種狀態間切換:follower, candidate 與 leader。leader 向 follower 同步日志,follower 只從 leader 處獲取日志。在節點初始啟動時,節點的 raft 狀態機將處于 follower 狀態并被設定一個 election timeout,如果在這一時間周期內沒有收到來自 leader 的 heartbeat,節點將發起選舉:節點在將自己的狀態切換為 candidate 之后,向集群中其它 follower 節點發送請求,詢問其是否選舉自己成為 leader。當收到來自集群中過半數節點的接受投票后,節點即成為 leader,開始接收保存 client 的數據并向其它的 follower 節點同步日志。leader 節點依靠定時向 follower 發送 heartbeat 來保持其地位。任何時候如果其它 follower 在 election timeout 期間都沒有收到來自 leader 的 heartbeat,同樣會將自己的狀態切換為 candidate 并發起選舉。每成功選舉一次,新 leader 的步進數都會比之前 leader 的步進數大1。

    圖 3-1 raft 狀態切換示意圖

    3.2. 選舉

    3.2.1. 一個 candidate 成為 leader 需要具備三個要素:

    • 獲得集群多數節點的同意;
    • 集群中不存在比自己步進數更高的 candidate;
    • 集群中不存在其他 leader。

    3.2.2. 下面為一個 etcd 集群選舉過程的簡單描述:

    ? 初始狀態下集群中的所有節點都處于 follower 狀態。

    ? 某一時刻,其中的一個 follower 由于沒有收到 leader 的 heartbeat 率先發生 election timeout 進而發起選舉。

    ? 只要集群中超過半數的節點接受投票,candidate 節點將成為即切換 leader 狀態。

    ? 成為 leader 節點之后,leader 將定時向 follower 節點同步日志并發送 heartbeat。

    3.3. 節點異常

    集群中各個節點的狀態隨時都有可能發生變化。從實際的變化上來分類的話,節點的異常大致可以分為四種類型:

    • leader 不可用;
    • follower 不可用;
    • 多個 candidate 或多個 leader;
    • 新節點加入集群。

    3.3.1. leader 不可用

    下面將說明當集群中的 leader 節點不可用時,raft 集群是如何應對的。

    ? 一般情況下,leader 節點定時發送 heartbeat 到 follower 節點。

    ? 由于某些異常導致 leader 不再發送 heartbeat ,或 follower 無法收到 heartbeat 。

    ? 當某一 follower 發生 election timeout 時,其狀態變更為 candidate,并向其他 follower 發起投票。

    ? 當超過半數的 follower 接受投票后,這一節點將成為新的 leader,leader 的步進數加1并開始向 follower 同步日志。

    ? 當一段時間之后,如果之前的 leader 再次加入集群,則兩個 leader 比較彼此的步進數,步進數低的 leader 將切換自己的狀態為 follower。

    ? 較早前 leader 中不一致的日志將被清除,并與現有 leader 中的日志保持一致。

    3.3.2. follower 節點不可用

    follower 節點不可用的情況相對容易解決。因為集群中的日志內容始終是從 leader 節點同步的,只要這一節點再次加入集群時重新從 leader 節點處復制日志即可。

    ? 集群中的某個 follower 節點發生異常,不再同步日志以及接收 heartbeat。

    ? 經過一段時間之后,原來的 follower 節點重新加入集群。

    ? 這一節點的日志將從當時的 leader 處同步。

    3.3.3. 多個 candidate 或多個 leader

    在集群中出現多個 candidate 或多個 leader 通常是由于數據傳輸不暢造成的。出現多個 leader 的情況相對少見,但多個 candidate 比較容易出現在集群節點啟動初期尚未選出 leader 的“混沌”時期。

    ? 初始狀態下集群中的所有節點都處于 follower 狀態。

    ? 兩個節點同時成為 candidate 發起選舉。

    ? 兩個 candidate 都只得到了少部分 follower 的接受投票。

    ? candidate 繼續向其他的 follower 詢問。

    ? 由于一些 follower 已經投過票了,所以均返回拒絕接受。

    ? candidate 也可能向一個 candidate 詢問投票。

    ? 在步進數相同的情況下,candidate 將拒絕接受另一個 candidate 的請求。

    ? 由于第一次未選出 leader,candidate 將隨機選擇一個等待間隔(150ms ~ 300ms)再次發起投票。

    ? 如果得到集群中半數以上的 follower 的接受,這一 candidate 將成為 leader。

    ? 稍后另一個 candidate 也將再次發起投票。

    ? 由于集群中已經選出 leader,candidate 將收到拒絕接受的投票。

    ? 在被多數節點拒絕之后,并已知集群中已存在 leader 后,這一 candidate 節點將終止投票請求、切換為 follower,從 leader 節點同步日志。

    3.4. 日志

    3.4.1. 復制

    在 raft 集群中,所有日志都必須首先提交至 leader 節點。leader 在每個 heartbeat 向 follower 同步日志,follower 在收到日志之后向 leader 反饋結果,leader 在確認日志內容正確之后將此條目提交并存儲于本地磁盤。

    ? 首先有一條 uncommitted 的日志條目提交至 leader 節點。

    ? 在下一個 heartbeat,leader 將此條目復制給所有的 follower。

    ? 當大多數節點記錄此條目之后,leader 節點認定此條目有效,將此條目設定為已提交并存儲于本地磁盤。

    ? 在下一個 heartbeat,leader 通知所有 follower 提交這一日志條目并存儲于各自的磁盤內。

    3.4.2. 容錯

    如果由于網絡的隔斷,造成集群中多數的節點在一段時間內無法訪問到 leader 節點。按照 raft 共識算法,沒有 leader 的那一組集群將會通過選舉投票出新的 leader,甚至會在兩個集群內產生不一致的日志條目。在集群重新完整連通之后,原來的 leader 仍會按照 raft 共識算法從步進數更高的 leader 同步日志并將自己切換為 follower。

    ? 集群的理想狀態。

    ? 網絡間隔造成大多數的節點無法訪問 leader 節點。

    ? 新的日志條目添加到 leader 中。

    ? leader 節點將此條日志同步至能夠訪問到 leader 的節點。

    ? follower 確認日志被記錄,但是確認記錄日志的 follower 數量沒有超過集群節點的半數,leader 節點并不將此條日志存檔。

    ? 在被隔斷的這部分節點,在 election timeout 之后,followers 中產生 candidate 并發起選舉。

    ? 多數節點接受投票之后,candidate 成為 leader。

    ? 一個日志條目被添加到新的 leader。

    ? 日志被復制給新 leader 的 follower。

    ? 多數節點確認之后,leader 將日志條目提交并存儲。

    ? 在下一個 heartbeat,leader 通知 follower 各自提交并保存在本地磁盤。

    ? 經過一段時間之后,集群重新連通到一起,集群中出現兩個 leader 并且存在不一致的日志條目。

    ? 新的 leader 在下一次 heartbeat timeout 時向所有的節點發送一次 heartbeat。

    ? #1 leader 在收到步進數更高的 #2 leader heartbeat 時放棄 leader 地位并切換到 follower 狀態。

    ? 節點中所有未存檔的日志條目都將被丟棄。

    ? 未被復制的日志條目將會被同步給所有的 follower。

    通過這種方式,只要集群中有效連接的節點超過總數的一半,集群將一直以這種規則運行下去并始終確保各個節點中的數據始終一致。

    4. 實現

    4.1. etcd 結構

    一個 etcd 節點的核心由三部分組成:

    • Raft:raft 狀態機是對 raft 共識算法的實現
    • WAL:raft 日志存儲
    • Storage:數據的存儲與索引

    WAL (Write-ahead logging),是用于向系統提供原子性和持久性的一系列技術。在使用 WAL 的系提供中,所有的修改在提交之前都要先寫入 log 文件中。etcd 的 WAL 由日志存儲與快照存儲兩部分組成,其中 Entry 負責存儲具體日志的內容,而 Snapshot 負責在日志內容發生變化的時候保存 raft 的狀態。WAL 會在本地磁盤的一個指定目錄下分別日志條目與快照內容。

    4.2. 服務

    4.2.1. Clients

    在默認設定下,etcd 通過主機的 2379 端口向 Client 提供服務。如下圖:

    每個主機上的應用程序都可以通過主機的 2379 以 HTTP + JSON 的方式向 etcd 讀寫數據。寫入的數據會由 etcd 同步到集群的其它節點中。

    4.2.2. Peers

    在默認設定下,etcd 通過主機的 2380 端口在各個節點中同步 raft 狀態及數據。

    5. 創建

    從方法上來劃分,創建 etcd 集群的方式分為兩種:Static (通過制定 peers 的 IP 和端口創建)與 Discovery (通過一個發現服務創建)。

    Static 方式需要預先知道集群所有節點的 IP,所以適合小規模的集群或者搭建一個臨時的開發與測試環境。

    Discovery 方式不需要預先了解其他節點的 IP。啟動時 etcd 通過訪問一個 Discovery URL 來注冊自己并獲取其他節點的信息。這種方式通常適合將 etcd 部署在某個云服務平臺或是一個 DHCP 環境中。其中 Discovery 服務可以使用 CoreOS 提供的一個公共地址 https://discovery.etcd.io/new 來申請一個 token,或者自己搭建一個這樣的服務并設定一個 token。出于安全的考慮,這個 token 應該只在集群初始引導時短暫存在,因為集群建立之后將不再需要這一地址,而集群中節點的變更可以通過 etcd 運行時重構的能力來進行配置。

    6. 運行

    下面我們嘗試使用 etcd 0.5.0 以 discovery 方式創建一個 CoreOS 集群。當然由于 etcd 0.5.0 尚未正式發布,所以我們目前還無法從官方渠道獲得打包 etcd 0.5.0 的 CoreOS 鏡像,但是我們可以修改引導文件,在 CoreOS 啟動時將 etcd 0.5.0 下載至系統里進行配置并啟動。

    CoreOS 官方提供了一個使用 vagrant + virtualbox 項目,供用戶在本地電腦中創建一個微型 CoreOS 集群。我們可以在這個項目的基礎上進行修改來實現我們的需求。

    6.1. Clone 項目到本地

    git clone  https://github.com/coreos/coreos-vagrant.git cd coreos-vagrant cp config.rb.sample config.rb cp user-data.sample user-data

    6.2. 通過 CoreOS 提供的公共 discovery 服務申請 token

    curl https://discovery.etcd.io/new?size=3

    https://discovery.etcd.io/780456e1317eb2db312b62ba1cb9a4f7

    size = 3 表示這個集群節點總數為 3 個。

    6.3. 修改 config.rb 文件

    # Size of the CoreOS cluster created by Vagrant $num_instances=3

    將啟動的 CoreOS 實例數量定為 3 個

    6.4. 修改 user-data 文件

    6.4.1. 修改 etcd 參數:

    etcd:     discovery: https://discovery.etcd.io/780456e1317eb2db312b62ba1cb9a4f7     advertise-client-urls: http://$public_ipv4:2379     initial-advertise-peer-urls: http://$public_ipv4:2380     listen-client-urls: http://$public_ipv4:2379     listen-peer-urls: http://$public_ipv4:2380 

    6.4.2. 修改 etcd 服務內容

    - name: etcd.service       command: start       content: |         [Unit]         After=network-online.target         Requires=network-online.target                  [Service]         ExecStartPre=/usr/bin/wget -N -P /opt/bin https://github.com/coreos/etcd/releases/ download/v0.5.0-alpha.3/etcd-v0.5.0-alpha.3-linux-amd64.tar.gz         ExecStartPre=/usr/bin/tar -C /opt/bin -xvf /opt/bin/etcd-v0.5.0-alpha.3-linux-amd64.tar.gz         ExecStartPre=/usr/bin/chmod +x /opt/bin/etcd-v0.5.0-alpha.3-linux-amd64/etcd         ExecStart=/opt/bin/etcd-v0.5.0-alpha.3-linux-amd64/etcd          [Install]         WantedBy=multi-user.target 

    修改的部分讓我們重新定制了 etcd 服務的內容。在系統啟動時,先將 etcd 0.5.0 的打包文件下載至指定目錄并在稍后將其啟動。

    6.4.3. 使用 vagrant 啟動集群

    vagrant up

    稍后 vagrant 將幫助我們在 VirtualBox 中創建三個 CoreOS 實例。

    6.4.4. 登錄到 CoreOS

    登錄到其中的一個節點

    vagrant ssh core-01

    查看一下 etcd.service 的狀態,輸入:

    systemctl status etcd.service

    不出意外的話,可以看到其狀態為 active (running)

    etcd.service    Loaded: loaded (/etc/systemd/system/etcd.service; disabled)   Drop-In: /run/systemd/system/etcd.service.d            └─20-cloudinit.conf    Active: active (running) since Sun 2014-11-16 13:10:59 UTC; 12min ago   Process: 894 ExecStartPre=/usr/bin/chmod +x /opt/bin/etcd-v0.5.0-alpha.3- linux-amd64/etcd (code=exited, status=0/SUCCESS)   Process: 890 ExecStartPre=/usr/bin/tar -C /opt/bin -xvf /opt/bin/etcd- v0.5.0-alpha.3-linux-amd64.tar.gz (code=exited, status=0/SUCCESS)   Process: 857 ExecStartPre=/usr/bin/wget -N -P /opt/bin  https://github.com/coreos/etcd/releases/download/v0.5.0-alpha.3/etcd-v0.5.0 -alpha.3-linux-amd64.tar.gz (code=exited, status=0/SUCCESS)  Main PID: 896 (etcd)    CGroup: /system.slice/etcd.service            └─896 /opt/bin/etcd-v0.5.0-alpha.3-linux-amd64/etcd 

    6.4.5. 通過 etcdctl 查詢集群狀態

    etcdctl 可以幫助我們查詢一下集群中節點信息,輸入:

    /opt/bin/etcd-v0.5.0-alpha.3-linux-amd64/etcdctl --peers 172.17.8.101:2379 member list

    啟動參數 --peers 172.17.8.101:2379 表示通過本節點的 2379 端口訪問 etcd 接口,用戶可以根據自己的實際情況對 IP 地址進行修正。

    正常情況下可看到如下輸出:

    b4f4d25ed56d7a44: name=b74c24773df147e1be8e1e35defaad38 peerURLs= http://172.17.8.101:2380 clientURLs=http://172.17.8.101:2379 b7404cc414e7affa: name=001db0fc02184af5b293e2cb21c86a11 peerURLs= http://172.17.8.102:2380 clientURLs=http://172.17.8.102:2379 f609956c55a6809e: name=2840dc331d224360a097b781c876c9e5 peerURLs= http://172.17.8.103:2380 clientURLs=http://172.17.8.103:2379

    這樣,我們就在本地創建了一個基于 etcd 0.5.0 的 CoreOS 集群。

    7. 預告

    作為 CoreOS 及管理工具介紹的第三部分,筆者將向大家介紹 CoreOS 集群的重要管理工具 fleet ,通過 fleet 用戶可以在 CoreOS 實現簡單的 Orchestration 功能,敬請期待。

    posted on 2017-02-03 14:12 jinfeng_wang 閱讀(318) 評論(0)  編輯  收藏 所屬分類: 2016-thinking2016-zookeeper
    主站蜘蛛池模板: 亚洲av无码国产精品色午夜字幕| a级毛片视频免费观看| 日韩精品亚洲人成在线观看| 婷婷综合缴情亚洲狠狠尤物| 国产日本一线在线观看免费| 国产成人无码区免费内射一片色欲| 亚洲AV无码之国产精品| 亚洲乱码中文字幕小综合| 亚洲成AV人片一区二区| 精品国产亚洲一区二区在线观看 | 女人18毛片水真多免费看| 暖暖在线视频免费视频| 又粗又长又爽又长黄免费视频| 亚洲香蕉久久一区二区 | 久久er国产精品免费观看8| 欧美亚洲精品一区二区| 亚洲一区二区三区无码国产| 久久综合亚洲鲁鲁五月天| 亚洲成色www久久网站夜月| 在线播放亚洲第一字幕| 久久精品国产精品亚洲人人| 亚洲 另类 无码 在线| 国产成人在线观看免费网站 | 亚洲精品国产第1页| 亚洲尹人九九大色香蕉网站| 亚洲国产成人片在线观看| 国产av天堂亚洲国产av天堂| 亚洲中文字幕无码一久久区| 中文字幕亚洲激情| 亚洲精品午夜国产VA久久成人| 亚洲视频一区二区| 国产亚洲精品a在线观看| 亚洲人成无码网WWW| 亚洲一区二区三区偷拍女厕 | 国产成人精品日本亚洲语音| 亚洲熟妇AV乱码在线观看| 亚洲欧洲AV无码专区| 亚洲AV成人精品一区二区三区| 国产亚洲视频在线观看| 全部在线播放免费毛片| 国产大片免费天天看|