Redis 分佈式高可用終極指南

最近項目上需要用到 redis 高可用方案,遂上網找了一些資料學習,但是網上關於 redis 高可用的幾種實現方式或口徑不一,或含糊不清,或缺斤少兩。經歷了多方資料學習和實際驗證,本文試圖將 redis 分佈式和集羣方案從概念理解到技術選型到搭建使的整個過程用最簡單的語言講述清楚。

分佈式與集羣

下文會涉及到大量的分佈式和集羣術語,這裏我們先來複習一下集羣和分佈式的概念,加深一下理解。

目前的項目很少會採用單機架構了,一是因爲單機性能有限,二是因爲單機服務一旦故障整個系統就無法繼續提供服務了。所以目前集羣和分佈式的架構使用得很廣泛,主要就是爲了解決上述兩個問題,一個性能問題,一個故障問題,通過分佈式架構解決性能(高併發)問題,通過集羣架構解決故障服務(高可用)問題。

分佈式架構

分佈式:一個業務分拆多個子業務,部署在不同的服務器上

網上很多文章把分佈式架構說得很複雜,但都沒有切中關鍵,其實理解起來很簡單,所有的計算機系統都是爲業務服務的,將同一個業務拆分成多個子業務,各個子業務部署在不同的服務器上,這就是分佈式架構,通過將業務拆細,爲不同的子業務配置不同性能的服務器,提高整個系統的性能。我個人認爲目前很火的微服務概念其實本質上就是分佈式。

按照類型大致可以分爲兩種:分佈式計算分佈式存儲

分佈式計算很好理解,就是將大量計算任務分配到多個計算單元上以提高總計算性能。例如暴力破解某個密碼需要遍歷某個字符組合10萬次,假設一臺計算機需要10分鐘,那麼10臺計算機同時遍歷,每臺遍歷1萬次,最後將結果彙總,那麼就只需要1分鐘。這10臺計算機組合起來就是一個分佈式計算系統,這裏的業務就是計算。

同理,分佈式儲存也很好理解,就是將大量數據分配到多個儲存單元上以提高總存儲量。例如100ZB的數據一個儲存單元放不下,那就拆成100份,每個儲存單元存1份,那麼這100個存儲單元組合起來就是一個分佈式儲存系統,這裏的業務就是存儲。目前主流的關係型數據庫都有比較成熟的分佈式存儲方案,如 MySQL 的 MySQL Fabric、MyCat 等,Oracle Database 有Oracle Sharding 等。Redis 作爲流行的非關係型數據庫,由於是內存數據庫,理論上一般不會在 Redis 中存放太多的數據,但是在某些特殊情況下還是會有儲存空間不夠的情況,或者需要預防儲存空間不夠的情況發生,這個時候就需要 Redis 分佈式架構了。

例如某集團下有很多的子公司,每個子公司都有多套 IT 系統,其中很多 IT 系統都是需要使用 Redis 的,集團爲了統一管理,搭建了一套中央 Redis 系統,要求所有子公司下的 IT 系統統一使用集團的中央 Redis 庫,這個時候即使當前儲存容量夠用,但是爲了應對後期發展就必須使用到分佈式儲存,因爲分佈式架構理論上都支持無限水平拓展。

集羣架構

集羣:同一個業務,部署在多個服務器上

集羣同樣也非常好理解,就是在多個服務器上部署同一個業務,這樣可以起到兩個作用:

  1. 分散每臺服務器的壓力
  2. 任意一臺或者幾臺服務器宕機也不會影響整個系統

例如一個典型的 Web 集羣服務架構圖如下:

一個典型的 Web 集羣架構圖

這裏三個 Web Server 服務器實際上都是運行着同一套業務,但是三臺服務器就可以顯著分散單臺服務器壓力,並且任意一臺宕機也不會導致無法提供服務。

分佈式與集羣的關係

分佈式和集羣區別很好理解,用下面一張圖表示:

