Redis叢集方案-Codis
作者介紹
郝朝陽,DevOps視角社群發起人,高階運維工程師,專注於運維自動化的實現。現就職於宜搜科技,負責前端運維工作。致力於形成自己的運維細想體系。
codis介紹
codis是豌豆莢基礎架構團隊開發並開源的分散式redis服務,可以看作是一個無限記憶體的redis服務,有動態擴容/縮容的能力。
codis使redis獲得動態擴容/縮容的能力,增減redis例項對client完全透明,並不需要重啟服務,不需要業務方面擔心redis記憶體爆掉的問題。
codis架構
單codis-proxy架構
多codis-proxy架構
在codis的設計中,codis-proxy被設計成無狀態的,客戶端連線任何一個codis-proxy都是一樣的,所以可以比較容易單間多個codis-proxy來實現高可用並橫向擴容。建議使用多codis-proxy的高可用架構。
codis的特點
codis分片
codis採用pre-sharding的技術來實現資料的分片,預設分成1024個slot(0-1023)。對於每個key來說,通過雜湊演算法crc32(key)%1024來 確定slot id。
slot是虛擬概念。每一個slot都會有一個且必須有一個特定的server group id來表示這個slot的資料由哪個server group來提供。資料的遷移也是以slot為最小單位的。
codis資料遷移
codis支援通過codis-server進行資料遷移,遷移資料時是一個個key來進行的。每次以一個key為最小單位進行遷移,不會把主執行緒block住。redis的操作是記憶體的,批量的一次性寫入和分多次set幾乎沒有區別,再者這個模型還避免了遷移過程中的資料更新同步的問題,因為遷移一個key的操作是原子性的,對於這個redis-server來說,在完成這次遷移指令前,是不會響應其它請求的,所以保證了資料的安全。
redis遷移到codis
redis-port工具
codis提供了redis-port的命令列工具,能夠實現從資料上T的redis叢集遷移到codis分散式redis叢集。redis-port具有如下功能:
- 靜態分析RDB檔案,包括解析以及恢復RDB資料到redis
- 從redis上dump RDB檔案以及在redis和codis之間動態同步資料
實現步驟
實現redis叢集遷移到codis叢集,需要進行如下操作
- 搭建好codis叢集,並且codis-proxy能正確執行起來
- 對每一個redis例項執行一個redis-port來向你codis匯入資料。如: nohup redis-port sync –ncpu=4–from=redis-server:6379 \ –target=codis-proxy:19000 >${port}.log 2>&1 &
每個redis-port負責將對應的redis資料匯入到codis 多個redis-port之間互不干擾,除非多個redis上的key出現衝突 單個redis-port可以將負責的資料並行遷移一提高速度,通過—nohup指定並行數 匯入速度受頻寬以及codis-proxy處理速度限制
- 完成資料遷移,在適當的時候將服務指向codis叢集,並將redis叢集下線
原redis叢集下線時,會導致redis-port連線斷開,於是自動退出
高可用
codis-proxy高可用
因為codis-proxy是無狀態的,所以比較容易實現高可用性並橫向擴容。
對於JAVA使用者來說,可以使用設計者修改過的jedis(https://github.com/CodisLabs/jodis),來實現codis-proxy的高可用。它會通過監控zk上的註冊資訊來實時獲得當前可用的proxy列表,既可以保證高可用性,也可以通過輪流請求所有的proxy實現負載均衡。如果需要非同步請求,可以使用基於Netty開發的Nedis。
redis例項高可用
對於codis-group的redis例項來說,當一個group的master故障後,應該讓管理員清楚的知道,並手動將slave升級為master,因為這涉及到資料一致性等問題。當group中的master故障,其中一個slave升級為master後,該組內的其它slave例項是不會自動改變狀態的,這些slave仍試圖從舊的master上同步資料,因而導致組內新的master和slave之間資料不一致。因為redis的slaveof命令切換master時會丟棄slave上的全部資料,從新master完整同步,會消耗新master資源,因此建議在知情的情況下手動操作,是用codis-configserver addslave。
codis通過開放的api實現自動切換主從的工具-codis-ha,會檢測到master故障後,會自動將其下線,並將期中一個salve提升為master,但是不會自動重新整理其它slave的狀態。
文章來自微信公眾號:DevOps視角