Redis高可用架構(gòu)

前言

Redis是一個(gè)高性能的key-value數(shù)據(jù)庫(kù),現(xiàn)時(shí)越來(lái)越多企業(yè)與應(yīng)用使用Redis作為緩存服務(wù)器。樓主是一枚JAVA后端程序員,也算是半個(gè)運(yùn)維工程師了。在Linux服務(wù)器上搭建Redis嗤朴,怎么可以不會(huì)呢?下面樓主就帶著大家從0開(kāi)始虫溜,依次搭建:Redis單機(jī)服務(wù)器 -> Redis主從復(fù)制 ->Redis-Sentinel高可用雹姊。逐步搭建出高可用的Redis緩存服務(wù)器。

搭建Redis

1. 下載并解壓

首先從Redis官網(wǎng)下載Redis并解壓衡楞,樓主使用的版本是4.0.2吱雏。依次執(zhí)行如下命令:

cd /opt
wget http://download.redis.io/releases/redis-4.0.2.tar.gz
tar -zcvf redis-4.0.2.tar.gz

如果沒(méi)有安裝gcc依賴包,則安裝對(duì)應(yīng)依賴包

yum install -y gcc-c++ tcl

2. 編譯并安裝

下載并解壓完畢后瘾境,則對(duì)源碼包進(jìn)行編譯安裝歧杏,樓主的Redis安裝路徑為/usr/local/redis,同學(xué)們可以自行修改語(yǔ)句:make install PREFIX=你想要安裝的路徑

cd /opt/redis-4.0.2
make install PREFIX=/usr/local

復(fù)制Redis相關(guān)命令到/usr/sbin目錄下迷守,這樣就可以直接執(zhí)行這些命令犬绒,不用寫(xiě)全路徑

cd /usr/local/redis/bin
sudo cp redis-* /usr/sbin

3. 建立Redis配置文件

安裝完成之后將 Redis 配置文件拷貝到系統(tǒng)配置目錄/etc/下,redis.confRedis 的配置文件兑凿,redis.confRedis 源碼目錄凯力,port默認(rèn) 6379。

cp /usr/local/redis-4.0.2/redis.conf  /etc/

Redis配置文件主要參數(shù)解析參考

    daemonize  no               #redis進(jìn)程是否以守護(hù)進(jìn)程的方式運(yùn)行,yes為是,no為否(不以守護(hù)進(jìn)程的方式運(yùn)行會(huì)占用一個(gè)終端)
    pidfile /var/run/redis.pid  #指定redis進(jìn)程的PID文件存放位置
    port 6379                   #redis進(jìn)程的端口號(hào)
    bind 127.0.0.1              #綁定的主機(jī)地址
    timeout  300                #客戶端閑置多長(zhǎng)時(shí)間后關(guān)閉連接,默認(rèn)此參數(shù)為0即關(guān)閉此功能
    loglevel verbose            #redis日志級(jí)別,可用的級(jí)別有debug.verbose.notice.warning
    logfile stdout              #log文件輸出位置,如果進(jìn)程以守護(hù)進(jìn)程的方式運(yùn)行,此處又將輸出文件設(shè)置為stdout的話,就會(huì)將日志信息輸出到/dev/null里面去了
    databases 16                #設(shè)置數(shù)據(jù)庫(kù)的數(shù)量,默認(rèn)為0可以使用select <dbid>命令在連接上指定數(shù)據(jù)庫(kù)id
    save <seconds><changes>   #指定在多少時(shí)間內(nèi)刷新次數(shù)達(dá)到多少的時(shí)候會(huì)將數(shù)據(jù)同步到數(shù)據(jù)文件;
    rdbcompression yes          #指定存儲(chǔ)至本地?cái)?shù)據(jù)庫(kù)時(shí)是否壓縮文件,默認(rèn)為yes即啟用存儲(chǔ);
    dbfilename dump.db          #指定本地?cái)?shù)據(jù)庫(kù)文件名
    dir ./                      #指定本地?cái)?shù)據(jù)問(wèn)就按存放位置;
    slaveof <masterip><masterport>    #指定當(dāng)本機(jī)為slave服務(wù)時(shí),設(shè)置master服務(wù)的IP地址及端口,在redis啟動(dòng)的時(shí)候他會(huì)自動(dòng)跟master進(jìn)行數(shù)據(jù)同步
    masterauth <master-password>       #當(dāng)master設(shè)置了密碼保護(hù)時(shí),slave服務(wù)連接master的密碼;
    requirepass footbared       #設(shè)置redis連接密碼,如果配置了連接密碼,客戶端在連接redis是需要通過(guò)AUTH<password>命令提供密碼,默認(rèn)關(guān)閉
    maxclients 128              #設(shè)置同一時(shí)間最大客戶連接數(shù),默認(rèn)無(wú)限制;redis可以同時(shí)連接的客戶端數(shù)為redis程序可以打開(kāi)的最大文件描述符,如果設(shè)置 maxclients 0礼华,表示不作限制咐鹤。當(dāng)客戶端連接數(shù)到達(dá)限制時(shí),Redis會(huì)關(guān)閉新的連接并向客戶端返回max number of clients reached錯(cuò)誤信息
    maxmemory<bytes>           #指定Redis最大內(nèi)存限制圣絮,Redis在啟動(dòng)時(shí)會(huì)把數(shù)據(jù)加載到內(nèi)存中祈惶,達(dá)到最大內(nèi)存后,Redis會(huì)先嘗試清除已到期或即將到期的Key,當(dāng)此方法處理 后捧请,仍然到達(dá)最大內(nèi)存設(shè)置凡涩,將無(wú)法再進(jìn)行寫(xiě)入操作,但仍然可以進(jìn)行讀取操作疹蛉。Redis新的vm機(jī)制突照,會(huì)把Key存放內(nèi)存,Value會(huì)存放在swap區(qū)
    appendonly no               #指定是否在每次更新操作后進(jìn)行日志記錄氧吐,Redis在默認(rèn)情況下是異步的把數(shù)據(jù)寫(xiě)入磁盤(pán),如果不開(kāi)啟末盔,可能會(huì)在斷電時(shí)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失筑舅。因?yàn)?redis本身同步數(shù)據(jù)文件是按上面save條件來(lái)同步的,所以有的數(shù)據(jù)會(huì)在一段時(shí)間內(nèi)只存在于內(nèi)存中陨舱。默認(rèn)為no
    appendfilename appendonly.aof       #指定跟新日志文件名默認(rèn)為appendonly.aof
    appendfsync everysec         #指定更新日志的條件,有三個(gè)可選參數(shù)no:表示等操作系統(tǒng)進(jìn)行數(shù)據(jù)緩存同步到磁盤(pán)(快),always:表示每次更新操作后手動(dòng)調(diào)用fsync()將數(shù)據(jù)寫(xiě)到磁盤(pán)(慢翠拣,安全), everysec:表示每秒同步一次(折衷,默認(rèn)值);

