基於一致性雜湊的分散式記憶體鍵值儲存——CHKV
Consistent Hashing based Key-Value Memory Storage
基於一致性雜湊的分散式記憶體鍵值儲存——CHKV。
系統設計
- NameNode : 維護key與節點的對映關係(Hash環),用心跳檢測DataNode(一般被動,被動失效時主動詢問三次),節點增減等系統資訊變化時調整資料並通知Client;
- DataNode : 儲存具體的資料,向NameNode主動發起心跳並採用請求響應的方式來實現上下線,便於NameNode挪動資料
- Client : 負責向NameNode請求DataNode資料和Hash演算法等系統資訊並監聽其變化,操縱資料時直接向對應DataNode發起請求就行,暫時只包含set,get,delete三個操作
NameNode失效則整個系統不可用
若當成記憶體資料庫使用,則只要有一個 DataNode 失效(未經請求與資料轉移就下線了)
整個系統就不可對外服務;
若當成記憶體快取使用,則 DataNode 失效只是失去了一部分快取,系統仍然可用。
客戶要使用CHKV就必須使用Client庫或者自己依據協議(相容redis)實現,可以是多種語言的API。
分析
要想實現高可用有兩點: NameNode 要主從雙機熱備,避免單點失效;每個 DataNode 可以做成主從複製甚至叢集。
各個元件之間的連線情況:
- NameNode 要保持和 N 個 Client 的TCP長連線,但是隻有在叢集發生變化時才有互動,所以使用IO多路複用負載就不大
- NameNode 要和 M 個 DataNode 保持心跳,TCP請求響應式,負載與 M 和心跳間隔秒數 interval 有關
- DataNode 與 Client 是TCP請求響應式操作,操作結束斷開連線,也可以考慮加入連線池
- DataNode 與 NameNode 保持心跳
- Client 與 NameNode 保持TCP長連線
- Client 與 DataNode TCP請求響應式操作
如下圖所示,有4個連線,其中1、2要保持連線,3、4完成請求後就斷開連線
NameNode
|| ||
1 、心跳請求響應|| ||2、監聽長連線
|| 3、資料請求響應 ||
DataNodes ========== Clients
|| ||
||
4、資料轉移,可複用3
開發優先順序:3、1、4、2
具體效能瓶頸要結合壓測來分析
使用方法
DataNode 執行起來就可以直接使用 redis-cli 連線,如redis-cli -h 127.0.0.1 -p 10100
,並進行set、get、del
操作;
注意:現在必須首先執行 NameNode,然後通過JVM引數的方式調整埠,可以在同一臺機器上執行多個 DataNode,
若要在不同機器上執行 DataNode 則可以直接修改配置檔案
新的DataNode可以直接上線,NameNode會自動通知下一個節點轉移相應資料給新節點;DataNode若要下線,
則可以通過telnet DataNode 節點的下線監聽埠(TCP監聽) 如 telnet 127.0.0.1 6666
,
併發送 k 字元即可,待下線的DataNode收到命令 k 後會自動把資料全部轉移給下一個DataNode
然後提示程序pid,使用者就可以關閉該DataNode程序了,如 Linux: kill -s 9 23456
,Windows:taskkill /pid 23456
NameNode和DataNode啟動後就可以使用Client了,程式碼示例如下:
try(Client client = new Client("192.168.0.136","10102")){
logger.debug(client.set("192.168.0.136:10099","123456")+"");
logger.debug(client.get("192.168.0.136:10099")+"");
logger.debug(client.set("112","23")+"");
logger.debug(client.del("1321")+"");
logger.debug(client.del("112")+"");
}
程式碼結構
- NameNode : 實現 NameNode 功能
- handler : handler
- res : 資源,如常量,命令工廠
- service : 服務,含Client管理,DataNode管理
- DataNode : 實現 DataNode 功能
- command : 處理客戶端各個命令的具體命令物件
- job : 一些的任務如心跳、資料遷移
- handler : 處理連線的handler
- service : 服務,含定時任務管理,資料請求管理
- Client : 實現 Client 功能
- handler : handler
- Client : 暴露給使用者的命令管理
- Connection : 發出網路請求
- Common : 實現一些公共的功能,上面三個模組依賴於此模組
- command : 命令抽象類
- model : 一些公用的pojo,如請求響應物件
- util : 一些工具類
- helper : 輔助指令碼
水平有限,目前專案的問題還很多,可以列個清單:
- 高可用性保證
- 斷線重連
- DataNode遷移資料的完整性保證
- 遷移過程資料的一致性
- 對於WeakReference的支援
- 更多資料型別
- 更多操作
- 完整的校驗機制
- 等等……
全部程式碼在Github上,歡迎 star,歡迎 issue,歡迎 pull request……
總之就是歡迎大家和我一起完善這個專案,一起進步。