高可用是通過設計,減少系統不能提供服務的時間,是分布式系統的基礎也是保障系統可靠性的重要手段。而 Redis 作為一款普及率最高的內存型中間件,它的高可用技術也非常的成熟。
我們今天分享的面試題是,Redis 是如何保證系統高可用的?它的實現方式有哪些?
Redis通過一系列策略和技術來保證其系統的高可用性。以下是Redis保證高可用的主要實現方式:
-
持久化:
- RDB (Redis DataBase):在指定的時間間隔內將內存中的數據集快照寫入磁盤,它執行的是全量數據備份,恢復時是將快照文件直接讀到內存里。
- AOF (Append Only File):以日志的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),在Redis啟動之初會重新執行文件中記錄的寫指令來恢復數據。AOF日志是一個只進行追加的日志文件,因此寫入性能也非常高,而且文件不容易破損。
-
主從復制(Master-Slave):
- 主從復制是Redis實現高可用的基礎,它的原理是將一臺Redis服務器的數據,復制到其他的Redis服務器。主節點(Master)處理寫請求,并將數據同步給從節點(Slave),從節點處理讀請求。當主節點故障時,可以通過選舉算法從從節點中選舉出新的主節點。
-
哨兵(Sentinel):
- 哨兵是一個獨立的進程,用于監控主從集群的運行狀態。當主節點故障時,哨兵會執行自動故障轉移,將其中一個從節點提升為主節點,從而保證系統的高可用性。同時,哨兵還可以監控Redis的持久化情況,如果持久化出現故障,則通知管理員。
-
Redis集群(Cluster):
- Redis集群實現了Redis數據的分片,每個節點只保存一部分數據。集群通過哈希槽(Hash Slot)來分配數據,每個節點都負責一部分哈希槽。當節點故障時,集群會自動將數據重新分配到其他節點上,從而保證數據的高可用性。
-
讀寫分離:
- 在主從復制的基礎上,配合讀寫分離策略,可以進一步提高Redis的并發處理能力。通常主節點負責寫請求,而從節點負責讀請求。這樣可以減輕主節點的負載壓力,提高系統的整體性能。
-
使用代理工具:
- 如Twemproxy、Codis等代理工具可以實現Redis的負載均衡和故障轉移。這些工具將多個Redis實例組成一個集群,客戶端通過代理工具來訪問Redis集群,代理工具負責將請求分發到合適的Redis實例上。
典型回答
Redis 高可用的手段主要有以下四種:
- 數據持久化
- 主從數據同步(主從復制)
- Redis 哨兵模式(Sentinel)
- Redis 集群(Cluster)
其中數據持久化保證了系統在發生宕機或者重啟之后數據不會丟失,增加了系統的可靠性和減少了系統不可用的時間(省去了手動恢復數據的過程);而主從數據同步可以將數據存儲至多臺服務器,這樣當遇到一臺服務器宕機之后,可以很快地切換至另一臺服務器以繼續提供服務;哨兵模式用于發生故障之后自動切換服務器;而 Redis 集群提供了多主多從的 Redis 分布式集群環境,用于提供性能更好的 Redis 服務,并且它自身擁有故障自動切換的能力。
考點分析
高可用的問題屬于 Redis 中比較大的面試題了,因為很多知識點都和這個面試題有關,同時也屬于比較難的面試題了。因為涉及了分布式集群,而分布式集群屬于 Redis 中比較難懂的一個知識點。和此問題相關的面試題還有以下幾個:
- 數據持久化有幾種方式?
- Redis 主從同步有幾種模式?
- 什么是 Redis 哨兵模式?它解決了什么問題?
- Redis 集群的優勢是什么?
知識擴展
1.數據持久化
持久化功能是 Redis 和 Memcached 的主要區別之一,因為只有 Redis 提供了此功能。
在 Redis 4.0 之前數據持久化方式有兩種:AOF 方式和 RDB 方式。
- RDB(Redis DataBase,快照方式)是將某一個時刻的內存數據,以二進制的方式寫入磁盤。
- AOF(Append Only File,文件追加方式)是指將所有的操作命令,以文本的形式追加到文件中。
RDB 默認的保存文件為 dump.rdb,優點是以二進制存儲的,因此占用的空間更小、數據存儲更緊湊,并且與 AOF 相比,RDB 具備更快的重啟恢復能力。
AOF 默認的保存文件為 appendonly.aof,它的優點是存儲頻率更高,因此丟失數據的風險就越低,并且 AOF 并不是以二進制存儲的,所以它的存儲信息更易懂。缺點是占用空間大,重啟之后的數據恢復速度比較慢。
可以看出 RDB 和 AOF 各有利弊,RDB 具備更快速的數據重啟恢復能力,并且占用更小的磁盤空間,但有數據丟失的風險;而 AOF 文件的可讀性更高,但卻占用了更大的空間,且重啟之后的恢復速度更慢,于是在 Redis 4.0 就推出了混合持久化的功能。
混合持久化的功能指的是 Redis 可以使用 RDB + AOF 兩種格式來進行數據持久化,這樣就可以做到揚長避短物盡其用了,混合持久化的存儲示意圖如下圖所示:
我們可以使用“config get aof-use-rdb-preamble”的命令來查詢 Redis 混合持久化的功能是否開啟,執行示例如下:
127.0.0.1:6379> config get aof-use-rdb-preamble
1) "aof-use-rdb-preamble"
2) "yes"
如果執行結果為“no”則表示混合持久化功能關閉,不過我們可以使用“config set aof-use-rdb-preamble yes”的命令打開此功能。
Redis 混合持久化的存儲模式是,開始的數據以 RDB 的格式進行存儲,因此只會占用少量的空間,并且之后的命令會以 AOF 的方式進行數據追加,這樣就可以減低數據丟失的風險,同時可以提高數據恢復的速度。
2.Redis 主從同步
主從同步是 Redis 多機運行中最基礎的功能,它是把多個 Redis 節點組成一個 Redis 集群,在這個集群當中有一個主節點用來進行數據的操作,其他從節點用于同步主節點的內容,并且提供給客戶端進行數據查詢。
Redis 主從同步分為:主從模式和從從模式。主從模式就是一個主節點和多個一級從節點,如下圖所示:
而從從模式是指一級從節點下面還可以擁有更多的從節點,如下圖所示:
主從模式可以提高 Redis 的整體運行速度,因為使用主從模式就可以實現數據的讀寫分離,把寫操作的請求分發到主節點上,把其他的讀操作請求分發到從節點上,這樣就減輕了 Redis 主節點的運行壓力,并且提高了 Redis 的整體運行速度。
不但如此使用主從模式還實現了 Redis 的高可用,當主服務器宕機之后,可以很迅速的把從節點提升為主節點,為 Redis 服務器的宕機恢復節省了寶貴的時間。
并且主從復制還降低了數據丟失的風險,因為數據是完整拷貝在多臺服務器上的,當一個服務器磁盤壞掉之后,可以從其他服務器拿到完整的備份數據。
3.Redis 哨兵模式
Redis 主從復制模式有那么多的優點,但是有一個致命的缺點,就是當 Redis 的主節點宕機之后,必須人工介入手動恢復,那么到特殊時間段,比如公司組織全體團建或者半夜突然發生主節點宕機的問題,此時如果等待人工去處理就會很慢,這個時間是我們不允許的,并且我們還需要招聘專職的人來負責數據恢復的事,同時招聘的人還需要懂得相關的技術才能勝任這份工作。既然如此的麻煩,那有沒有簡單一點的解決方案,這個時候我們就需要用到 Redis 的哨兵模式了。
Redis 哨兵模式就是用來監視 Redis 主從服務器的,當 Redis 的主從服務器發生故障之后,Redis 哨兵提供了自動容災修復的功能,如下圖所示:
Redis 哨兵模塊存儲在 Redis 的 src/redis-sentinel 目錄下,如下圖所示:
我們可以使用命令“./src/redis-sentinel sentinel.conf”來啟動哨兵功能。
有了哨兵功能之后,就再也不怕 Redis 主從服務器宕機了。哨兵的工作原理是每個哨兵會以每秒鐘 1 次的頻率,向已知的主服務器和從服務器,發送一個 PING 命令。如果最后一次有效回復 PING 命令的時間,超過了配置的最大下線時間(Down-After-Milliseconds)時,默認是 30s,那么這個實例會被哨兵標記為主觀下線。
如果一個主服務器被標記為主觀下線,那么正在監視這個主服務器的所有哨兵節點,要以每秒 1 次的頻率確認主服務器是否進入了主觀下線的狀態。如果有足夠數量(quorum 配置值)的哨兵證實該主服務器為主觀下線,那么這個主服務器被標記為客觀下線。此時所有的哨兵會按照規則(協商)自動選出新的主節點服務器,并自動完成主服務器的自動切換功能,而整個過程都是無須人工干預的。
4.Redis 集群
Redis 集群也就是 Redis Cluster,它是 Redis 3.0 版本推出的 Redis 集群方案,將數據分布在不同的主服務器上,以此來降低系統對單主節點的依賴,并且可以大大提高 Redis 服務的讀寫性能。Redis 集群除了擁有主從模式 + 哨兵模式的所有功能之外,還提供了多個主從節點的集群功能,實現了真正意義上的分布式集群服務,如下圖所示:
Redis 集群可以實現數據分片服務,也就是說在 Redis 集群中有 16384 個槽位用來存儲所有的數據,當我們有 N 個主節點時,可以把 16384 個槽位平均分配到 N 臺主服務器上。當有鍵值存儲時,Redis 會使用 crc16 算法進行 hash 得到一個整數值,然后用這個整數值對 16384 進行取模來得到具體槽位,再把此鍵值存儲在對應的服務器上,讀取操作也是同樣的道理,這樣我們就實現了數據分片的功能。
小結
今天我們分享了保障 Redis 高可用的 4 種手段:數據持久化保證了數據不丟失;Redis 主從讓 Redis 從單機變成了多機。它有兩種模式:主從模式和從從模式,但當主節點出現問題時,需要人工手動恢復系統;Redis 哨兵模式用來監控 Redis 主從模式,并提供了自動容災恢復的功能。最后是 Redis 集群,除了可以提供主從和哨兵的功能之外,還提供了多個主從節點的集群功能,這樣就可以把數據均勻的存儲各個主機主節點上,實現了系統的橫向擴展,大大提高了 Redis 的并發處理能力。