3.1 設(shè)置后端啟動(dòng):

由于Redis默認(rèn)是前端啟動(dòng)游盲,必須保持在當(dāng)前的窗口中误墓,如果使用ctrl + c退出,那么Redis也就退出益缎,不建議使用谜慌。

    vi /etc/redis.conf

修改Redis配置文件把舊值daemonize no 改為 新值daemonize yes

3.2 設(shè)置訪問(wèn):

Redis默認(rèn)只允許本機(jī)訪問(wèn),可是有時(shí)候我們也需要 Redis 被遠(yuǎn)程訪問(wèn)莺奔。

vi /etc/redis.conf

找到 bind 那行配置欣范,默認(rèn)是: # bind 127.0.0.1

去掉#注釋并改為: bind 0.0.0.0 此設(shè)置會(huì)變成允許所有遠(yuǎn)程訪問(wèn)。如果想指定限制訪問(wèn)令哟,可設(shè)置對(duì)應(yīng)的IP恼琼。

3.3 配置Redis日志記錄:

找到logfile那行配置,默認(rèn)是:logfile ""屏富,改為logfile /var/log/redis_6379.log

3.4 設(shè)置 Redis 請(qǐng)求密碼:
vi /etc/redis.conf

找到默認(rèn)是被注釋的這一行:# requirepass foobared

去掉注釋?zhuān)?foobared 改為你想要設(shè)置的密碼晴竞,比如我打算設(shè)置為:123456,所以我改為:requirepass "123456"

修改之后重啟下服務(wù)

有了密碼之后狠半,進(jìn)入客戶端噩死,就得這樣訪問(wèn):redis-cli -h 127.0.0.1 -p 6379 -a 123456

4. Redis常用操作

4.1 啟動(dòng)
/usr/local/redis/bin/redis-server /etc/redis.conf
4.2 關(guān)閉
/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 shutdown
4.3 查看是否啟動(dòng)
    ps -ef | grep redis
4.4 進(jìn)入客戶端
    redis-cli
   
4.5 關(guān)閉客戶端
redis-cli shutdown
4.6 設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)配置
echo "/usr/local/redis/bin/redis-server /etc/redis.conf" >/etc/rc.local
4.7 開(kāi)放防火墻端口
添加規(guī)則:iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT
保存規(guī)則:service iptables save
重啟 iptables:service iptables restart

