Serf是什么?
Serf是hashicorp開源的去中心化成員管理、失敗檢測和服務編排工具,具有輕量級、高可用和分區容錯的特點。Serf底層采用gossip協議,通過在集群中廣播消息,從而實現了集群中節點下線自動感知。由于gossip協議實現了最終一致性,所以Serf是一個AP系統。Serf可應用于負載均衡器、Memcached或者Redis集群管理、DNS記錄更新等場景。
Serf如何工作?
Serf建立在gossip協議之上,實現了"SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol"論文中算法,集群中每個節點維護一個成員列表,通過失效檢測器模塊檢測節點是否宕機,傳播組件將節點成員列表進行交換合并,從而更新集群幾點狀態。
Serf傳播組件
傳播組件中,節點將維護的成員列表隨機的發往集群中若干節點,從而進行信息交換。一般有兩種交換模式:Anti-entropy和Rumor mongering。Anti-entropy會交換節點的全量信息,Rumor mongering會交換節點的增量信息。對于每種模式,具體實施時,可以采用Push、Pull或者Push-Pull混合方式。Push方式會主動推出新信息到其他節點;Pull方式需要隨機選擇若干節點,推送自己的信息;Push-Pull混合方式則需要結合Push和Pull進行信息雙向交換。Serf采用了Anti-entropy模式,交換信息時使用Push-Pull混合方式。
Serf實效檢測器
失效檢測器則通過輪詢成員列表,定期發送心跳信息來檢測節點狀態。心跳信息會通過多種通信方式進行發送,首先會定向發送UDP包,如果在超時時間內沒有收到確認回復,則會隨機選擇若干節點,通過向中繼節點發送間接心跳信息,委托中繼節點確定節點狀態;如果中繼節點仍然沒有收到回復,則會將該節點標記為疑似實效節點,在確定的閾值范圍內,如果沒有收到回復信息,才會將節點最終標記為實效。
在Serf所采用的gossip協議中,同時融入了網絡診斷功能,該功能實現了"Vivaldi: A Decentralized Network Coordinate System"論文中的算法。通過維持節點在集群中的多維度坐標,來計算節點間RTT時間。
Serf集群搭建
Serf支持接收命令行請求,從而實現節點添加,用戶查詢及事件處理。下面以搭建2個節點的集群為例,說明Serf如何處理命令行請求。
首先,從官網下載二進制壓縮包,解壓后及為二進制可執行文件。
執行agent命令啟動Serf節點1,該節點具有集群唯一的名字foo,gossip端口綁定地址127.0.0.1:5000,集群間rpc通信端口綁定127.0.0.1:7373。
serf agent -node=foo -bind=127.0.0.1:5000 -rpc-addr=127.0.0.1:7373
同樣格式的命令啟動Serf節點2:
serf agent -node=bar -bind=127.0.0.1:5001 -rpc-addr=127.0.0.1:7374
雖然此時已經有兩個節點啟動,但是這兩個節點并不知道彼此的存在,也就是說沒有形成一個集群。為了能夠讓節點能夠彼此發現,需要手動將節點添加到一個已知的集群,這需要執行Serf的join命令:
serf join 127.0.0.1:5001
該命令告訴foo節點,加入節點bar所在的集群。此時通過查詢命令members,則可以看到集群節點狀態:
$ serf members
foo 127.0.0.1:5000 alive
bar 127.0.0.1:5001 alive
可以看到集群中已經有兩個狀態為alive的節點,至此一個測試使用的Serf集群搭建成功。