分佈式與集羣的區別

需要注意的是分佈式不一定能用上,但是集羣一般都是需要的。因爲不是所有系統都需要應對高併發場景,但高可用是一個系統能夠長期穩定運行基本保障。因此用到分佈式架構的系統基本上都會用到集羣,而用集羣架構的系統卻不一定會用到分佈式。

Redis 部署指南

單節點方案:Redis Standalone

原理簡介

這是最簡單的 redis 部署方案,所有數據存儲和讀寫操作都在同一個 redis 服務上。

這種方式優點很明顯:部署簡單,無論是部署成本還是運維成本都很低,本地測試時最常見也是最方便的方式。

但同時缺點也很明顯:不能實現高可用,也不能應對高併發場景,也無法輕易水平拓展,數據儲存量很容易見頂。

部署實例

單節點模式的部署是最簡單的,一下是 Linux 系統下部署單節點 redis 的方法:

 

# 下載 Redis 二進制安裝包:
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
# 解壓二進制包
tar –zxvf redis-5.0.4.tar.gz
# 進入解壓文件夾並編譯二進制文件
cd redis-5.0.4
make
# 安裝
cd src
make test
make install

在 make install 和 make test 的時候可能會遇到下面這個問題:

 

You need tcl 8.5 or newer in order to run the Redis test
make: *** [test] Error 1

這是因爲系統中的 TCL 語言版本太低,TCL 語言是一種工具腳本語言,在安裝 Redis 的過程中 make test 命令需要用到這個腳本語言,這個時候我們需要升級一下系統中的 TCL 版本:

 

# 下載一個高於 8.5 版本的 TCL 安裝包,比如 8.6.8
wget http://downloads.sourceforge.net/tcl/tcl8.6.8-src.tar.gz
# 解壓
tar -zxvf tcl8.6.8-src.tar.gz  -C /usr/local/  
# 切換到解壓後的源碼目錄
cd  /usr/local/tcl8.6.8/unix/
# 編譯和安裝
sudo ./configure  
sudo make  
sudo make install

升級 TCL 到 8.5 版本以後,繼續執行之前報錯的語句,完成 Redis 的安裝,安裝完成後用 redis-server -v 驗證安裝是否成功,若成功輸出如下版本信息則代表安裝成功:

 

Redis server v=5.0.4

安裝成功就可以直接運行了,但是默認配置下是不支持後臺運行的,觀點命令窗口就會結束 redis 進程,這顯然是不行的。所以我們再簡單改一下 redis 的配置,讓其能夠直接後臺運行。

 

# 進入到 redis 的安裝目錄,編輯 redis.conf
vim /usr/redis/redis-5.0.4/redis.conf
# 將 daemonize no 修改成 daemonize yes (使 redis 服務可以在後臺運行)

# 在指定配置下運行redis服務
/usr/local/bin/redis-server /usr/redis/redis-5.0.4/redis.conf 
# 查看redis運行情況
ps -ef | grep redis

# 輸出
app   21794   1  0 Jan28 ?  03:31:25 ./redis-server *:6379

可以看到 redis 在默認的 6379 端口下運行,配置文件中還有一些可以調整的地方,這裏就不一一列舉了。

那麼單節點模式 redis 服務就部署完成了

Redis 高可用方案:Redis Sentinel

原理簡介

Redis Sentinel 是 Redis 官方推薦的高可用性(HA)解決方案,這是生產環境中最實用也是最常用的方案。

這裏涉及到另一個概念:master-slaver(主從模式)。很好理解,就是常用的主備模式,例如 nginx 的主備模式。一個主 redis 節點可以配置多個從節點,當主節點掛掉時,從節點自動頂上代替主節點,這樣就可以有效的避免一個節點掛掉導致整個系統掛掉的問題,實現 redis 服務的高可用。如下圖:

master-slaver

