Redis 架構(gòu)是如何演進(jìn)的?為什么?
Redis 現(xiàn)在已經(jīng)十分流行,互聯(lián)網(wǎng)幾乎所有項(xiàng)目都會(huì)用到,在使用 Redis 時(shí),你知道是如何保證穩(wěn)定和高效的提供服務(wù)呢,它的架構(gòu)演化路程是什么呢?
單機(jī)版 Redis
2010 年,Redis 1.0 版本發(fā)布,這個(gè)架構(gòu)非常簡單。你的業(yè)務(wù)系統(tǒng)可以把 Redis 作為緩存系統(tǒng),從 MySQL 查詢數(shù)據(jù),接著寫入到 Redis 中,之后業(yè)務(wù)系統(tǒng)再從 Redis 中讀取這些數(shù)據(jù)。
就這樣想享受 Redis 快到飛起的性能。然而,隨著時(shí)間的推移,業(yè)務(wù)體諒發(fā)展起來,忽然有一天,Redis 宕機(jī),所有的流量會(huì)打到 MySQL 上,嚴(yán)重的話還會(huì)壓垮 MySQL。
數(shù)據(jù)持久化
于是趕緊重啟 Redis,可是因?yàn)?Redis 都是把數(shù)據(jù)保存在內(nèi)存中,盡管你把 Redis 重啟了,之前的戶數(shù)也丟失了。流量依然會(huì)打到 MySQL 上,咋辦呢?
于是,2013 年,Redis 2.8 版本發(fā)布,迎來了數(shù)據(jù)持久化。我們總不能每次寫數(shù)據(jù)都寫磁盤,這樣太慢了,于是 Redis 引入 RDB 內(nèi)存快照的方式實(shí)現(xiàn)持久化。
定時(shí)的把當(dāng)前 Redis Redis 中的數(shù)據(jù),寫到磁盤上的 RDB 文件就可以了。除了 RDB 內(nèi)存快照文件做持久化以外,還支持 AOF 文件。也就是將每次寫指令都寫到 AOF 文件中。
主從復(fù)制
似乎經(jīng)過上面的優(yōu)化,你再也不擔(dān)心 Redis 宕機(jī)了,即使宕機(jī),也可以通過持久化文件快速恢復(fù) Redis 中的數(shù)據(jù)。
可事情并沒這么簡單,如果一個(gè)一個(gè)實(shí)例宕機(jī),我們是否可以部署多個(gè) Redis 實(shí)例,并保持實(shí)時(shí)數(shù)據(jù)同步,當(dāng)一個(gè)實(shí)例宕機(jī),手動(dòng)從剩下的實(shí)例提升為 master 繼續(xù)提供服務(wù)實(shí)現(xiàn)高可用。
就這樣,Redis 2.8 版本添加了主從復(fù)制功能。主從復(fù)制架構(gòu)誕生了,master 處理實(shí)時(shí)讀寫請(qǐng)求,另一個(gè)叫做 slave 的節(jié)點(diǎn)同步 master 的數(shù)據(jù)。通過主從架構(gòu)縮短不可用時(shí)間,并且還可以讓 slave 節(jié)點(diǎn)分擔(dān)一部分讀請(qǐng)求,提升應(yīng)用整體性能。
哨兵集群
有了主從復(fù)制就萬無一失了么?答案是否定的。
因?yàn)槲覀兺ㄟ^人工介入來實(shí)現(xiàn)主從切換的,就必須要算上人的反應(yīng)時(shí)間、操作時(shí)間,所以,在這期間你的業(yè)務(wù)應(yīng)用依舊會(huì)受到影響。
如何把這個(gè)過程自動(dòng)化?
我們可以引入一個(gè)檢查員,讓這個(gè)檢察院實(shí)時(shí)監(jiān)測(cè) master 的健康狀態(tài),這個(gè)觀察者就叫做哨兵。
2012 年,Redis 在 2.6 版本首次發(fā)布哨兵模式,直到 Redis 2.8 版本第二版才變成生產(chǎn)可用。
哨兵是 Redis 的一種運(yùn)行模式,它專注于對(duì) Redis 實(shí)例(主節(jié)點(diǎn)、從節(jié)點(diǎn))運(yùn)行狀態(tài)的監(jiān)控,并能夠在主節(jié)點(diǎn)發(fā)生故障時(shí)通過一系列的機(jī)制實(shí)現(xiàn)選主及主從切換,實(shí)現(xiàn)故障轉(zhuǎn)移,確保整個(gè) Redis 系統(tǒng)的可用性。結(jié)合 Redis 的 官方文檔,可以知道 Redis 哨兵具備的能力有如下幾個(gè):
- 監(jiān)控:持續(xù)監(jiān)控 master 、slave 是否處于預(yù)期工作狀態(tài)。
- 自動(dòng)切換主庫:當(dāng) Master 運(yùn)行故障,哨兵啟動(dòng)自動(dòng)故障恢復(fù)流程:從 slave 中選擇一臺(tái)作為新 master。
- 通知:讓 slave 執(zhí)行 replicaof ,與新的 master 同步;并且通知客戶端與新 master 建立連接。
Cluster 集群
2015 年,Redis 3.0 發(fā)布,這是一個(gè)里程碑版本,新增了 Redis 集群。
使用 Redis Cluster 集群,主要解決了大數(shù)據(jù)量存儲(chǔ)導(dǎo)致的各種慢問題,同時(shí)也便于橫向拓展。
Redis 集群是一種分布式數(shù)據(jù)庫方案,集群通過分片(sharding)來進(jìn)行數(shù)據(jù)管理(「分治思想」的一種實(shí)踐)。
將數(shù)據(jù)劃分為 16384 的 slots,每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分槽位。槽位的信息存儲(chǔ)于每個(gè)節(jié)點(diǎn)中。是一個(gè)無中心架構(gòu),并提供復(fù)制和故障轉(zhuǎn)移功能。
展望未來
Redis 受歡迎主要原因是極高的性能以及豐富、方便使用的數(shù)據(jù)結(jié)構(gòu),這些簡單好用的數(shù)據(jù)結(jié)構(gòu)大幅度降低開發(fā)業(yè)務(wù)復(fù)雜度。大家都在緊貼用戶需求,開發(fā)更多的數(shù)據(jù)結(jié)構(gòu)。
- 2017 年,Redis 5.0 發(fā)布,該版本最大的變化,就是新增了 stream 數(shù)據(jù)類型。
- 2020 年,Redis 6.0 發(fā)布,該版本引入了網(wǎng)絡(luò) IO 多線程,Redis 模型主要分為網(wǎng)絡(luò)模塊和命令處理模塊,作者認(rèn)為正常情況下,redis 單線程模型中,網(wǎng)絡(luò)模塊往往成為瓶頸高發(fā)地;
- 2022 年,Redis 7.0 發(fā)布,該版本就是重構(gòu)了 dict 結(jié)構(gòu),內(nèi)存占用更小,內(nèi)存成本會(huì)大大減少,RDB 版本不向下兼容。