歡迎光臨
每天分享高質量文章

Redis高可用,高效能,架構演進史

來自公眾號:Java識堂

介紹

上個禮拜,我搭建了一個mongo分片叢集,發現分散式系統保證高可用和高效能的套路都差不多。高效能就是做分片(可以類比為分庫分表,將資料分到不同伺服器上),在Kafka中叫分割槽,在mongodb中叫shard,在HDFS上叫DataNode。而保證高可用的方式就是做交叉備份。然後我很好奇Redis是怎麼部署的。

上測試環境檢視叢集的狀態

info replication

輸出如下,好吧,沒有做高可用,一個master節點開跑。

# Replication
role:master
connected_slaves:0

一個Redis實體其實有很多問題,最起碼Redis崩了就沒法提供服務了,而且單機能夠承載的QPS在上萬到幾萬不等

replication(複製)

如果業務要承載的QPS在幾十萬,單機是不可能做到的,此時就可以用到複製。做一個主從架構,一主多從,master節點負責寫,slave節點負責讀,假如說一個節點可以承載的5w讀QPS,那麼兩個節點就可以承載10w的讀QPS,水平擴容非常方便。

master節點掛太多slave節點會有效能問題,此時就可以在slave節點上掛slave節點

redis replication的核心機制有如下幾點

1、redis採用非同步方式複製資料到slave node,不會block master node的正常工作
2一個master node可以配置多個slave node,slave node也可以連線其他的slave node
3、slave node主要用來進行橫向擴容,做讀寫分離,擴容的slave node可以提高讀的吞吐量

主從複製的實現原理

1、slave連線master,傳送SYNC命令;
2、master接收到SYNC命名後,開始執行BGSAVE命令生成RDB檔案並使用緩衝區記錄此後執行的所有寫命令;
3、master BGSAVE執行完後,向slave傳送快照檔案,併在傳送期間繼續記錄被執行的寫命令;
4、slave收到快照檔案後丟棄所有舊資料,載入收到的快照;
5、master快照傳送完畢後開始向salve傳送緩衝區中的寫命令;
6、slave完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;

sentinel(哨兵)

主從架構有一個缺點就是如果master節點掛了,那麼寫服務是不可用的,因為slave節點預設是隻讀的,這時就重啟master節點或者重新配置主從,有沒有更好的方案呢?類似zookeeper的元件,能自動完成主從切換。在Redis中還真有,就是sentinel節點,當master節點發生故障能自動完成主從切換。

當master節點掛掉時,sentinel將一個slave節點變成maste節點,當原先的master節點可用時,以slave的角色加入叢集。

一個高可用的系統是很忌諱有單點問題的。看到沒,sentinel就是一個單點,如果sentinel掛了,主從切換也就沒人做了。所以應該將sentinel也做成一個叢集

哨兵的作用有如下幾點

1、叢集監控,負責監控redis master和slave行程是否正常工作
2、訊息通知,如果某個redis實體有故障,那麼哨兵負責傳送訊息作為報警通知給管理員
3、故障轉移,如果master node掛掉了,會自動轉移到slave node上
4、配置中心,客戶端初始化時,透過哨兵獲得master地址,如果故障轉移發生了,通知客戶端新的master地址

redis cluster(叢集)

主從+哨兵,只能保證Redis的高可用,並不能保證Redis的高效能,因為一個master節點並不能放海量資料,而且單個Redis的實體過大時,會導致rdb檔案過大,當執行主從同步時時間過長。

如果想做到高效能該怎麼辦?分片啊,我一開始就提到了,都是一個套路。redis搞幾個節點,每個節點儲存一部分資料。可想而知,此時查詢和插入都得按照一定的分片策略,總不能查詢一個資料把所有的redis節點遍歷一遍吧。而這種操作不應該放在客戶端,中介軟體興起了,常見的有codis,twemproxy

圖片來自《Redis 深度歷險:核心原理與應用實踐》

客戶端不連線具體的Redis,而是連線Codis,2個Codis節點保證高可用,和Mycat一個套路。

當然Redis作者也意識到這個問題了,redis cluster應用而生。

沒時間寫了,下一篇再補充sentinel 和 redis cluster的其他知識吧

已同步到看一看
贊(0)

分享創造快樂