但是這個方案需要解決兩個基本問題:

  1. 如何提前判斷各個節點(尤其是主節點)的運行健康狀況?
  2. 當主節點宕機的時候如何從多個從節點中選出一個作爲新的主節點並實現自動切換?

這時 Redis Sentinel 應運而生,它主要有以下三個特點:

  • 監控(Monitoring):Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
  • 提醒(Notification):當被監控的某個 Redis 服務器出現問題時,Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
  • 自動故障遷移(Automatic failover):當一個主服務器不能正常工作時,Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級爲新的主服務器,並讓失效主服務器的其他從服務器改爲複製新的主服務器; 當客戶端試圖連接失效的主服務器時, 集羣也會向客戶端返回新主服務器的地址,使得集羣可以使用新主服務器代替失效服務器。

總結來說就是 sentinel 可以監控一個或者多個 master-slaver 集羣,定時對每個節點進行健康檢查,可以通過 API 發送通知,並自動進行故障轉移。這時r redis 結構就變成了

使用了 redis sentinel 之後客戶端不再直接連接 redis 節點獲取服務,而是使用 sentinel 代理獲取 redis 服務,類似 Nginx 的代理模式。那麼這裏又有一個新問題,就是如果 sentinel 宕機了,那麼客戶端就找不到 redis 服務了,所以 sentinel 本身也是需要支持高可用。

好在sentinel 本身也支持集羣部署,並且各個 sentinel 之間支持自動監控,如此一來 redis 主從服務和 sentinel 服務都可以支持高可用。預期結構如下:

redis sentinel集羣

部署實例

master-slaver 一主二從

那麼下面我們就來實操一下,以下過程大部分參考 redis 官方 Redis Sentinel 文檔

安裝 redis 就不重複了,和單機 redis 一樣。

redis 解壓後,redis home 目錄下有 redis 配置的樣例文件,我們不直接在此文件上就行修改,在redis home目錄下新建文件夾 master-slave ,將配置文件都放於此目錄下,下面是三個 redis 節點配置的關鍵部分

  • master 配置文件:redis-6379.conf

    port 6379
    daemonize yes
    logfile "6379.log"
    dbfilename "dump-6379.rdb"
    dir "/opt/soft/redis/data"
    
  • slave-1 配置文件:redis-6380.conf

    port 6380
    daemonize yes
    logfile "6380.log"
    dbfilename "dump-6380.rdb"
    dir "/opt/soft/redis/data"
    # 關鍵配置:將這個 redis 指定爲某個第一個 redis 的 slaver
    slaveof 127.0.0.1 6379
    
  • slave-2 配置文件:redis-6381.conf

    port 6381
    daemonize yes
    logfile "6381.log"
    dbfilename "dump-6381.rdb"
    dir "/opt/soft/redis/data"
    # 關鍵配置:將這個 redis 指定爲某個第一個 redis 的 slaver
    slaveof 127.0.0.1 6379
    

分別啓動這三個 redis 服務,啓動過程就不羅嗦了,和分別啓動三個單機 redis 是一樣的,分別指定三個配置文件即可。啓動後如下圖所示:

image

6379、6380、6381 端口分別在運行一個 redis-server。

接下來查看這三個 redis-server 之間的關係:連接到主 redis 上用 info replication即可查看

image

可以看到當前連接的 redis 服務爲 master 角色,下面有兩個 slaver,IP 和端口都能看到。

這樣我們就順利的完成了 一主二從 redis 環境的搭建,下面開始搭建 sentinel 集羣。

sentinel 集羣

sentinel 本質上是一個特殊的 redis,大部分配置和普通的 redis 沒有什麼區別,主要區別在於端口和其哨兵監控設置,下面是三個典型的 sentinel 配置文件中的關鍵內容:

  • sentinel-26379.conf

 

