redis三種集群方式主從/哨兵/Cluster

redis的集群方式主要有以下三種:

1、 主從模式

master掛掉之后,slave仍能正常讀,但redis不再提供寫服務,直到master重新啟動
slave掛掉之后不影響其他slave的讀和master的讀寫,slave重啟后重新同步master數(shù)據(jù)

主寫從讀:

主庫寫,從庫讀,從庫掛掉之后從主庫讀。
主讀寫從備份:
主庫讀寫,從庫只做備份。主庫掛掉之后,redis不再工作

主從一致:

從庫啟動后,主動向master發(fā)送SYNC命令,master將保存快照(RDB持久化數(shù)據(jù))和 保存快照到當前時間的緩存命令 發(fā)送給slave。slave接收消息后加載快照和執(zhí)行緩存命令

slave上線后,master每次接收寫命令都會發(fā)給slave,保證主從一致。

缺點:

master掛掉之后不能再提供寫服務。單點故障

優(yōu)點:

簡單,易維護。省資源

2、哨兵模式

監(jiān)控redis集群的狀態(tài),在master掛掉之后,重新選擇新的master。選擇機制:

  • 使用如下條件篩選備選node:
  1. slave節(jié)點狀態(tài)處于S_DOWN,O_DOWN,DISCONNECTED的除外
  2. 最近一次ping應答時間不超過5倍ping的間隔(假如ping的間隔為1秒,則最近一次應答延遲不應超過5秒,redis sentinel默認為1秒)
  3. info_refresh應答不超過3倍info_refresh的間隔(原理同2,redis sentinel默認為10秒)
  4. slave節(jié)點與master節(jié)點失去聯(lián)系的時間不能超過( (now - master->s_down_since_time) + (master->down_after_period * 10))??傮w意思是說,slave節(jié)點與master同步太不及時的(比如新啟動的節(jié)點),不應該參與被選舉。
  5. Slave priority不等于0(這個是在配置文件中指定,默認配置為100)。
  • 從備選node中,按照如下順序選擇新的master
  1. 較低的slave_priority(這個是在配置文件中指定,默認配置為100)
  2. 較大的replication offset(每個slave在與master同步后offset自動增加)
  3. 較小的runid(每個redis實例,都會有一個runid,通常是一個40位的隨機字符串,在redis啟動時設置,重復概率非常小)
  4. 如果以上條件都不足以區(qū)別出唯一的節(jié)點,則會看哪個slave節(jié)點處理之前master發(fā)送的command多,就選誰。

哨兵也是有集群的,哨兵之前也是互相監(jiān)控的,哨兵和redis集群之前是多對多的關系。

哨兵監(jiān)控master流程:
  1. 哨兵每秒向master、slave發(fā)送一次ping命令,每10s發(fā)送一次info命令。
  2. 如果實例回復的時間比設置的時間要晚,則實例會被標記為主觀下線
  3. 如果master被標記為主觀下線,則監(jiān)控該master的所有哨兵會向該master每秒發(fā)送一次ping,確認其下線。
  4. 當有足夠多的哨兵確認了該master的下線狀態(tài),則該master就會被標記為客觀下線。
  5. 如果master被標記為客觀下線,則哨兵向所有slave發(fā)送INFO命令每s一次。
  6. 若沒有足夠多的哨兵同意master下線則master客觀下線狀態(tài)會被解除。若master重新向哨兵相應,則master主觀下線狀態(tài)解除。

3、集群模式

可以說是哨兵模式和主從模式的結合。cluster模式有多個節(jié)點,每個節(jié)點都有主從。主要解決單機redis內(nèi)存不夠的問題。
redis集群通過哈希槽將redis數(shù)據(jù)分布式存儲到集群的master節(jié)點中,slave節(jié)點不工作,僅在master節(jié)點掛掉之后替換master繼續(xù)提供服務。
redis每個節(jié)點負責一部分哈希槽位。

集群節(jié)點的擴展/收縮方式:
  1. 首先啟動一個 Redis 節(jié)點,記為 M4。
  2. 使用 cluster meet 命令,讓新 Redis 節(jié)點加入到集群中。新節(jié)點剛開始都是主節(jié)點狀態(tài),由于沒有負責的>槽,所以不能接受任何讀寫操作,后續(xù)我們就給他遷移槽和填充數(shù)據(jù)。
  3. 對 M4 節(jié)點發(fā)送 cluster setslot { slot } importing { sourceNodeId } 命令,讓目標節(jié)點準備導入槽的數(shù)據(jù)。 >4) 對源節(jié)點,也就是 M1,M2,M3 節(jié)點發(fā)送 cluster setslot { slot } migrating { targetNodeId } 命令,讓源節(jié)>點準備遷出槽的數(shù)據(jù)。
  4. 源節(jié)點執(zhí)行 cluster getkeysinslot { slot } { count } 命令,獲取 count 個屬于槽 { slot } 的鍵,然后執(zhí)行步驟>六的操作進行遷移鍵值數(shù)據(jù)。
  5. 在源節(jié)點上執(zhí)行 migrate { targetNodeIp} " " 0 { timeout } keys { key... } 命令,把獲取的鍵通過 pipeline 機制>批量遷移到目標節(jié)點,批量遷移版本的 migrate 命令在 Redis 3.0.6 以上版本提供。
  6. 重復執(zhí)行步驟 5 和步驟 6 直到槽下所有的鍵值數(shù)據(jù)遷移到目標節(jié)點。
  7. 向集群內(nèi)所有主節(jié)點發(fā)送 cluster setslot { slot } node { targetNodeId } 命令,通知槽分配給目標節(jié)點。為了>保證槽節(jié)點映射變更及時傳播,需要遍歷發(fā)送給所有主節(jié)點更新被遷移的槽執(zhí)行新節(jié)點。
客戶端路由:
  1. smart集群客戶端維護了一張哈希槽對應節(jié)點的關系列表。
  2. 客戶端根據(jù)本地 slot 緩存發(fā)送命令到源節(jié)點,如果存在鍵對應則直接執(zhí)行并返回結果給客戶端。
  3. 如果節(jié)點返回 MOVED 錯誤,更新本地的 slot 到 Redis 節(jié)點的映射關系,然后重新發(fā)起請求。
  4. 如果數(shù)據(jù)正在遷移中,節(jié)點會回復 ASK 重定向異常。格式如下: ( error ) ASK { slot } { targetIP } : { targetPort }
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容