Linux下 Redis集群搭建詳解(主從+哨兵)
前言
由于項目需要,搭建了一個 Redis 服務器集群,實現了主從配置和容災部署,使得主機出現故障時,可自動進行容災切換,下面就詳細講解一下如何利用 Redis 來實現。
文章重點
1、Redis 入門簡介
2、Redis 安裝部署
3、Redis 集群整體架構
4、Redis 主從配置及數據同步
5、Redis 哨兵模式搭建
一、Redis 入門簡介
Redis(Remote Dictionary Server 遠程字典服務)是一個開源的高性能key-value數據庫,它通常被稱為數據結構服務器,因為值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型,官網:https://redis.io/。
- Redis支持數據的持久化,可以將內存中的數據保存在磁盤中,重啟的時候可以再次加載進行使用。
- Redis不僅僅支持簡單的key-value類型的數據,同時還提供 list,set,zset,hash等數據結構的存儲。
- Redis支持數據的備份,即master-slave模式的數據備份。
為什么用Redis?
一個字,快!傳統的關系型數據庫如 Mysql 等已經不能適用所有的場景了,比如在高并發,訪問流量高峰等情況時,數據庫很容易崩了。Redis 運行在內存,能起到一個緩沖作用,由于內存的讀寫速度遠快于硬盤,因此 Redis 在性能上比其他基于硬盤存儲的數據庫有明顯的優勢。同時除了快之外,還可應用于集群的自動容災切換以及數據的讀寫分離,減輕高并發的壓力。
二、Redis 安裝部署
1、下載安裝包
官網下載地址:https://redis.io/download,這里我們下載目前最新版5.0.7,直接點擊下載。

或者直接使用命令下載,如下:
- wget http://download.redis.io/releases/redis-5.0.7.tar.gz
2、安裝
首先解壓安裝包,如下
- cd redis-5.0.7/
- make

tar
進入解壓文件目錄使用make命令對解壓的 redis 文件進行編譯,如下
- cd redis-5.0.7/
- make

make
編譯完成之后,可以看到解壓文件 redis-5.0.7 中會有對應的 src、conf 等文件,如下

編譯后目錄
編譯成功后,進入 src 文件夾,執行 make install 進行 Redis 安裝。
- cd src/
- make install
安裝完成后,顯示如下

install
注:如出現/bin/sh: cc: command not found錯誤,是因為沒有安裝 gcc 環境,使用命令yum install gcc安裝 gcc 環境即可。
3、部署
由于 src 下文件非常多,我們可以將幾個常用的命令和 conf 配置文件復制出來進行統一管理,如下:(1)新建 bin 和 etc 文件夾
- cd /root/redis-5.0.7/
- mkdir etc
- mkdir bin
(2)回到安裝目錄,將redis.conf復制到 ect 文件夾下
- cp redis.conf /root/redis-5.0.7/etc
(3)進入 src 文件夾下,將mkreleasehdr.sh、redis-benchmark、redis-check-aof、redis-check-rdb、redis-cli、redis-server、redis-sentinel文件復制到 bin 文件夾
- cd src/
- cp mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-server redis-sentinel /root/redis-5.0.7/bin/
查看復制后的文件,如下

copyFile
4、啟動redis服務
切換到 bin 目錄,使用./redis-server即可啟動 redis 服務,但是這種方式沒有指明配置文件,redis 將采用默認配置,所以我們需要讓 redis 按照我們的配置文件來啟動,如下,啟動時指定剛才我們復制到 etc 文件夾下的redis.conf。
- cd /root/redis-5.0.7/bin
- ./redis-server /root/redis-5.0.7/etc/redis.conf

啟動redis服務
啟動后查看redis的進程,如下,可以看到6379端口就是我們運行的 redis 服務(配置文件中默認端口為6379)。

查看redis進程
使用redis-cli命令連接客戶端,如下

redis-cli
5、關閉redis服務
如果需要關閉redis服務,使用如下命令即可關閉。
- redis-cli -p 6379 shutdown

關閉redis服務
三、Redis 集群整體架構
這里我們采用的集群整體架構就是主從結構+哨兵(sentinel),實現容災的自動切換,如下圖所示:

