前言
Redis
是一個(gè)高性能的key-value
數(shù)據(jù)庫吞杭,現(xiàn)時(shí)越來越多企業(yè)與應(yīng)用使用Redis
作為緩存服務(wù)器。樓主是一枚JAVA
后端程序員嘀韧,也算是半個(gè)運(yùn)維工程師了篇亭。在Linux
服務(wù)器上搭建Redis
,怎么可以不會(huì)呢锄贷?下面樓主就帶著大家從0開始绢慢,依次搭建:Redis
單機(jī)服務(wù)器 -> Redis
主從復(fù)制 -> Redis-Sentinel高可用
乌询。逐步搭建出高可用的Redis緩存服務(wù)器。主要參考文章:簡書:搭建一個(gè)redis高可用系統(tǒng)
樓主基于此文一步步參考著搭建,所以內(nèi)容較為相似管钳,感謝原文作者闪金,特此申明羡滑。
搭建Redis
1. 下載并解壓
首先從Redis
官網(wǎng)下載Redis
并解壓丝格,樓主使用的版本是4.0.2。依次執(zhí)行如下命令:
cd /usr/local/
wget http://download.redis.io/releases/redis-4.0.2.tar.gz
tar -zxvf redis-4.0.2.tar.gz
如果沒有安裝gcc
依賴包碴萧,則安裝對(duì)應(yīng)依賴包
yum install -y gcc-c++ tcl
2. 編譯并安裝
下載并解壓完畢后乙嘀,則對(duì)源碼包進(jìn)行編譯安裝,樓主的Redis
安裝路徑為/usr/local/redis
破喻,同學(xué)們可以自行修改語句:make install PREFIX=你想要安裝的路徑
cd /usr/local/redis-4.0.2/
make install PREFIX=/usr/local/redis
復(fù)制Redis
相關(guān)命令到/usr/sbin
目錄下虎谢,這樣就可以直接執(zhí)行這些命令,不用寫全路徑
cd /usr/local/redis/bin/
sudo cp redis-cli redis-server redis-sentinel /usr/sbin/
3. 建立Redis配置文件
安裝完成之后將 Redis
配置文件拷貝到系統(tǒng)配置目錄/etc/
下曹质,redis.conf
是 Redis
的配置文件婴噩,redis.conf
在 Redis
源碼目錄,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 #客戶端閑置多長時(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ù)庫的數(shù)量,默認(rèn)為0可以使用select <dbid>命令在連接上指定數(shù)據(jù)庫id
save <seconds> <changes> #指定在多少時(shí)間內(nèi)刷新次數(shù)達(dá)到多少的時(shí)候會(huì)將數(shù)據(jù)同步到數(shù)據(jù)文件;
rdbcompression yes #指定存儲(chǔ)至本地?cái)?shù)據(jù)庫時(shí)是否壓縮文件,默認(rèn)為yes即啟用存儲(chǔ);
dbfilename dump.db #指定本地?cái)?shù)據(jù)庫文件名
dir ./ #指定本地?cái)?shù)據(jù)問就按存放位置;
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是需要通過AUTH<password>命令提供密碼,默認(rèn)關(guān)閉
maxclients 128 #設(shè)置同一時(shí)間最大客戶連接數(shù),默認(rèn)無限制;redis可以同時(shí)連接的客戶端數(shù)為redis程序可以打開的最大文件描述符,如果設(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è)置匀伏,將無法再進(jìn)行寫入操作,但仍然可以進(jìn)行讀取操作蝴韭。Redis新的vm機(jī)制够颠,會(huì)把Key存放內(nèi)存,Value會(huì)存放在swap區(qū)
appendonly no #指定是否在每次更新操作后進(jìn)行日志記錄榄鉴,Redis在默認(rèn)情況下是異步的把數(shù)據(jù)寫入磁盤履磨,如果不開啟蛉抓,可能會(huì)在斷電時(shí)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失。因?yàn)?redis本身同步數(shù)據(jù)文件是按上面save條件來同步的剃诅,所以有的數(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ù)緩存同步到磁盤(快),always:表示每次更新操作后手動(dòng)調(diào)用fsync()將數(shù)據(jù)寫到磁盤(慢,安全), 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è)置訪問:
Redis
默認(rèn)只允許本機(jī)訪問翻屈,可是有時(shí)候我們也需要 Redis 被遠(yuǎn)程訪問陈哑。
vi /etc/redis.conf
找到 bind 那行配置,默認(rèn)是: # bind 127.0.0.1
去掉#
注釋并改為: bind 0.0.0.0
此設(shè)置會(huì)變成允許所有遠(yuǎ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
去掉注釋,把 foobared
改為你想要設(shè)置的密碼涂臣,比如我打算設(shè)置為:123456
盾计,所以我改為:requirepass "123456"
修改之后重啟下服務(wù)
有了密碼之后,進(jì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è)置開機(jī)自動(dòng)啟動(dòng)配置
echo "/usr/local/redis/bin/redis-server /etc/redis.conf" >> /etc/rc.local
4.7 開放防火墻端口
添加規(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" ] && exit 0
redis="/usr/local/redis/bin/redis-server"
prog=$(basename $redis)
REDIS_CONF_FILE="/etc/redis.conf"
[ -f /etc/sysconfig/redis ] && . /etc/sysconfig/redis
lockfile=/var/lock/subsys/redis
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 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
reload() {
echo -n $"Reloading $prog: "
killproc $redis -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && 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說明
172.16.2.185:6379 主
172.16.2.181:6379 從
2. Redis主從架構(gòu)配置
編輯從機(jī)的
Redis
配置文件剖煌,找到 210 行(大概)材鹦,默認(rèn)這一行應(yīng)該是注釋的:# slaveof <masterip> <masterport>
我們需要去掉該注釋,并且填寫我們自己的主機(jī)的 IP 和 端口耕姊,比如:
slaveof 172.16.2.185 6379
桶唐,如果主機(jī)設(shè)置了密碼,還需要找到masterauth <master-password>
這一行茉兰,去掉注釋尤泽,改為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)完成了主從配置闹丐,我們可以測試下:
我們進(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é)
需要注意的是:從庫不具備寫入數(shù)據(jù)能力惑畴,不然會(huì)報(bào)錯(cuò)。 從庫只有只讀能力航徙。
主從架構(gòu)的優(yōu)點(diǎn):除了減少主庫連接的壓力如贷,還有可以關(guān)掉主庫的持久化功能,把持久化的功能交給從庫進(jìn)行處理到踏。
第一個(gè)從庫配置的信息是連上主庫杠袱,后面的第二個(gè)從庫配置的連接信息是連上第一個(gè)從庫, 假如還有第三個(gè)從庫的話窝稿,我們可以把第三個(gè)從庫的配置信息連上第二個(gè)從庫上楣富,以此類推。
Redis Sentinel高可用架構(gòu)搭建
1. 自動(dòng)故障轉(zhuǎn)移
- 雖然使用主從架構(gòu)配置
Redis
做了備份伴榔,看上去很完美纹蝴。但由于Redis
目前只支持主從復(fù)制備份(不支持主主復(fù)制),當(dāng)主Redis
掛了踪少,從Redis
只能提供讀服務(wù)塘安,無法提供寫服務(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ù)制備份驱显。
注意:搭建Redis Sentinel
推薦至少3臺(tái)服務(wù)器侨舆,但由于樓主偷懶,下面用例只用了2臺(tái)服務(wù)器绢陌。
Redis Sentinel
的主要功能如下:
監(jiān)控:哨兵不斷的檢查
master
和slave
是否正常的運(yùn)行。通知:當(dāng)監(jiān)控的某臺(tái)
Redis
實(shí)例發(fā)生問題時(shí)熔恢,可以通過API
通知系統(tǒng)管理員和其他的應(yīng)用程序脐湾。自動(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ù)端通知的新地址鹰霍。配置提供者:哨兵作為
Redis
客戶端發(fā)現(xiàn)的權(quán)威來源:客戶端連接到哨兵請(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
命令,并通過節(jié)點(diǎn)的回復(fù)來判斷節(jié)點(diǎn)是否在線督勺。
如果在down-after-millisecondes
毫秒內(nèi)渠羞,沒有收到有效的回復(fù),則會(huì)判定該節(jié)點(diǎn)為主觀下線智哀。
如果該節(jié)點(diǎn)為master
次询,則該Sentinel
節(jié)點(diǎn)會(huì)通過sentinel is-master-down-by-addr
命令向其它sentinel
節(jié)點(diǎn)詢問對(duì)該節(jié)點(diǎn)的判斷,如果超過<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è)操作:
在所有的
slave
服務(wù)器中辨嗽,挑選出一個(gè)slave
世落,并將其轉(zhuǎn)換為master
。讓其它
slave
服務(wù)器糟需,改為復(fù)制新的master
屉佳。將舊
master
設(shè)置為新master
的slave
,這樣洲押,當(dāng)舊的master
重新上線時(shí)武花,它會(huì)成為新master
的slave
。
2. 搭建Redis Sentinel高可用架構(gòu)
這里使用兩臺(tái)服務(wù)器杈帐,每臺(tái)服務(wù)器上開啟一個(gè)redis-server
和redis-sentinel
服務(wù)体箕。
redis-server說明
172.16.2.185:6379 主
172.16.2.181:6379 從
redis-sentinel說明
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ì)重寫主從關(guān)系累铅,即slaveof
跃须,不會(huì)自動(dòng)寫入masterauth
。如果Redis
原本沒有設(shè)置密碼娃兽,則可以忽略菇民。
Redis
程序上面已經(jīng)安裝過了,我們只需增加redis-sentinel
的相關(guān)配置即可投储,將 redis-sentinel
的配置文件拷貝到系統(tǒng)配置目錄/etc/
下第练,sentinel.conf
是 redis-sentinel
的配置文件,sentinel.conf
在 Redis
源碼目錄玛荞。
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沒有響應(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
配置文件說明:
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í)例超過該時(shí)間沒有返回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í)間越長,完成故障轉(zhuǎn)移所需的時(shí)間就越長
6.sentinel failover-timeout master001 180000:如果在該時(shí)間(ms)內(nèi)未能完成failover操作隅很,則認(rèn)為該failover失敗
7.sentinel notification-script <master-name> <script-path>:指定sentinel檢測到該監(jiān)控的redis實(shí)例指向的實(shí)例異常時(shí)撞牢,調(diào)用的報(bào)警腳本。該配置項(xiàng)可選叔营,但是很常用
2.2 開放防火墻端口
添加規(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)移測試
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)從庫提升為主庫屋彪。
3.3 注意事項(xiàng)
如果停掉
master
后,Sentinel
顯示足夠數(shù)量的sdown
后绒尊,沒有出現(xiàn)odown
或try-failover
畜挥,則檢查密碼等配置是否正確如果停掉
master
后,試圖切換的時(shí)候婴谱,發(fā)現(xiàn)日志出現(xiàn)failover-abort-not-elected
蟹但,則分2種情況分別解決:
- 如果
Redis
實(shí)例沒有配置
protected-mode yes
bind 172.16.2.185
則在Sentinel
配置文件加上protected-mode no
即可
- 如果
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í)需要ip
和port
华糖,但redis-server
進(jìn)行故障轉(zhuǎn)移時(shí)麦向,主Redis
是變化的,所以ip
地址也是變化的客叉】纳撸客戶端程序如何感知當(dāng)前主Redis
的ip
地址和端口呢?redis-sentinel
提供了接口十办,請(qǐng)求任何一個(gè)Sentinel
,發(fā)送SENTINEL get-master-addr-by-name <master name>
就能得到當(dāng)前主Redis
的ip
和port
超棺。
客戶端每次連接Redis
前向族,先向sentinel
發(fā)送請(qǐng)求,獲得主Redis
的ip
和port
棠绘,然后用返回的ip
和port
連接Redis
件相。
這種方法的缺點(diǎ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)中主Redis
的ip
地址是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)在的問題是憔四,如何在進(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>
是新主Redis
的IP
地址弱判,可以在這個(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)前主Redis
是172.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
上,通過VIP
訪問主機(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
訪問主機(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
通過查詢Sentinel
發(fā)現(xiàn)從機(jī)172.16.2.181
提升為主根穷。
通過訪問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ì)再出一篇文章教大家如何通過JAVA
連接Redis
進(jìn)行相關(guān)操作喷橙。至于Redis Cluster
集群方案啥么,等有空再搭建然后再和大家一同分享。
參考文章
搭建一個(gè)redis高可用系統(tǒng)
Redis 安裝和配置
Redis 復(fù)制贰逾、Sentinel的搭建和原理說明
Redis 快速入門(官網(wǎng)翻譯)
Redis Sentinel機(jī)制與用法(一)
Redis哨兵-實(shí)現(xiàn)Redis高可用
讀懂Redis并配置主從集群及高可用部署
在Redis Sentinel環(huán)境下悬荣,jedis該如何配置
redis sentinel 主從切換(failover)解決方案,詳細(xì)配置
Redis-3.2.1主從故障測試實(shí)例