5. 將Redis注冊(cè)為系統(tǒng)服務(wù)

在/etc/init.d目錄下添加Redis服務(wù)的啟動(dòng),暫停和重啟腳本:

```
vi /etc/init.d/redis
```

腳本內(nèi)容如下:

```#!/bin/sh  
#  
# redis - this script starts and stops the redis-server daemon  
#  
# chkconfig:   - 85 15  
# description:  Redis is a persistent key-value database  
# processname: redis-server  
# config:      /usr/local/redis/bin/redis-server
# config:      /etc/redis.conf  
# Source function library.  
. /etc/rc.d/init.d/functions  
# Source networking configuration.  
. /etc/sysconfig/network  
# Check that networking is up.  
[ "$NETWORKING" = "no" ] &amp;&amp; exit 0  
redis="/usr/local/redis/bin/redis-server" 
prog=$(basename $redis)  
REDIS_CONF_FILE="/etc/redis.conf" 
[ -f /etc/sysconfig/redis ] &amp;&amp; . /etc/sysconfig/redis  
lockfile=/var/lock/subsys/redis  
<span class="hljs-function"><span class="hljs-title">start() {  
    [ -x $redis ] || exit 5  
    [ -f $REDIS_CONF_FILE ] || exit 6  
    echo -n $"Starting $prog: "  
    daemon $redis $REDIS_CONF_FILE  
    retval=$?  
    echo  
    [ $retval -eq 0 ] &amp;&amp; touch $lockfile  
    return $retval  
}  
<span class="hljs-function"><span class="hljs-title">stop() {  
    echo -n $"Stopping $prog: "  
    killproc $prog -QUIT  
    retval=$?  
    echo  
    [ $retval -eq 0 ] &amp;&amp; rm -f $lockfile  
    return $retval  
}  
<span class="hljs-function"><span class="hljs-title">restart() {  
    stop  
    start  
}  
<span class="hljs-function"><span class="hljs-title">reload() {  
    echo -n $"Reloading $prog: "  
    killproc $redis -HUP  
    RETVAL=$?  
    echo  
}  
<span class="hljs-function"><span class="hljs-title">force_reload() {  
    restart  
}  
<span class="hljs-function"><span class="hljs-title">rh_status() {  
    status $prog  
}  
<span class="hljs-function"><span class="hljs-title">rh_status_q() {  
    rh_status >/dev/null 2>&amp;1  
}  
case "$1" in  
    start)  
        rh_status_q &amp;&amp; exit 0  
        $1  
        ;;  
    stop)  
        rh_status_q || exit 0  
        $1  
        ;;  
    restart|configtest)  
        $1  
        ;;  
    reload)  
        rh_status_q || exit 7  
        $1  
        ;;  
    force-reload)  
        force_reload  
        ;;  
    status)  
        rh_status  
        ;;  
    condrestart|try-restart)  
        rh_status_q || exit 0  
    ;;  
    *)  
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart| reload|orce-reload}"  
        exit 2  
esac
```

賦予腳本權(quán)限

```chmod 755 /etc/init.d/redis
```

啟動(dòng)神年、停止和重啟:

```service redis start
service redis stop
service redis restart
```

至此甜滨,`Redis`單機(jī)服務(wù)器已搭建完畢,下面我們看看主從架構(gòu)如何搭建瘤袖。

# 搭建Redis主從架構(gòu)

### 1. redis-server說(shuō)明

```172.16.2.185:6379 主

172.16.2.181:6379 從
```