redis架構(主從+哨兵)
一個主節點(master)可擁有多個從節點(slave),從節點實現對主節點的復制,保證數據同步。而哨兵(sentinel)則對各節點進行監控,主要包括主節點存活檢測、主從運行情況檢測等,一旦主節點宕機,哨兵可自動進行故障轉移 (failover)、主從切換。接下來就開始搭建這樣一個集群,首先是主從結構,然后是哨兵模式,接著往下看。
四、Redis 主從配置及數據同步
在第一步 Redis 安裝部署中我們已經啟動了 Redis 服務,但是配置文件并沒有做修改,因為主從配置主要就是通過修改配置文件來實現,所以 Redis 配置文件的修改統一在這里進行講解。
這里我創建了三臺虛擬機來演示,分別按照上述安裝方式安裝好 Redis,三臺虛擬機如下配置:
IP地址端口號角色192.168.231.1306379主機(master)192.168.231.1326380從機(slave)192.168.231.1316381從機(slave)
現在進入 etc 文件夾,使用vi redis.conf命令打開編輯 redis.conf 配置文件,如下

viconfig
首先看一下redis.conf 配置文件中的各個參數,詳解如下
- # redis進程是否以守護進程的方式運行,yes為是,no為否(不以守護進程的方式運行會占用一個終端)。
- daemonize no
- # 指定redis進程的PID文件存放位置
- pidfile /var/run/redis.pid
- # redis進程的端口號
- port 6379
- #是否開啟保護模式,默認開啟。要是配置里沒有指定bind和密碼。開啟該參數后,redis只會本地進行訪問,拒絕外部訪問。要是開啟了密碼和bind,可以開啟。否則最好關閉設置為no。
- protected-mode yes
- # 綁定的主機地址
- bind 127.0.0.1
- # 客戶端閑置多長時間后關閉連接,默認此參數為0即關閉此功能
- timeout 300
- # redis日志級別,可用的級別有debug.verbose.notice.warning
- loglevel verbose
- # log文件輸出位置,如果進程以守護進程的方式運行,此處又將輸出文件設置為stdout的話,就會將日志信息輸出到/dev/null里面去了
- logfile stdout
- # 設置數據庫的數量,默認為0可以使用select <dbid>命令在連接上指定數據庫id
- databases 16
- # 指定在多少時間內刷新次數達到多少的時候會將數據同步到數據文件
- save <seconds> <changes>
- # 指定存儲至本地數據庫時是否壓縮文件,默認為yes即啟用存儲
- rdbcompression yes
- # 指定本地數據庫文件名
- dbfilename dump.db
- # 指定本地數據問就按存放位置
- dir ./
- # 指定當本機為slave服務時,設置master服務的IP地址及端口,在redis啟動的時候他會自動跟master進行數據同步
- replicaof <masterip> <masterport>
- # 當master設置了密碼保護時,slave服務連接master的密碼
- masterauth <master-password>
- # 設置redis連接密碼,如果配置了連接密碼,客戶端在連接redis是需要通過AUTH<password>命令提供密碼,默認關閉
- requirepass footbared
- # 設置同一時間最大客戶連接數,默認無限制。redis可以同時連接的客戶端數為redis程序可以打開的最大文件描述符,如果設置 maxclients 0,表示不作限制。當客戶端連接數到達限制時,Redis會關閉新的連接并向客戶端返回 max number of clients reached 錯誤信息
- maxclients 128
- # 指定Redis最大內存限制,Redis在啟動時會把數據加載到內存中,達到最大內存后,Redis會先嘗試清除已到期或即將到期的Key。當此方法處理后,仍然到達最大內存設置,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放內存,Value會存放在swap區
- maxmemory<bytes>
- # 指定是否在每次更新操作后進行日志記錄,Redis在默認情況下是異步的把數據寫入磁盤,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。因為redis本身同步數據文件是按上面save條件來同步的,所以有的數據會在一段時間內只存在于內存中。默認為no。
- appendonly no
- # 指定跟新日志文件名默認為appendonly.aof
- appendfilename appendonly.aof
- # 指定更新日志的條件,有三個可選參數 - no:表示等操作系統進行數據緩存同步到磁盤(快),always:表示每次更新操作后手動調用fsync()將數據寫到磁盤(慢,安全), everysec:表示每秒同步一次(折衷,默認值);
- appendfsync everysec
1、主機配置
主機(192.168.231.130)需要改動的配置如下所示,修改完畢后先按 esc ,然后:wq命令保存退出。
- bind:0.0.0.0
- port:6379
- protected-mode:no
- daemonize:yes
- logfile:./redis.log
- requirepass:pwdtest@2019
- masterauth:pwdtest@2019
- replicaof 192.168.231.130 6379
- bind:0.0.0.0
Redis 默認只允許本機訪問,把 bind 修改為 0.0.0.0 表示允許所有遠程訪問。如果想指定限制訪問,可設置對應的 ip。
- port:6379
監聽端口默認為6379,想改其他也行。
- protected-mode:no
關閉保護模式,可以外部訪問。
- daemonize:yes
設置為后臺啟動。
- logfile:./redis.log
redis 日志文件,生成后在 bin 目錄下可找到。
- requirepass:pwdtest@2019
設置 redis 連接密碼。
- masterauth:pwdtest@2019
slave 服務連接 master 的密碼。
2、從機配置
從機的配置和主機相似,相同的地方我就不再詳解,不同的地方是需要使用replicaof指定主機(master)的IP地址和端口,需要注意的是老版本使用的是 slaveof,目前我使用的5.0.7版本要使用 replicaof ,如下。
- bind:0.0.0.0
- port:6379
- protected-mode:no
- daemonize:yes
- logfile:./redis.log
- requirepass:pwdtest@2019
- masterauth:pwdtest@2019
- replicaof 192.168.231.130 6379
- replicaof 192.168.231.130 6379
指定當本機為 slave 服務時,設置 master 服務的IP地址及端口,在 redis 啟動的時候會自動跟 master 進行數據同步,所以兩臺從機都這樣配置即可。
注:由于我們搭建的集群需要自動容災切換,主數據庫可能會變成從數據庫,所以三臺機器上都需要同時設置 requirepass 和 masterauth 配置項。
3、數據同步
上面我們主從節點的配置文件配置好后,重啟 redis 服務,進入 bin 目錄即可查看配置文件中指定的redis.log日志文件。

