環(huán)境介紹:
Master: 1.1.1.10
Slave: 1.1.1.11
Virtural IP Address (VIP):1.1.1.111
設(shè)計(jì)思路:
當(dāng) Master 與 Slave 均運(yùn)作正常時(shí), Master負(fù)責(zé)服務(wù)驾茴,Slave負(fù)責(zé)Standby谅阿;
當(dāng) Master 掛掉,Slave 正常時(shí), Slave接管服務(wù)缩抡,同時(shí)關(guān)閉主從復(fù)制功能隧膏;
當(dāng) Master 恢復(fù)正常哗讥,則從Slave同步數(shù)據(jù),同步數(shù)據(jù)之后關(guān)閉主從復(fù)制功能胞枕,恢復(fù)Master身份杆煞,于此同時(shí)Slave等待Master同步數(shù)據(jù)完成之后,恢復(fù)Slave身份。
然后依次循環(huán)索绪。
需要注意的是湖员,這樣做需要在Master與Slave上都開啟本地化策略械拍,否則在互相自動(dòng)切換的過程中拇颅,未開啟本地化的一方會(huì)將另一方的數(shù)據(jù)清空,造成數(shù)據(jù)完全丟失拴驮。
- 下面唤反,是具體的實(shí)施步驟:
一凳寺、安裝
1. 安裝keepalived
yum install -y keepalived
2. 安裝redis
tar xvf redis-2.8.tar.gz
cd redis-2.8
make PREFIX=/usr/local/redis install
3. 把redis加入開機(jī)啟動(dòng)
vim /etc/init.d/redis
#!/bin/sh
#Configurations injected by install_server below....
EXEC=/usr/local/redis/bin/redis-server
CLIEXEC=/usr/local/redis/bin/redis-cli
PIDFILE=/usr/local/redis/var/redis.pid
CONF=/usr/local/redis/etc/redis.conf
REDISPORT="6379"
###############
# SysV Init Information
# chkconfig: - 58 74
# description: redis_6379 is the redis daemon.
### BEGIN INIT INFO
# Provides: redis_6379
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Should-Start: $syslog $named
# Should-Stop: $syslog $named
# Short-Description: start and stop redis_6379
# Description: Redis daemon
### END INIT INFO
case "$1" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
$EXEC $CONF
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -p $REDISPORT shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
status)
PID=$(cat $PIDFILE)
if [ ! -x /proc/${PID} ]
then
echo 'Redis is not running'
else
echo "Redis is running ($PID)"
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Please use start, stop, restart or status as first argument"
;;
esac
chkconfig redis on
二、配置
1. 配置redis
mkdir /usr/local/redis/etc/
mkdir /usr/local/redis/var/
vim /usr/local/redis/etc/redis.conf
daemonize yes
pidfile /usr/local/redis/var/redis.pid
port 6379
timeout 300
loglevel debug
logfile /usr/local/redis/var/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir /usr/local/redis/var/
appendonly no
appendfsync always
- conf的主要配置參數(shù)的意義:
daemonize:是否以后臺(tái)daemon方式運(yùn)行
pidfile:pid文件位置
port:監(jiān)聽的端口號(hào)
timeout:請(qǐng)求超時(shí)時(shí)間
loglevel:log信息級(jí)別
logfile:log文件位置
databases:開啟數(shù)據(jù)庫的數(shù)量
save * :保存快照的頻率彤侍,第一個(gè)表示多長時(shí)間肠缨,第三個(gè)*表示執(zhí)行多少次寫操作。在一定時(shí)間內(nèi)執(zhí)行一定數(shù)量的寫操作時(shí)盏阶,自動(dòng)保存快照晒奕。可設(shè)置多個(gè)條件名斟。
rdbcompression:是否使用壓縮
dbfilename:數(shù)據(jù)快照文件名(只是文件名脑慧,不包括目錄)
dir:數(shù)據(jù)快照的保存目錄(這個(gè)是目錄)
appendonly:是否開啟appendonlylog,開啟的話每次寫操作會(huì)記一條log砰盐,這會(huì)提高數(shù)據(jù)抗風(fēng)險(xiǎn)能力闷袒,但影響效率。
appendfsync:appendonlylog如何同步到磁盤(三個(gè)選項(xiàng)岩梳,分別是每次寫都強(qiáng)制調(diào)用fsync囊骤、每秒啟用一次fsync、不調(diào)用fsync等待系統(tǒng)自己同步)
- 將Redis的命令所在目錄添加到系統(tǒng)參數(shù)PATH中
>vim /etc/profile
export PATH="$PATH:/usr/local/redis/bin"
source /etc/profile
啟動(dòng)redis冀值,/etc/init.d/redis start
用redis-cli命令進(jìn)行測試
2. 配置keepalive
>vim /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_DEVEL
}
vrrp_script check_redis_port {
script "/etc/keepalived/scripts/redis_check.sh" ###監(jiān)控腳本
interval 2 ###監(jiān)控時(shí)間
}
vrrp_instance VI_1 {
state BACKUP #主備都用BACKUP
interface eth0
virtual_router_id 51
priority 100 #slave端用 priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass redis
}
notify_master "/etc/keepalived/scripts/redis_master.sh"
notify_backup "/etc/keepalived/scripts/redis_backup.sh"
notify_fault "/etc/keepalived/scripts/redis_fault.sh"
notify_stop "/etc/keepalived/scripts/redis_stop.sh"
track_script {
check_redis_port
}
virtual_ipaddress {
1.1.1.111
}
}
3. 編寫相關(guān)腳本
- 編寫監(jiān)控腳本
>mkdir /etc/keepalived/scripts
>cd !$
>vim redis_check.sh
#!/bin/bash
ALIVE=`/usr/local/redis/bin/redis-cli PING`
if [ "$ALIVE" == "PONG" ]; then
echo $ALIVE
exit 0
else
echo $ALIVE
exit 1
fi
- 編寫負(fù)責(zé)運(yùn)作的關(guān)鍵腳本
notify_master /etc/keepalived/scripts/redis_master.sh
notify_backup /etc/keepalived/scripts/redis_backup.sh
notify_fault /etc/keepalived/scripts/redis_fault.sh
notify_stop /etc/keepalived/scripts/redis_stop.sh
說明:
因?yàn)镵eepalived在轉(zhuǎn)換狀態(tài)時(shí)會(huì)依照狀態(tài)來呼叫:
當(dāng)進(jìn)入Master狀態(tài)時(shí)會(huì)呼叫notify_master
當(dāng)進(jìn)入Backup狀態(tài)時(shí)會(huì)呼叫notify_backup
當(dāng)發(fā)現(xiàn)異常情況時(shí)進(jìn)入Fault狀態(tài)呼叫notify_fault
當(dāng)Keepalived程序終止時(shí)則呼叫notify_stop
具體腳本:
>vim redis_master.sh
#!/bin/bash
REDISCLI="/usr/local/redis/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 1.1.1.11 6379 >> $LOGFILE 2>&1 #master和backup都寫對(duì)方ip
sleep 10 #延遲10秒以后待數(shù)據(jù)同步完成后再取消同步狀態(tài)
echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
>vim redis_backup.sh
#!/bin/bash
REDISCLI="/usr/local/redis/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
sleep 15 #延遲15秒待數(shù)據(jù)被對(duì)方同步完成之后再切換主從角色
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 1.1.1.11 6379 >> $LOGFILE 2>&1 #master和backup都寫對(duì)方ip
>vim /etc/keepalived/scripts/redis_stop.sh
#!/bin/bash
LOGFILE=/var/log/keepalived-redis-state.log
echo "[stop]" >> $LOGFILE
date >> $LOGFILE
- 給腳本都加上可執(zhí)行權(quán)限:
chmod +x /etc/keepalived/scripts/*.sh
三也物、驗(yàn)證
1. 啟動(dòng)
- 啟動(dòng)Master上的Redis
>/etc/init.d/redis start
- 啟動(dòng)Slave上的Redis
>/etc/init.d/redis start
- 啟動(dòng)Master上的Keepalived
>/etc/init.d/keepalived start
- 啟動(dòng)Slave上的Keepalived
>/etc/init.d/keepalived start
- 嘗試通過VIP連接Redis:
redis-cli -h 1.1.1.111
set a 3
get a
3
分別的兩邊的redis進(jìn)行啟停,會(huì)看到較色轉(zhuǎn)移列疗,vip轉(zhuǎn)移
- 現(xiàn)在redis的高可用做好了焦除,接下來做redis共享tomcat,session
2. 配置tomcat
在tomcat/lib 下作彤,加入如下jar包
百度云盤有(東張瞎望的魚):
- 分別修改2個(gè)tomcat的context.xml
<!--
redis save session
-->
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="1.1.1.111"
port="6379"
database="0"
maxInactiveInterval="60"/>
重啟tomcat
- 設(shè)置nginx
upstream redis-session {
server 1.1.1.10:8081 weight=1; #mem01
# server 1.1.1.10:8082 weight=1; #mem02
server 1.1.1.11:8083 weight=1; #mem03
# server 1.1.1.11:8084 weight=1; #mem04
}
server {
listen 80;
server_name redis-session;
location / {
proxy_pass http://redis-session;
}
}
瀏覽器訪問
多次刷新膘魄,session id是不會(huì)變的,共享成功
分別對(duì)2臺(tái)redis進(jìn)行啟停竭讳,也不會(huì)影響session共享
redis-cli -h 1.1.1.111
keys *
臥槽创葡,老子終于完成
Tips:后面redis會(huì)崩潰,MISCONF Redis is configured to save RDB snapshots
解決方案如下:
運(yùn)行 config set stop-writes-on-bgsave-error no 命令
關(guān)閉配置項(xiàng)stop-writes-on-bgsave-error解決該問題绢慢。