分區
Nuclear是一個分散式的Key-Value存儲系統,那么key對應的數據分布在什麼節點上,需要遵守一定的規則。熟悉MemecachedClient的同學一定清楚一致性Hash的套用,沒錯,HashRing就是我們的不二選擇。在Nuclear中,數據分布在0~2的HashRing上,Nuclear集群初始化的時候,根據節點數均分整個Hash Ring。
在N=3時,A,B,C三個節點的配置就是系統需要的最少節點了。Nuclear中,順時針的開始值和結束值確定一個分區管理的數據範圍,同時規定分區的範圍左開右閉。因此,如上圖,我們記錄A,B,C分別管理的分區範圍是:
A {[c,a],[b, c],[a,b]}
B {[a,b],[c,a],[b,c]}
C {[b,c],[a,b],[c,a]}
可以看出,A處理管理自己的分區數據外,還會把自己管理的數據順時針往前複製到2(N-1)個節點中。
節點變更
Nuclear增加節點時需要制定目標節點的名稱,即增加的節點是用來分擔目標節點的負載的。這點不同於Dynamo的分區策略,節點增加的時候會均衡的從現有的節點竊取分區,Nuclear中增加的節點只會影響到鄰近的三個節點。
記錄N,A,B,C管理的分區如下:
N {[c,n],[b,c],[a,b]}
A {[n,a],[c,n],[b,c]}
B {[a,b],[n,a],[c,n]}
C {[b,c],[a,b],[n,a]}
Nuclear的分區管理模組將自動的計算出需要同步到N上的數據:
A [a,b] => N
B [b,c] => N
C [c,n] => N
不難明白,其實就是把A,B,C不再需要的數據挪給新的節點了。刪、替換節點原理大同小異,不再冗述。
路由
Nuclear提供伺服器端路由策略,Client的請求隨機落在Node節點上,由接收到請求的節點處理後續的邏輯。相對於Client端路由來說,優點是Client無需知道Nuclear集群元數據,易於維護;缺點是會造成一定程度的延時,不過我們的測試結果顯示延時在可接受範圍之內。
兩個設計上的Tips貢獻給大家:
1. 萬事皆異步
我們在編碼的過程中走了一些彎路,同步的操作在高並發的情況下帶來的性能下降是非常恐怖的,於是乎,Nuclear系統中任何的高並發操作都消除了Block。no waiting, no delay。
2. 根據系統負載控制後台執行緒的資源占用
Nuclear系統中有不少的後台執行緒默默無聞的做著各種辛苦的工作,但是它們同樣會占用系統資源,我們的解決方案是根據系統負載動態調整執行緒的運行和停止,並達到平衡。
特性
高可拓展
一個Nuclear集群支持1到n(n<2的64平方)個節點(Node)的規模,每台伺服器(Server)支持部署多個節點。當集群資源達到瓶頸時,可以通過增加新的節點來擴展。增加新節點的過程,系統服務無需停止,無需人工干預遷移數據。Nuclear理論上可以無限Scale-Out。
高可靠性
單個節點的crash永遠對系統的運行造成影響,不存在單點風險。數據的寫入參考Dynamo的W+R>N理論,簡釋之,例如設定系統每一份數據都存儲在3個節點上(N=3),那么讀的話必須成功讀到兩個節點上的數據才認為讀成功 (R=2),寫的話必須成功寫到兩個節點上才認為寫成功( W=2)。系統永遠可寫入(Hinted HandOff)。
高性能
在Xeon E5405 CPU的伺服器上,單節點每秒最高2.5w req/s。整個集群的性能取決於一致性級別、N、W、R數及底層存儲引擎的選擇。