#設置 sentinel 工作端口
port 26379
#後臺運行 
daemonize yes
#日誌文件名稱
logfile "26379.log"
#設置當前 sentinel 監控的 redis ip 和 端口
sentinel monitor mymaster 127.0.0.1 6379 2
#設置判斷 redis 節點宕機時間
sentinel down-after-milliseconds mymaster 60000
#設置自動故障轉移超時
sentinel failover-timeout mymaster 180000
#設置同時故障轉移個數
sentinel parallel-syncs mymaster 1
  • sentinel-26380.conf

 

#設置 sentinel 工作端口
port 26380
#後臺運行 
daemonize yes
#日誌文件名稱
logfile "26380.log"
#設置當前 sentinel 監控的 redis ip 和 端口
sentinel monitor mymaster 127.0.0.1 6379 2
#設置判斷 redis 節點宕機時間
sentinel down-after-milliseconds mymaster 60000
#設置自動故障轉移超時
sentinel failover-timeout mymaster 180000
#設置同時故障轉移個數
sentinel parallel-syncs mymaster 1
  • sentinel-26381.conf

    #設置 sentinel 工作端口
    port 26391
    #後臺運行 
    daemonize yes
    #日誌文件名稱
    logfile "26381.log"
    #設置當前 sentinel 監控的 redis ip 和 端口
    sentinel monitor mymaster 127.0.0.1 6379 2
    #設置判斷 redis 節點宕機時間
    sentinel down-after-milliseconds mymaster 60000
    #設置自動故障轉移超時
    sentinel failover-timeout mymaster 180000
    #設置同時故障轉移個數
    sentinel parallel-syncs mymaster 1
    

針對幾個監控設置的配置做一下詳細說明:

  • sentinel monitor [master-group-name] [ip] [port] [quorum]

    這個命令中【master-group-name】是 master redis 的名稱;【ip】和【port】分別是其 ip 和端口,很好理解。最後一個參數【quorum】是”投票數“

    舉個栗子,redis 集羣中有3個 sentinel 實例,其中 master 掛掉了,如果這裏的票數是2,表示有2個 sentinel 認爲 master 掛掉啦,才能被認爲是正真的掛掉啦。其中 sentinel 集羣中各個 sentinel 之間通過 gossip 協議互相通信。
    具體怎樣投票還涉及到 redis 集羣中的【主觀下線】和【客觀下線】的概念,後面再詳細介紹。

    • down-after-milliseconds

      sentinel 會向 master 發送心跳 PING 來確認 master 是否存活,如果 master 在“一定時間範圍”內不迴應PONG 或者是回覆了一個錯誤消息,那麼這個 sentinel 會主觀地認爲這個 master 已經不可用了。而這個down-after-milliseconds 就是用來指定這個“一定時間範圍”的,單位是毫秒。

    • failover-timeout

      這個參數 redis 官方文檔中並未做詳細說明,但是很好理解,就是 sentinel 對 redis 節點進行自動故障轉移的超時設置,當 failover(故障轉移)開始後,在此時間內仍然沒有觸發任何 failover 操作,當前sentinel 將會認爲此次故障轉移失敗。

    • parallel-syncs

      當新master產生時,同時進行 slaveof 到新 master 並進行同步複製的 slave 個數,也就是同時幾個 slave 進行同步。因爲在 salve 執行 salveof 與新 master 同步時,將會終止客戶端請求,因此這個值需要權衡。此值較大,意味着“集羣”終止客戶端請求的時間總和和較大,此值較小,意味着“集羣”在故障轉移期間,多個 salve 向客戶端提供服務時仍然使用舊數據。

      我們配置三個 sentinel 幾點組成一個 sentinel 集羣,端口分別是 23679,23680,23681

然後就可以啓動 sentinel 集羣了

啓動 sentinel 有兩種方式:

  1. redis-sentinel /path/to/sentinel.conf
  2. redis-server /path/to/sentinel.conf --sentinel

