CAP in tns
tns (thrift nameserver) provides distributed solutions for thrift, support find services, high availability, load balancing, the gray release, horizontal scaling, and so on.
cap
C:一致性
A:可用性
P:分區容忍性
Architecture in tns
集群采用無中心化設計,按節點ID排序並順時針組成一個環,如圖C1,節點按固定頻率將其知道的cluster list、status和service list同步給下一個節點,並記錄被同步節點的健康狀態。
一致性
cluster視角
在tns中,不可變約束包括cluster node列表、cluster node健康狀態、service node 列表。
tns 針對以上不可變約束滿足最終一致性
增加node(cluster、service)
假設數據同步周期為T,鏈接某個cluster node並增加一個node(cluster、service),在最長T周期後數據會被同步給下個節點,以此類推,假設集群節點數為N,最終一致時間最長為(N-1)T
移除node(service)
tns目前隻支持移除service node,對於cluster node的移除功能暫不支持。
對於移除service node,tns需要經曆兩個階段:Leaving階段和Tombstone階段
- Leaving階段
- 被移除的service node會被立即變更狀態為Leaving,並取消對應的ping任務
- 在周期T內,狀態會被傳輸到下個節點
- 最終在(N-1)T內,狀態會被傳輸到所有節點
-
Tombstone階段
- tns中有一Tombstone任務,每隔10分鍾運行一次
- 每次運行檢查service node狀態
- 若狀態為Leaving,將狀態變更為Tombstone
- 若狀態為Tombstone,直接移除
處於Leaving狀態的節點仍會同步給其它節點;處於Tombstone狀態的節點不會同步給其它節點;這兩種狀態均不接受狀態更新;
為什麼是10分鍾?
保證Leaving狀態廣播到整個集群;保證在真正移除前,集群所有節點處於Tombstone狀態。
假設時間比較短,處於Leaving狀態的service node,可能還沒來得及廣播給整個集群,狀態即被變更為Tombstone,處於此狀態的數據不會進行同步,最終導致集群某個節點沒收到移除通知;另外,處於Tombstone狀態的service node,節點一旦被執行移除,其上一個節點待移除數據可能處於Leaving甚至是UP狀態,數據可能會被同步回來,最終導致集群出現錯誤。
tns中,同步的周期被設置為5秒,數據廣播到所有節點的最長時間為5(N-1),所以理論上集群節點數量N可以達到120個,結合tns的負載特點,基本不會用到這麼多節點
client視角
目前版本客戶端不考慮一致性問題,未來可能會增加單調讀一致性
,但需求不大
tns-client會定時從cluster同步數據,在這個周期內,可能會出現數據不一致。例如某時刻一個service node被移除或已經down 掉,並且未及時被tns-client同步過來,可能會導致client使用一個錯誤的service node來之行業務,拒絕鏈接等等,在tns-client中提供了brokenNode接口來移除一個故障節點
可用性
故障檢測
tns采用增量故障檢測算法
來檢測集群故障。
一個Up節點單次故障不會被立即標記為Down,而是被標記為Down_1,如果Down_1節點下次檢測仍是故障,則會被標記為Down_2,如果Down_2節點下次檢測仍是故障,則會被標記為Down,此後不會在對該節點之行故障檢測。如圖C2:
cluster視角
tns中,集群節點數量N>0即可寫。
client視角
tns中,集群節點數量N>0即可讀,同時因為tns是一個最終一致性的係統,節點的down機,會在(N-1)T內廣播到整個集群,同時tns-client定時從某個cluster node同步數據也是定時操作,所以同步時某個節點可能不可用,此種情況可以采取兩種措施:
- 換個節點立即重試
- 等待下一個同步周期(選擇到一個健康節點)
目前tns-client采用方法2
分區容忍性
一般認為在同一個機房不會出現分區,在跨機房場景中會出現分區現象;同時在同機房內節點的上下線也被認為是特殊的分區。如圖C3:
tns不滿足跨機房的分區容忍性,如果跨機房部署,出現分區情況,在沒有人為增加、移除節點的情況下沒有問題,tns中節點的增加、移除操作均為人工操作,所以這樣部署問題也不大,隻要在操作前檢查下集群狀態即可,操作後檢查下結果是否已經被廣播到整個集群。
最後更新:2017-04-11 16:00:48