查看log
下面我們需要設置一下防火墻,否則主從機之間無法同步數據,命令如下,這里根據自己設置的端口進行更改。
- firewall-cmd --add-port=6379/tcp --permanent --zone=public
- #重啟防火墻(修改配置后要重啟防火墻)
- firewall-cmd --reload
至此主從結構搭建完畢,不出意外主從機已經可以數據同步,下面我們分別查看三臺機器的信息,如下
- 192.168.231.130 6379(主)
info_6379.png
可以看到當前角色為主機(master),并且連接了另外兩臺從機(slave)。
- 192.168.231.132 6380(從)
info_6380.png
可以看到當前角色為從機(slave),并指明了主機地址192.168.231.130和端口6379。
- 192.168.231.131 6381(從)
info_6381.png
可以看到當前角色為從機(slave),并指明了主機地址192.168.231.130和端口6379。
4、主從驗證
接下來我們在主機(master)添加幾條數據,看從機(slave)是否可以獲取到,如果能獲取,說明數據已經同步到了從機,主機添加數據,如下:

6379set
兩臺從機已經獲取到數據,證明主從搭建成功并可同步數據,如下所示:

6380get

6381get
五、Redis 哨兵模式搭建
1、哨兵模式詳解
Redis Sentinel是Redis 的高可用性解決方案,由一個或多個Sentinel(哨兵)實例組成。它可以監視任意多個主服務器,以及這些主服務器屬下的所有從服務器,并在被監視的主服務器進入下線狀態時,自動將下線主服務器屬下的某個從服務器升級為新的主服務器,它的主要功能如下:
- 監控(Monitoring):Sentinel會不斷地檢查你的主服務器和從服務器是否運作正常。
- 通知(Notification):當被監控的某個 Redis 服務器出現問題時, Sentinel可以通過API向管理員或者其他應用程序發送通知。
- 故障遷移:當主服務器不能正常工作時,Sentinel會自動進行故障遷移,也就是主從切換。
- 統一的配置管理:連接者詢問sentinel取得主從的地址。
哨兵原理
Sentinel 使用的算法核心是 Raft 算法,主要用途就是用于分布式系統,系統容錯,以及Leader選舉,每個Sentinel都需要定期的執行以下任務:
- 每個 Sentinel 會自動發現其他 Sentinel 和從服務器,它以每秒鐘一次的頻率向它所知的主服務器、從服務器以及其他 Sentinel 實例發送一個 PING 命令。
- 如果一個實例(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 那么這個實例會被 Sentinel 標記為主觀下線。 有效回復可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。
- 如果一個主服務器被標記為主觀下線, 那么正在監視這個主服務器的所有Sentinel要以每秒一次的頻率確認主服務器的確進入了主觀下線狀態。
- 如果一個主服務器被標記為主觀下線, 并且有足夠數量的Sentinel(至少要達到配置文件指定的數量)在指定的時間范圍內同意這一判斷, 那么這個主服務器被標記為客觀下線。
- 在一般情況下, 每個Sentinel會以每 10 秒一次的頻率向它已知的所有主服務器和從服務器發送 INFO 命令。 當一個主服務器被Sentinel標記為客觀下線時,Sentinel向下線主服務器的所有從服務器發送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
- 當沒有足夠數量的Sentinel同意主服務器已經下線, 主服務器的客觀下線狀態就會被移除。 當主服務器重新向Sentinel的 PING 命令返回有效回復時, 主服務器的主管下線狀態就會被移除。

哨兵原理
配置文件詳解
哨兵的配置主要就是修改sentinel.conf配置文件中的參數,在Redis安裝目錄即可看到此配置文件,各參數詳解如下:
- # 哨兵sentinel實例運行的端口,默認26379
- port 26379
- # 哨兵sentinel的工作目錄
- dir ./
- # 是否開啟保護模式,默認開啟。
- protected-mode:no
- # 是否設置為后臺啟動。
- daemonize:yes
- # 哨兵sentinel的日志文件
- logfile:./sentinel.log
- # 哨兵sentinel監控的redis主節點的
- ## ip:主機ip地址
- ## port:哨兵端口號
- ## master-name:可以自己命名的主節點名字(只能由字母A-z、數字0-9 、這三個字符".-_"組成。)
- ## quorum:當這些quorum個數sentinel哨兵認為master主節點失聯 那么這時 客觀上認為主節點失聯了
- # sentinel monitor <master-name> <ip> <redis-port> <quorum>
- sentinel monitor mymaster 127.0.0.1 6379 2
- # 當在Redis實例中開啟了requirepass,所有連接Redis實例的客戶端都要提供密碼。
- # sentinel auth-pass <master-name> <password>
- sentinel auth-pass mymaster 123456
- # 指定主節點應答哨兵sentinel的最大時間間隔,超過這個時間,哨兵主觀上認為主節點下線,默認30秒
- # sentinel down-after-milliseconds <master-name> <milliseconds>
- sentinel down-after-milliseconds mymaster 30000
- # 指定了在發生failover主備切換時,最多可以有多少個slave同時對新的master進行同步。這個數字越小,完成failover所需的時間就越長;反之,但是如果這個數字越大,就意味著越多的slave因為replication而不可用。可以通過將這個值設為1,來保證每次只有一個slave,處于不能處理命令請求的狀態。
- # sentinel parallel-syncs <master-name> <numslaves>
- sentinel parallel-syncs mymaster 1
- # 故障轉移的超時時間failover-timeout,默認三分鐘,可以用在以下這些方面:
- ## 1. 同一個sentinel對同一個master兩次failover之間的間隔時間。
- ## 2. 當一個slave從一個錯誤的master那里同步數據時開始,直到slave被糾正為從正確的master那里同步數據時結束。
- ## 3. 當想要取消一個正在進行的failover時所需要的時間。
- ## 4.當進行failover時,配置所有slaves指向新的master所需的最大時間。不過,即使過了這個超時,slaves依然會被正確配置為指向master,但是就不按parallel-syncs所配置的規則來同步數據了
- # sentinel failover-timeout <master-name> <milliseconds>
- sentinel failover-timeout mymaster 180000
- # 當sentinel有任何警告級別的事件發生時(比如說redis實例的主觀失效和客觀失效等等),將會去調用這個腳本。一個腳本的最大執行時間為60s,如果超過這個時間,腳本將會被一個SIGKILL信號終止,之后重新執行。
- # 對于腳本的運行結果有以下規則:
- ## 1. 若腳本執行后返回1,那么該腳本稍后將會被再次執行,重復次數目前默認為10。
- ## 2. 若腳本執行后返回2,或者比2更高的一個返回值,腳本將不會重復執行。
- ## 3. 如果腳本在執行過程中由于收到系統中斷信號被終止了,則同返回值為1時的行為相同。
- # sentinel notification-script <master-name> <script-path>
- sentinel notification-script mymaster /var/redis/notify.sh
- # 這個腳本應該是通用的,能被多次調用,不是針對性的。
- # sentinel client-reconfig-script <master-name> <script-path>
- sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
2、哨兵搭建
這里我們部署三個哨兵,每臺服務器一個哨兵,配置方式相同,如下
(1)同樣為了方便管理,首先將sentinel.conf復制到 etc 下
- cd /data/redis-5.0.7/
- cp sentinel.conf /data/redis-5.0.7/etc/
(2)編輯 sentinel.conf
- cd etc/
- vi sentinel.conf
配置文件修改如下,修改完畢后先按 esc ,然后:wq命令保存退出。
- //端口默認為26379。
- port:26379
- //關閉保護模式,可以外部訪問。
- protected-mode:no
- //設置為后臺啟動。
- daemonize:yes
- //日志文件。
- logfile:./sentinel.log
- //指定主機IP地址和端口,并且指定當有2臺哨兵認為主機掛了,則對主機進行容災切換。
- sentinel monitor mymaster 192.168.231.130 6379 2
- //當在Redis實例中開啟了requirepass,這里就需要提供密碼。
- sentinel auth-pass mymaster pwdtest@2019
- //這里設置了主機多少秒無響應,則認為掛了。
- sentinel down-after-milliseconds mymaster 3000
- //主備切換時,最多有多少個slave同時對新的master進行同步,這里設置為默認的1。
- snetinel parallel-syncs mymaster 1
- //故障轉移的超時時間,這里設置為三分鐘。
- sentinel failover-timeout mymaster 180000
3、防火墻設置
命令如下,這里根據自己設置的端口進行更改。
- firewall-cmd --add-port=26379/tcp --permanent --zone=public
- #重啟防火墻(修改配置后要重啟防火墻)
- firewall-cmd --reload
4、啟動三個哨兵:
- cd /data/redis-5.0.7/bin
- redis-sentinel /data/redis-5.0.7/etc/sentinel.conf
三個哨兵都啟動后,可使用如下命令查看哨兵信息
- redis-cli -p 26379
- info sentinel

info_sentinel.
可以看到,哨兵已經監聽到當前的主機IP端口和運行狀態,并且有2臺從機,3個哨兵。
5、容災切換
現在我們模擬主機宕機,將主機 redis 服務關閉,如下

模擬宕機
現在我們去看三臺服務器的情況,發現剛才的主機(192.168.231.130 6379)已經變成了從機,并且哨兵(Sentinel)通過選舉機制選舉了從機(192.168.231.131 6381)作為了新的主機,如下

容災切換
進入192.168.231.131 6381 可以看到它已經由從機(slave)變為了主機(master),并且成功連接從機。

newMaster
需要注意的是,主從切換后配置文件已經被自動進行了更改,我們現在看一下新上位的主機 redis 日志,如下

容災后redis日志
可以看到,當主機掛了的時候,一直連接主機被拒絕,當哨兵選舉它為主機后,它成功執行重寫的配置文件,并且連接了其他從機。
至此,主從+哨兵的集群架構搭建完畢。
結語
為了寫這篇文章,熬了好幾個夜,覺得有幫助點贊轉發吧。最后感興趣的可以關注下我的公眾號(公眾號搜索chaodev),來吧英雄。