這兩種啓動方式沒有區別,按照順序分別啓動三個 sentinel 節點之後,我們任意連接其中的一個 sentinel 節點查看集羣關係,如下圖:

 

image

我們連接 26379 這個端口的 sentinel,用 info sentinel命令可以看到這個 sentinel 監控的 master redis 服務的 ip,端口,以及 maste 的 slaver 節點數量,以及 sentinel 的數量。

再連接 26380 這個節點試試:

image

可以看到結果和上面一樣。

如此,我們的 sentinel 集羣也部署完成了

那麼,當前這個 redis sentinel 高可用集羣的做種拓撲圖如下:

image

高可用故障測試

下面我們來測試一下這個高可用方案的實際能力。

我們手動把一主二從中的主節點 kill 掉:

image

然後連接 6380 節點,查看集羣狀態:

 

image

可以看到 6380 節點已經自動升級爲了 master 節點,還有 6381 這一個 slaver 節點,自動故障轉移成功

我們再手動啓動 6379 節點,觀察集羣狀態:

image

如圖,6379節點重新啓動後,自動變成了 6380 節點的從節點。

如此一套完整的 redis 高可用方案就部署完成了。

Redis 主觀下線和客觀下線

前面說過, Redis 的 Sentinel 中關於下線(down)有兩個不同的概念:

  • 主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個 Sentinel 實例對服務器做出的下線判斷。
  • 客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 實例在對同一個服務器做出 SDOWN 判斷, 並且通過 SENTINEL is-master-down-by-addr 命令互相交流之後, 得出的服務器下線判斷。 (一個 Sentinel 可以通過向另一個 Sentinel 發送 SENTINEL is-master-down-by-addr 命令來詢問對方是否認爲給定的服務器已下線)

如果一個服務器沒有在 master-down-after-milliseconds 選項所指定的時間內, 對向它發送 PING 命令的 Sentinel 返回一個有效回覆(valid reply), 那麼 Sentinel 就會將這個服務器標記爲主觀下線。

服務器對 PING 命令的有效回覆可以是以下三種回覆的其中一種:

  • 返回 +PONG 。
  • 返回 -LOADING 錯誤。
  • 返回 -MASTERDOWN 錯誤。

如果服務器返回除以上三種回覆之外的其他回覆, 又或者在指定時間內沒有回覆 PING 命令, 那麼 Sentinel 認爲服務器返回的回覆無效(non-valid)。

注意, 一個服務器必須在 master-down-after-milliseconds 毫秒內, 一直返回無效回覆纔會被 Sentinel 標記爲主觀下線。

舉個栗子, 如果 master-down-after-milliseconds 選項的值爲 30000 毫秒(30 秒), 那麼只要服務器能在每 29 秒之內返回至少一次有效回覆, 這個服務器就仍然會被認爲是處於正常狀態的。

從主觀下線狀態切換到客觀下線狀態並沒有使用嚴格的法定人數算法(strong quorum algorithm), 而是使用了流言協議: 如果 Sentinel 在給定的時間範圍內, 從其他 Sentinel 那裏接收到了足夠數量的主服務器下線報告, 那麼 Sentinel 就會將主服務器的狀態從主觀下線改變爲客觀下線。 如果之後其他 Sentinel 不再報告主服務器已下線, 那麼客觀下線狀態就會被移除。

有一點需要注意的是:客觀下線條件只適用於主服務器: 對於任何其他類型的 Redis 實例, Sentinel 在將它們判斷爲下線前不需要進行協商, 所以從服務器或者其他 Sentinel 永遠不會達到客觀下線條件。

只要一個 Sentinel 發現某個主服務器進入了客觀下線狀態, 這個 Sentinel 就可能會被其他 Sentinel 推選出, 並對失效的主服務器執行自動故障遷移操作。

Redis 分佈式高可用方案:Redis Cluster

原理簡介