2. Redis主從架構(gòu)配置

  • 編輯從機(jī)的 Redis 配置文件衣摩,找到 210 行(大概),默認(rèn)這一行應(yīng)該是注釋的: # slaveof <masterip> <masterport>

  • 我們需要去掉該注釋?zhuān)⑶姨顚?xiě)我們自己的主機(jī)的 IP 和 端口,比如:slaveof 172.16.2.185 6379艾扮,如果主機(jī)設(shè)置了密碼既琴,還需要找到masterauth <master-password>這一行,去掉注釋?zhuān)臑?code>masterauth 主機(jī)密碼泡嘴。

  • 配置完成后重啟從機(jī)Redis 服務(wù)

  • 重啟完之后甫恩,進(jìn)入主機(jī)的 redis-cli 狀態(tài)下redis-cli -h 127.0.0.1 -p 6379 -a 123456,輸入:INFO replication
    可以查詢到當(dāng)前主機(jī)的 Redis處于什么角色酌予,有哪些從機(jī)已經(jīng)連上主機(jī)磺箕。

    主機(jī)信息172.16.2.185

    # Replication
    role:master
    connected_slaves:1
    slave0:ip=172.16.2.181,port=6379,state=online,offset=28,lag=1
    master_replid:625ae9f362643da5337835beaeabfdca426198c7
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:28
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:28
    

    從機(jī)信息172.16.2.181

    # Replication
    role:slave
    master_host:172.16.2.185
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:3
    master_sync_in_progress:0
    slave_repl_offset:210
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:625ae9f362643da5337835beaeabfdca426198c7
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:210
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:210
    
  • 此時(shí)已經(jīng)完成了主從配置,我們可以測(cè)試下:
    我們進(jìn)入主機(jī)的 redis-cli 狀態(tài)抛虫,然后 set 某個(gè)值松靡,比如:set myblog YouMeek.com

  • 我們切換進(jìn)入從機(jī)的 redis-cli 的狀態(tài)下,獲取剛剛設(shè)置的值看是否存在:get myblog建椰,此時(shí)雕欺,我們可以發(fā)現(xiàn)是可以獲取到值的。

    3. Redis主從架構(gòu)總結(jié)

  • 需要注意的是:從庫(kù)不具備寫(xiě)入數(shù)據(jù)能力棉姐,不然會(huì)報(bào)錯(cuò)屠列。 從庫(kù)只有只讀能力。

  • 主從架構(gòu)的優(yōu)點(diǎn):除了減少主庫(kù)連接的壓力伞矩,還有可以關(guān)掉主庫(kù)的持久化功能笛洛,把持久化的功能交給從庫(kù)進(jìn)行處理。

  • 第一個(gè)從庫(kù)配置的信息是連上主庫(kù)乃坤,后面的第二個(gè)從庫(kù)配置的連接信息是連上第一個(gè)從庫(kù)撞蜂, 假如還有第三個(gè)從庫(kù)的話,我們可以把第三個(gè)從庫(kù)的配置信息連上第二個(gè)從庫(kù)上侥袜,以此類(lèi)推蝌诡。

    Redis Sentinel高可用架構(gòu)搭建

    1. 自動(dòng)故障轉(zhuǎn)移

  • 雖然使用主從架構(gòu)配置Redis做了備份,看上去很完美枫吧。但由于Redis目前只支持主從復(fù)制備份(不支持主主復(fù)制)浦旱,當(dāng)主Redis掛了,從Redis只能提供讀服務(wù)九杂,無(wú)法提供寫(xiě)服務(wù)颁湖。所以,還得想辦法例隆,當(dāng)主Redis掛了甥捺,讓從Redis升級(jí)成為主Redis

  • 這就需要自動(dòng)故障轉(zhuǎn)移镀层,Redis Sentinel帶有這個(gè)功能镰禾,當(dāng)一個(gè)主Redis不能提供服務(wù)時(shí),Redis Sentinel可以將一個(gè)從Redis升級(jí)為主Redis,并對(duì)其他從Redis進(jìn)行配置吴侦,讓它們使用新的主Redis進(jìn)行復(fù)制備份屋休。
    <figure>

    Redis Sentinel架構(gòu)圖- 圖片來(lái)自于CSDN 在Redis Sentinel環(huán)境下,jedis該如何配置
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="865" height="469"></svg>" class="inited"><figcaption></figcaption></figure>

    注意:搭建Redis Sentinel推薦至少3臺(tái)服務(wù)器备韧,但由于樓主偷懶劫樟,下面用例只用了2臺(tái)服務(wù)器。

    Redis Sentinel的主要功能如下:

  1. 監(jiān)控:哨兵不斷的檢查masterslave是否正常的運(yùn)行织堂。

  2. 通知:當(dāng)監(jiān)控的某臺(tái)Redis實(shí)例發(fā)生問(wèn)題時(shí)叠艳,可以通過(guò)API通知系統(tǒng)管理員和其他的應(yīng)用程序。

  3. 自動(dòng)故障轉(zhuǎn)移:如果一個(gè)master不正常運(yùn)行了易阳,哨兵可以啟動(dòng)一個(gè)故障轉(zhuǎn)移進(jìn)程附较,將一個(gè)slave升級(jí)成為master,其他的slave被重新配置使用新的master闽烙,并且應(yīng)用程序使用Redis服務(wù)端通知的新地址。

  4. 配置提供者:哨兵作為Redis客戶端發(fā)現(xiàn)的權(quán)威來(lái)源:客戶端連接到哨兵請(qǐng)求當(dāng)前可靠的master的地址声搁。如果發(fā)生故障黑竞,哨兵將報(bào)告新地址。

    默認(rèn)情況下疏旨,每個(gè)Sentinel節(jié)點(diǎn)會(huì)以每秒一次的頻率對(duì)Redis節(jié)點(diǎn)和其它的Sentinel節(jié)點(diǎn)發(fā)送PING命令很魂,并通過(guò)節(jié)點(diǎn)的回復(fù)來(lái)判斷節(jié)點(diǎn)是否在線。

    如果在down-after-millisecondes毫秒內(nèi)檐涝,沒(méi)有收到有效的回復(fù)遏匆,則會(huì)判定該節(jié)點(diǎn)為主觀下線。

    如果該節(jié)點(diǎn)為master谁榜,則該Sentinel節(jié)點(diǎn)會(huì)通過(guò)sentinel is-master-down-by-addr命令向其它sentinel節(jié)點(diǎn)詢問(wèn)對(duì)該節(jié)點(diǎn)的判斷幅聘,如果超過(guò)<quorum>個(gè)數(shù)的節(jié)點(diǎn)判定master不可達(dá),則該sentinel節(jié)點(diǎn)會(huì)將master判斷為客觀下線窃植。

    這個(gè)時(shí)候帝蒿,各個(gè)Sentinel會(huì)進(jìn)行協(xié)商,選舉出一個(gè)領(lǐng)頭Sentinel巷怜,由該領(lǐng)頭Sentinel對(duì)master節(jié)點(diǎn)進(jìn)行故障轉(zhuǎn)移操作葛超。

    故障轉(zhuǎn)移包含如下三個(gè)操作:

  5. 在所有的slave服務(wù)器中,挑選出一個(gè)slave延塑,并將其轉(zhuǎn)換為master绣张。

  6. 讓其它slave服務(wù)器,改為復(fù)制新的master关带。

  7. 將舊master設(shè)置為新masterslave侥涵,這樣,當(dāng)舊的master重新上線時(shí),它會(huì)成為新masterslave独令。

    2. 搭建Redis Sentinel高可用架構(gòu)

    這里使用兩臺(tái)服務(wù)器端朵,每臺(tái)服務(wù)器上開(kāi)啟一個(gè)redis-serverredis-sentinel服務(wù)。

    redis-server說(shuō)明

    172.16.2.185:6379 主
    
    172.16.2.181:6379 從
    

    redis-sentinel說(shuō)明

    172.16.2.185:26379
    
    172.16.2.181:26379
    
    2.1 建立Redis配置文件

    如果要做自動(dòng)故障轉(zhuǎn)移燃箭,則建議所有的redis.conf都設(shè)置masterauth冲呢,因?yàn)樽詣?dòng)故障只會(huì)重寫(xiě)主從關(guān)系,即slaveof招狸,不會(huì)自動(dòng)寫(xiě)入masterauth敬拓。如果Redis原本沒(méi)有設(shè)置密碼,則可以忽略裙戏。

    Redis程序上面已經(jīng)安裝過(guò)了乘凸,我們只需增加redis-sentinel的相關(guān)配置即可,將 redis-sentinel的配置文件拷貝到系統(tǒng)配置目錄/etc/下累榜,sentinel.confredis-sentinel的配置文件营勤,sentinel.confRedis 源碼目錄。

    cp /usr/local/redis-4.0.2/sentinel.conf  /etc/
    

    修改sentinel.conf配置文件內(nèi)容如下:

    vi /etc/sentinel.conf
    
    protected-mode no
    sentinel monitor mymaster 172.16.2.185 6379 2
    # redis在搭建時(shí)設(shè)置了密碼壹罚,所以要進(jìn)行密碼配置
    sentinel auth-pass mymaster “123456“
    #5秒內(nèi)mymaster沒(méi)有響應(yīng)葛作,就認(rèn)為SDOWN
    sentinel down-after-milliseconds mymaster 5000  
    sentinel failover-timeout  mymaster 15000
    

    在配置最后加上

    logfile /var/log/sentinel.log
    pidfile  /var/run/sentinel.pid
    daemonize yes
    

    配置文件說(shuō)明:

    1.port :當(dāng)前Sentinel服務(wù)運(yùn)行的端口

    2.dir : Sentinel服務(wù)運(yùn)行時(shí)使用的臨時(shí)文件夾

    3.sentinel monitor master001 192.168.110.10163792:Sentinel去監(jiān)視一個(gè)名為master001的主redis實(shí)例,這個(gè)主實(shí)例的IP地址為本機(jī)地址192.168.110.101猖凛,端口號(hào)為6379晃洒,而將這個(gè)主實(shí)例判斷為失效至少需要2個(gè) Sentinel進(jìn)程的同意修肠,只要同意Sentinel的數(shù)量不達(dá)標(biāo)磅网,自動(dòng)failover就不會(huì)執(zhí)行

    4.sentinel down-after-milliseconds master001 30000:指定了Sentinel認(rèn)為Redis實(shí)例已經(jīng)失效所需的毫秒數(shù)唉铜。當(dāng)實(shí)例超過(guò)該時(shí)間沒(méi)有返回PING,或者直接返回錯(cuò)誤菠红,那么Sentinel將這個(gè)實(shí)例標(biāo)記為主觀下線第岖。只有一個(gè) Sentinel進(jìn)程將實(shí)例標(biāo)記為主觀下線并不一定會(huì)引起實(shí)例的自動(dòng)故障遷移:只有在足夠數(shù)量的Sentinel都將一個(gè)實(shí)例標(biāo)記為主觀下線之后,實(shí)例才會(huì)被標(biāo)記為客觀下線试溯,這時(shí)自動(dòng)故障遷移才會(huì)執(zhí)行

    5.sentinel parallel-syncs master001 1:指定了在執(zhí)行故障轉(zhuǎn)移時(shí)绍傲,最多可以有多少個(gè)從Redis實(shí)例在同步新的主實(shí)例,在從Redis實(shí)例較多的情況下這個(gè)數(shù)字越小耍共,同步的時(shí)間越長(zhǎng)烫饼,完成故障轉(zhuǎn)移所需的時(shí)間就越長(zhǎng)

    6.sentinel failover-timeout master001 180000:如果在該時(shí)間(ms)內(nèi)未能完成failover操作,則認(rèn)為該failover失敗

    7.sentinel notification-script :指定sentinel檢測(cè)到該監(jiān)控的redis實(shí)例指向的實(shí)例異常時(shí)试读,調(diào)用的報(bào)警腳本杠纵。該配置項(xiàng)可選,但是很常用

    2.2 開(kāi)放防火墻端口
    添加規(guī)則:iptables -I INPUT -p tcp -m tcp --dport 26379 -j ACCEPT
    保存規(guī)則:service iptables save
    重啟iptables:service iptables restart
    
    2.3 啟動(dòng)redis-sentinel
    redis-sentinel  /etc/sentinel.conf
    

    在任意一臺(tái)機(jī)子均可查看到相關(guān)服務(wù)信息

    redis-cli -h 127.0.0.1 -p 26379
    
    INFO sentinel
    
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=172.16.2.185:6379,slaves=1,sentinels=2
    

    3. 自動(dòng)故障轉(zhuǎn)移測(cè)試

    3.1 停止主Redis
    redis-cli -h 172.16.2.185 -p 6379 -a 123456 shutdown
    
    3.2 查看redis-sentinel的監(jiān)控狀態(tài)
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=172.16.2.181:6379,slaves=1,sentinels=2
    

    發(fā)現(xiàn)從庫(kù)提升為主庫(kù)钩骇。

    3.3 注意事項(xiàng)
  • 如果停掉master后比藻,Sentinel顯示足夠數(shù)量的sdown后铝量,沒(méi)有出現(xiàn)odowntry-failover,則檢查密碼等配置是否正確
  • 如果停掉master后银亲,試圖切換的時(shí)候慢叨,發(fā)現(xiàn)日志出現(xiàn) failover-abort-not-elected,則分2種情況分別解決:
  1. 如果Redis實(shí)例沒(méi)有配置

    protected-mode yes
    bind 172.16.2.185
    

    則在Sentinel 配置文件加上protected-mode no即可

  2. 如果Redis實(shí)例有配置

    protected-mode yes
    bind 172.16.2.185
    

    則在Sentinel配置文件加上

    protected-mode yes
    bind 172.16.2.185
    

    至此务蝠,redis的高可用方案已經(jīng)搭建完成拍谐。

    VIP對(duì)外提供虛擬IP實(shí)現(xiàn)高可用

    1. 現(xiàn)有情況概述

    客戶端程序(如JAVA程序)連接Redis時(shí)需要ipport,但redis-server進(jìn)行故障轉(zhuǎn)移時(shí)馏段,主Redis是變化的轩拨,所以ip地址也是變化的≡合玻客戶端程序如何感知當(dāng)前主Redisip地址和端口呢亡蓉?redis-sentinel提供了接口,請(qǐng)求任何一個(gè)Sentinel喷舀,發(fā)送SENTINEL get-master-addr-by-name <master name>就能得到當(dāng)前主Redisipport砍濒。

    客戶端每次連接Redis前,先向sentinel發(fā)送請(qǐng)求硫麻,獲得主Redisipport爸邢,然后用返回的ipport連接Redis

    這種方法的缺點(diǎn)是顯而易見(jiàn)的庶香,每次操作Redis至少需要發(fā)送兩次連接請(qǐng)求甲棍,第一次請(qǐng)求Sentinel简识,第二次請(qǐng)求Redis赶掖。

    更好的辦法是使用VIP,當(dāng)然這對(duì)配置的環(huán)境有一定的要求七扰,比如Redis搭建在阿里云服務(wù)器上奢赂,可能不支持VIP

    VIP方案是颈走,Redis系統(tǒng)對(duì)外始終是同一ip地址膳灶,當(dāng)Redis進(jìn)行故障轉(zhuǎn)移時(shí),需要做的是將VIP從之前的Redis服務(wù)器漂移到現(xiàn)在新的主Redis服務(wù)器上立由。

    比如:當(dāng)前Redis系統(tǒng)中主Redisip地址是172.16.2.185轧钓,那么VIP(172.16.2.250)指向172.16.2.185,客戶端程序用VIP(172.16.2.250)地址連接Redis锐膜,實(shí)際上連接的就是當(dāng)前主Redis毕箍,這樣就避免了向Sentinel發(fā)送請(qǐng)求。

    當(dāng)主Redis宕機(jī)道盏,進(jìn)行故障轉(zhuǎn)移時(shí)而柑,172.16.2.181這臺(tái)服務(wù)器上的Redis提升為主文捶,這時(shí)VIP(172.16.2.250)指向172.16.2.181,這樣客戶端程序不需要修改任何代碼媒咳,連接的是172.16.2.181這臺(tái)主Redis粹排。

    2.漂移VIP實(shí)現(xiàn)Redis故障轉(zhuǎn)移

    那么現(xiàn)在的問(wèn)題是,如何在進(jìn)行Redis故障轉(zhuǎn)移時(shí)涩澡,將VIP漂移到新的主Redis服務(wù)器上顽耳。

    這里可以使用Redis Sentinel的一個(gè)參數(shù)client-reconfig-script,這個(gè)參數(shù)配置執(zhí)行腳本筏养,Sentinel在做failover的時(shí)候會(huì)執(zhí)行這個(gè)腳本斧抱,并且傳遞6個(gè)參數(shù)<master-name>、 <role>渐溶、 <state>辉浦、 <from-ip>、 <from-port>茎辐、 <to-ip>宪郊、<to-port>,其中<to-ip>是新主RedisIP地址拖陆,可以在這個(gè)腳本里做VIP漂移操作弛槐。

    sentinel client-reconfig-script mymaster /opt/notify_mymaster.sh
    

    修改兩個(gè)服務(wù)器的redis-sentinel配置文件/etc/sentinel.conf,增加上面一行依啰。然后在/opt/目錄下創(chuàng)建notify_mymaster.sh腳本文件乎串,這個(gè)腳本做VIP漂移操作,內(nèi)容如下:

    vi /opt/notify_mymaster.sh
    
    #!/bin/bash
    echo "File Name: $0"
    echo "Quoted Values: $@"
    echo "Quoted Values: $*"
    echo "Total Number of Parameters : $#"
    
    MASTER_IP=${6}  #第六個(gè)參數(shù)是新主redis的ip地址
    LOCAL_IP='172.16.2.185'  #當(dāng)前服務(wù)器IP速警,主機(jī)172.16.2.185叹誉,從機(jī)172.16.2.181
    VIP='172.16.2.250'
    NETMASK='24'
    INTERFACE='eth1'
    if [ ${MASTER_IP} = ${LOCAL_IP} ]; then
         sudo /sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}  #將VIP綁定到該服務(wù)器上
         sudo /sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
        exit 0
    else
         sudo /sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}   #將VIP從該服務(wù)器上刪除
       exit 0
    fi
    exit 1  #如果返回1,sentinel會(huì)一直執(zhí)行這個(gè)腳本
    

    賦予腳本權(quán)限

    chmod 755 /opt/notify_mymaster.sh
    

    現(xiàn)在當(dāng)前主Redis172.16.2.185闷旧,需要手動(dòng)綁定VIP到該服務(wù)器上长豁。

    /sbin/ip  addr add 172.16.2.250/24 dev eth1
    /sbin/arping -q   -c 3 -A 172.16.2.250 -I eth1
    

    由于VIP只能綁定只有一臺(tái)機(jī)子,所以建議將改為bind 0.0.0.0添加至redis.conf

    vi /etc/redis.conf
    

    設(shè)置bind 0.0.0.0

    由于VIP只能綁定只有一臺(tái)機(jī)子忙灼,所以建議將改為bind 0.0.0.0添加至sentinel.conf

    vi /etc/sentinel.conf
    

    設(shè)置bind 0.0.0.0

    重啟Redis

    service redis restart`
    

    重啟Sentinel

    redis-sentinel /etc/sentinel.conf
    

    隨后我們?cè)诹硪慌_(tái)機(jī)器172.16.2.181上匠襟,通過(guò)VIP訪問(wèn)主機(jī)

    redis-cli -h 172.16.2.250 -p 6379 -a 123456 INFO replication
    

    可正常通訊,信息如下:

    # Replication
    role:master
    connected_slaves:1
    slave0:ip=172.16.2.181,port=6379,state=online,offset=0,lag=0
    master_replid:325b0bccab611d329d9c2cd2c35a1fe3c01ae196
    master_replid2:c1f7a7d17d2c35575a34b00eb10c8abf32df2243
    master_repl_offset:22246293
    second_repl_offset:22241024
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:22237293
    repl_backlog_histlen:9001
    

    訪問(wèn)主機(jī)的Sentinel

    redis-cli -h 172.16.2.250 -p 26379 INFO sentinel
    

    可正常通訊该园,信息如下:

    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=172.16.2.185:6379,slaves=1,sentinels=3
    

    下面關(guān)閉主機(jī)的Redis服務(wù)酸舍,看看VIP是否漂移到另一臺(tái)服務(wù)器上。

    redis-cli -h 172.16.2.185 -p 6379 -a 123456 shutdown
    

    查看是否已進(jìn)行切換

    redis-cli -h 172.16.2.250 -p 26379 INFO sentinel
    
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=172.16.2.181:6379,slaves=1,sentinels=3
    

    通過(guò)查詢Sentinel發(fā)現(xiàn)從機(jī)172.16.2.181提升為主里初。

    通過(guò)訪問(wèn)VIP的方式連接Redis

    redis-cli -h 172.16.2.250 -p 6379 -a 123456 INFO replication
    
    # Replication
    role:master
    connected_slaves:0
    master_replid:cab30a4083f35652053ffcd099d70b9aaf7a80f3
    master_replid2:3da856dd33cce4bedd54926df6797b410f1ab9e8
    master_repl_offset:74657
    second_repl_offset:36065
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:74657
    
    

從上面信息可知啃勉,VIP已經(jīng)飄移成功∏嗥伲可喜可賀璧亮,大吉大利萧诫,晚上吃雞。

總結(jié)

至此枝嘶,高可用Redis緩存服務(wù)已搭建完畢帘饶,遲點(diǎn)會(huì)再出一篇文章教大家如何通過(guò)JAVA連接Redis進(jìn)行相關(guān)操作。至于Redis Cluster集群方案群扶,等有空再搭建然后再和大家一同分享及刻。

參考文章

搭建一個(gè)redis高可用系統(tǒng)

Redis 安裝和配置

Redis 復(fù)制、Sentinel的搭建和原理說(shuō)明

Redis 快速入門(mén)(官網(wǎng)翻譯)

Redis Sentinel機(jī)制與用法(一)

Redis哨兵-實(shí)現(xiàn)Redis高可用

讀懂Redis并配置主從集群及高可用部署

在Redis Sentinel環(huán)境下竞阐,jedis該如何配置

redis sentinel 主從切換(failover)解決方案缴饭,詳細(xì)配置

Redis-3.2.1主從故障測(cè)試實(shí)例

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市骆莹,隨后出現(xiàn)的幾起案子颗搂,更是在濱河造成了極大的恐慌,老刑警劉巖幕垦,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丢氢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡先改,警方通過(guò)查閱死者的電腦和手機(jī)疚察,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)仇奶,“玉大人貌嫡,你說(shuō)我怎么就攤上這事「盟荩” “怎么了岛抄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)朗伶。 經(jīng)常有香客問(wèn)我弦撩,道長(zhǎng)步咪,這世上最難降的妖魔是什么论皆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮猾漫,結(jié)果婚禮上点晴,老公的妹妹穿的比我還像新娘。我一直安慰自己悯周,他們只是感情好粒督,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著禽翼,像睡著了一般屠橄。 火紅的嫁衣襯著肌膚如雪族跛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天锐墙,我揣著相機(jī)與錄音礁哄,去河邊找鬼。 笑死溪北,一個(gè)胖子當(dāng)著我的面吹牛桐绒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播之拨,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼茉继,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蚀乔?” 一聲冷哼從身側(cè)響起烁竭,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吉挣,沒(méi)想到半個(gè)月后颖变,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡听想,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年腥刹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汉买。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡衔峰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蛙粘,到底是詐尸還是另有隱情垫卤,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布出牧,位于F島的核電站穴肘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏舔痕。R本人自食惡果不足惜评抚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伯复。 院中可真熱鬧慨代,春花似錦、人聲如沸啸如。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叮雳。三九已至想暗,卻和暖如春妇汗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背说莫。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工铛纬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唬滑。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓告唆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親晶密。 傳聞我的和親對(duì)象是個(gè)殘疾皇子擒悬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容