作爲一個內存數據庫,實現高可用是一個基本保障,當儲存服務在可預見的將來需要做存儲拓展時,分佈式儲存就是一個必須要考慮到的事情。例如部署一箇中央 redis 儲存服務,提供給集團下所有的子公司所有需要的系統使用,並且系統數量在不斷的增加,此時在部署服務的時候,分佈式儲存結構幾乎是必然的選擇。

Redis 3.0 版本之前,可以通過前面說所的 Redis Sentinel(哨兵)來實現高可用 ( HA ),從 3.0 版本之後,官方推出了Redis Cluster,它的主要用途是實現數據分片(Data Sharding),同時提供了完整的 sharding、replication(複製機制仍使用原有機制,並且具備感知主備的能力)、failover 解決方案,稱爲 Redis Cluster,同樣可以實現 HA,是官方當前推薦的方案。

在 Redis Sentinel 模式中,每個節點需要保存全量數據,冗餘比較多,而在Redis Cluster 模式中,每個分片只需要保存一部分的數據,對於內存數據庫來說,還是要儘量的減少冗餘。在數據量太大的情況下,故障恢復需要較長時間,另外,內存的價格也是非常高昂的。

Redis Cluste r的具體實現細節是採用了 Hash 槽的概念,集羣會預先分配16384個槽(slot),並將這些槽分配給具體的服務節點,通過對 Key 進行 CRC16(key)%16384 運算得到對應的槽是哪一個,從而將讀寫操作轉發到該槽所對應的服務節點。當有新的節點加入或者移除的時候,再來遷移這些槽以及其對應的數據。在這種設計之下,我們就可以很方便的進行動態擴容或縮容。

當然,關於高可用的實現方案,也可以將 Redis-Sentinel 和 Redis-Cluster 兩種模式結合起來使用,不過比較複雜,並不太推薦。

下圖展示了 Redis Cluster 分配 key 和 slot 的基本原理:

redis cluster原理圖

一個典型的 Redis Cluster 分佈式集羣由多個Redis節點組成。不同的節點組服務的數據無交集,每個節點對應數據 sharding 的一個分片。節點組內部分爲主備 2 類,對應前面敘述的 master 和 slave。兩者數據準實時一致,通過異步化的主備複製機制保證。一個節點組有且僅有一個 master,同時有0到多個 slave。只有 master 對外提供寫服務,讀服務可由 master/slave 提供。如下所示:

Redis Cluster 拓撲結構

上圖中,key-value 全集被分成了 5 份,5個 slot(實際上Redis Cluster有 16384 [0-16383] 個slot,每個節點服務一段區間的slot,這裏面僅僅舉例)。A和B爲master節點,對外提供寫服務。分別負責 1/2/3 和 4/5 的slot。A/A1 和B/B1/B2 之間通過主備複製的方式同步數據。

上述的5個節點,兩兩通過 Redis Cluster Bus 交互,相互交換如下的信息:

1、數據分片(slot)和節點的對應關係;

2、集羣中每個節點可用狀態;

3、集羣結構發生變更時,通過一定的協議對配置信息達成一致。數據分片的遷移、主備切換、單點 master 的發現和其發生主備關係變更等,都會導致集羣結構變化。

4、publish/subscribe(發佈訂閱)功能,在Cluster版內部實現所需要交互的信息。

Redis Cluster Bus 通過單獨的端口進行連接,由於Bus是節點間的內部通信機制,交互的是字節序列化信息。相對 Client 的字符序列化來說,效率較高。

Redis Cluster是一個去中心化的分佈式實現方案,客戶端和集羣中任一節點連接,然後通過後面的交互流程,逐漸的得到全局的數據分片映射關係。

更多更詳細的 redis cluster 的說明請移步Redis Cluster 官方文檔

部署實例

Redis Cluster 集羣至少需要三個 master 節點,本文將以單機多實例的方式部署3個主節點及3個從節點,6個節點實例分別使用不同的端口及工作目錄

安裝 redis 同上,不贅述。

  1. 爲每個 redis 節點分別創建工作目錄

    在redis安裝目錄 /usr/local/redis-5.0.2 下新建目錄 redis-cluster,並在該目錄下再新建6個子目錄,7000,7001,8000,8001,9000,9001,此時目錄結構如下圖所示:

image

  1. 修改配置

    #開啓後臺運行
    daemonize yes
    #工作端口
    port 7000
    #綁定機器的內網IP或者公網IP,一定要設置,不要用 127.0.0.1
    bind 172.27.0.8  
    #指定工作目錄,rdb,aof持久化文件將會放在該目錄下,不同實例一定要配置不同的工作目錄
    dir /usr/local/redis-cluster/7000/
    #啓用集羣模式
    cluster-enabled yes 
    #生成的集羣配置文件名稱,集羣搭建成功後會自動生成,在工作目錄下
    cluster-config-file nodes-7000.conf 
    #節點宕機發現時間,可以理解爲主節點宕機後從節點升級爲主節點時間
    cluster-node-timeout 5000 
    #開啓AOF模式
    appendonly yes 
    #pid file所在目錄
    pidfile /var/run/redis_8001.pid 
    
  2. 按照上面的樣例將配置文件複製到另外5個目錄下,並對 port、dir、cluster-config-file 三個屬性做對應修改,這裏就不一一列舉了。

  3. 安裝 Ruby 和 RubyGems

    由於創建 redis cluster 需要用到 redis-trib 命令,而這個命令依賴 Ruby 和 RubyGems,因此需要安裝一下。

    [root@VM_0_15_centos redis-cluster]# yum install ruby
    [root@VM_0_15_centos redis-cluster]# yum install rubygems
    [root@VM_0_15_centos redis-cluster]# gem install redis --version 3.3.3
    
  4. 分別啓動6個節點

    [root@VM_0_15_centos redis-4.0.6]# ./src/redis-server redis-cluster/7000/redis.conf
    [root@VM_0_15_centos redis-4.0.6]# ./src/redis-server redis-cluster/7001/redis.conf
    [root@VM_0_15_centos redis-4.0.6]# ./src/redis-server redis-cluster/8000/redis.conf
    [root@VM_0_15_centos redis-4.0.6]# ./src/redis-server redis-cluster/8001/redis.conf
    [root@VM_0_15_centos redis-4.0.6]# ./src/redis-server redis-cluster/9000/redis.conf
    [root@VM_0_15_centos redis-4.0.6]# ./src/redis-server redis-cluster/9001/redis.conf
    
  5. 查看服務運行狀態

    [root@VM_0_15_centos redis-4.0.6]# ps -ef | grep redis
    root     20290     1  0 18:33 ?        00:00:02 ./src/redis-server *:8001 [cluster]
    root     20295     1  0 18:33 ?        00:00:02 ./src/redis-server *:8002 [cluster]
    root     20300     1  0 18:33 ?        00:00:02 ./src/redis-server *:8003 [cluster]
    root     20305     1  0 18:33 ?        00:00:02 ./src/redis-server *:8004 [cluster]
    root     20310     1  0 18:33 ?        00:00:02 ./src/redis-server *:8005 [cluster]
    root     20312     1  0 18:33 ?        00:00:02 ./src/redis-server *:8006 [cluster]
    root     22913 15679  0 19:31 pts/2    00:00:00 grep --color=auto redis
    

    可以看到6個節點以及全部成功啓動

  6. 創建 redis cluster

    [root@VM_0_15_centos redis-4.0.6]# ./src/redis-trib.rb create --replicas 1 172.27.0.8:7000 172.27.0.8:7001 172.27.0.8:8000 172.27.0.8:8001 172.27.0.8:9000 172.27.0.8:90001
    

    創建過程中會有部分需要確認的地方,按照提示輸入即可,集羣創建完畢後觀察一下這個集羣的節點狀態

    172.27.0.8:7000> cluster nodes
    068ac2afe1ade8b69b83226453fecc2b79cd93ae 172.27.0.8:7001@17001 slave 421ebe9e0a5ac6c811935ecd9dba83ef119dec17 0 1531008204920 4 connected
    784c727c83a5952d3714ac211021f909cc4dfee4 172.27.0.8:8001@18001 slave eb5d700e2f030c02fb1f30ba4420d0b4f7170d84 0 1531008203000 5 connected
    0537099e7cc7ab595c7aad5f0c96985251b85ec0 172.27.0.8:9001@19001 slave 79262341417df0a11eaf31e72bbf3e26f5f60ebf 0 1531008204419 6 connected
    421ebe9e0a5ac6c811935ecd9dba83ef119dec17 172.27.0.8:7000@17000 myself,master - 0 1531008204000 1 connected 0-5460
    eb5d700e2f030c02fb1f30ba4420d0b4f7170d84 172.27.0.8:8000@18000 master - 0 1531008203000 2 connected 5461-10922
    79262341417df0a11eaf31e72bbf3e26f5f60ebf 172.27.0.8:9000@19000 master - 0 1531008203419 3 connected 10923-16383
    

    如上所示,一個 3主3從的 redis cluster 分佈式集羣就搭建成功了,7000、8000、9000分別是三個 master 節點,7001、8001和9001爲對應的 slaver 節點。

其實如果你並不想管這麼多配置而只是想在最快的速度內創建一個 redis cluster 用作測試或者其他用途, redis 官方在 redis 安裝目錄的 Utils 目錄下提供了一個 create-cluster 的腳本,如下圖:

image

只要執行一下這個腳本就能自動創建一個 cluster:

[圖片上傳失敗...(image-c6eea0-1554881540128)]

進入到這個目錄下,執行./create-cluster start,即可立即完成一個 三主三從的 redis-cluster 的搭建:

image

如下圖所示就是直接使用這個腳本創建的 redis cluster:

image

Tips

  1. 如果想重新創建集羣,需要登錄到每個節點,執行 flushdb,然後執行cluster reset,重啓節點;

  2. 如果要批量殺掉Redis進程,可以使用 pkill redis-server命令;

  3. 如果redis開啓了密碼認證,則需要在redis.conf中增加屬性 : masterauth yourpassword ,並且需要修改/usr/local/share/gems/gems/redis-3.3.3/lib/redis目錄下的client.rb文件,將password屬性設置爲redis.conf中的requirepass的值,不同的操作系統client.rb的位置可能不一樣,可以使用 find / -name "client.rb"全盤查找一下;

 

 DEFAULTS = {
      :url => lambda { ENV["REDIS_URL"] },
      :scheme => "redis",
      :host => "127.0.0.1",
      :port => 6379,
      :path => nil,
      :timeout => 5.0,
      :password => "yourpassword",
      :db => 0,
      :driver => nil,
      :id => nil,
      :tcp_keepalive => 0,
      :reconnect_attempts => 1,
      :inherit_socket => false
    }
  1. Redis開啓密碼認證後,在集羣操作時問題會比較多,因此在非特殊情況下不建議開啓密碼認證,可以搭配使用防火牆保證 Redis 的安全。

故障測試的方法與上面一樣,故不贅述。

總結

Redis 服務的部署方案的選型大家根據自己項目的需求部署即可,一般來說 redis sentinel 就夠用了,也是目前用得最多的模式,但是 redis 3.0 之後官方推出的 redis-cluster 雖然本質是用於實現數據分片和分佈式存儲,但是其也實現了 redis sentinel 的全部功能,有完全的 HA 能力,並且部署起來更簡單,因此成爲了官方推薦的 HA 方案。我個人也更加推薦 redis cluster 方案。



作者:小胖0_0
鏈接:https://www.jianshu.com/p/21110d3130bc
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章