哨兵模式
- 原理
由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。也就是应用程序连接redis哨兵的三个端口但最后返回redis主的ip和端口,进行读写redis数据。
部署
- 创建redis用户,创建如下目录,把下载redis复制为如下目录
[redis@redis ~]$ ls
6379 6380 6381
6379 修改配置文件
- redis.conf
daemonize yes
pidfile "redis6379.pid"
port 6379
tcp-backlog 511
bind 192.168.128.34
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/home/redis/redis-env/6379/6379.log"
databases 16
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/home/redis/redis-env/6379"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-tru
- sentinel.conf
port 27379
bind 192.168.128.34
sentinel monitor server-1M 192.168.128.34 6379 2
sentinel failover-timeout server-1M 300000
sentinel config-epoch server-1M 11
sentinel leader-epoch server-1M 11
dir "/home/redis/redis-env/6379"
maxmemory 3gb
maxmemory-policy noeviction
sentinel known-slave server-1M 192.168.128.34 6380
sentinel known-slave server-1M 192.168.128.34 6381
sentinel known-sentinel server-1M 192.168.128.34 27381 6405d1ab6632fbc20a97f65430a66d211392bf12
sentinel known-sentinel server-1M 192.168.128.34 27380 3e6fda7297f80711df260d924c9bebbc004d999a
sentinel current-epoch 11
6380 修改配置文件
- redis.conf
daemonize yes
pidfile "redis6380.pid"
port 6380
tcp-backlog 511
bind 192.168.128.34
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/home/redis/redis-env/6380/6380.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/home/redis/redis-env/6380"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
maxclients 3000
maxmemory 3gb
maxmemory-policy noeviction
slaveof 192.168.128.34 6379
- sentinel.conf
port 27380
bind 192.168.128.34
sentinel monitor server-1M 192.168.128.34 6379 2
sentinel failover-timeout server-1M 300000
sentinel config-epoch server-1M 11
sentinel leader-epoch server-1M 11
dir "/home/redis/redis-env/6380"
maxmemory 3gb
maxmemory-policy noeviction
sentinel known-slave server-1M 192.168.128.34 6381
sentinel known-slave server-1M 192.168.128.34 6380
sentinel known-sentinel server-1M 192.168.128.34 27379 49922ded8bc33f23e37fa36535cb99f4e95150c7
sentinel known-sentinel server-1M 192.168.128.34 27381 6405d1ab6632fbc20a97f65430a66d211392bf12
sentinel known-sentinel server-1M 192.168.128.34 27380 3e6fda7297f80711df260d924c9bebbc004d999a
sentinel current-epoch 11
6381 修改配置文件
- redis.conf
daemonize yes
pidfile "redis6381.pid"
port 6381
tcp-backlog 511
bind 192.168.128.34
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/home/redis/redis-env/6381/6381.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/home/redis/redis-env/6381"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
maxclients 3000
maxmemory 3gb
maxmemory-policy noeviction
slaveof 192.168.128.34 6379
- sentinel.conf
port 27381
bind 192.168.128.34
sentinel monitor server-1M 192.168.128.34 6379 2
sentinel failover-timeout server-1M 300000
sentinel config-epoch server-1M 11
sentinel leader-epoch server-1M 11
dir "/home/redis/redis-env/6381"
maxmemory 3gb
maxmemory-policy noeviction
sentinel known-slave server-1M 192.168.128.34 6380
sentinel known-slave server-1M 192.168.128.34 6381
sentinel known-sentinel server-1M 192.168.128.34 27379 49922ded8bc33f23e37fa36535cb99f4e95150c7
sentinel known-sentinel server-1M 192.168.128.34 27380 3e6fda7297f80711df260d924c9bebbc004d999a
sentinel known-sentinel server-1M 192.168.128.34 27381 6405d1ab6632fbc20a97f65430a66d211392bf12
sentinel current-epoch 11
redis启动脚本
- 脚本,可直接复制使用
#!/bin/bash
#########################################################################################
################ service info ###########################################
#########################################################################################
ALIAS[0]="redis";
ALIAS[1]="sentinel";
PROC[0]="redis-server";
PROC[1]="redis-sentinel"
DIR[0]="./";
DIR[1]="./";
ARGV[0]="redis.conf"
ARGV[1]="sentinel.conf"
PORT[0]=":"`grep port ${ARGV[0]} |grep -v '#' | awk '{print $2}'`
PORT[1]=":"`grep port ${ARGV[1]} |grep -v '#' | awk '{print $2}'`
PROC_COUNT=2
CHECK_TIME=10
CHECK_LOGFILE="check.log"
CHECK_LOGFILE="/dev/null"
#########################################################################################
################################################################################33
usage()
{
echo "Usage: start.sh [options] service1 [,service2..]";
echo "Start/stop services or show files version"
echo " -c Get coredump, used with -k."
echo " -d Run a daemon script for service"
echo " -f Force kill service, used with -k"
echo " -h Print help infomation"
echo " -k Kill service"
echo " -o Get owner authority [ -o user ]"
echo " -r Restart service "
echo " -s Show service status"
echo " -v Show file version"
echo " list Show all services status"
echo " Note: If no option ,default to start a service. "
echo ""
echo "Valid shortcut for services:"
echo " redis"
echo " "
echo "Example: "
echo " \"start.sh list\" View status of all services."
echo " \"start.sh redis\" Start redis."
echo " \"start.sh -d redis\" Start redis with a daemon."
echo " \"start.sh cut_table redis\" Start cut_table and redis."
echo " \"start.sh -v redis\" Show redis version."
echo " \"start.sh -s redis\" Show redis status."
echo " \"start.sh -k redis\" Stop redis."
echo " \"start.sh -r redis\" Restart redis."
echo " \"start.sh -kd redis\" Stop redis and its daemon."
echo " \"start.sh -kf redis\" Force,kill redis immediately."
echo " \"start.sh all\" Start all services at once."
echo " \"start.sh -k all\" Stop all services at once."
}
echo_w()
{
width=`expr 60 - $1`
f=`printf "%ds" $width`
printf "%$f\n" "$2"
}
set_ulimit()
{
core_limit=`ulimit -c`
[ $core_limit="0" ]
if [ $? -eq "0" ]; then
ulimit -c unlimited
#echo "ulimit set"
fi;
}
checkDaemonRunning()
{
#ret=`ps -u $WHO -o pid -o comm -o cmd|grep "$SCRIPT_NAME -a -d $1" | grep "$2" |grep -v grep|awk '{print $1}'`;
ret=`ps -u $WHO elf|grep "$SCRIPT_NAME -a -d $1" | grep "$2" |grep -v grep|awk '{print $3}'`;
echo $ret
if [ "$ret" = "" ]; then
return 0;
else
return 1;
fi
}
checkRunning()
{
#ret=`ps -u $WHO -o pid -o comm|grep $1 | grep "$2" |awk '{print $1}'`;
ret=`ps -u $WHO elf|grep $1 | grep "$2" |awk '{print $3}'`;
echo $ret
if [ -z "$ret" ]; then
return 0;
else
return 1;
fi
#proc=`ps aux | grep $1 | grep -v grep`
#echo $proc
#if [ -z "$proc" ]; then
# return 0;
#else
# return 1;
#fi
}
show_status()
{
proc=${PROC[$1]}
ret=`checkRunning $proc ${PORT[$1]}`;
if [ $? -ne 0 ];then
str="$proc (pid $ret ${PORT[$1]})";
len=`expr length "$str"`;
echo -n $str
ret=`checkDaemonRunning ${ALIAS[$1]} ${PORT[$1]}`;
if [ $? -ne 0 ];then
echo_w `expr $len - 10` "[daemon][�[32mrunning�[0m]";
else
echo_w `expr $len - 10` "[�[32mrunning�[0m]";
fi
else
echo -n $proc
len=`expr length "$proc"`;
echo_w `expr $len - 10` "[�[31mstopped�[0m]";
fi
}
restart_proc()
{
kill_proc $1;
# [ $? -ne 0 ]&& return;
start_proc $1;
}
kill_daemon()
{
len=`expr length "${PROC[$1]} daemon"`
ret=`checkDaemonRunning ${ALIAS[$1]} ${PORT[$1]}`;
if [ $? -ne 0 ];then
echo -n "stoping ${PROC[$1]} ${PORT[$1]} daemon .";
for pid in "$ret"
do
kill -9 $pid;
done
echo_w $len "[�[31mstopped�[0m]";
fi
}
kill_proc()
{
result=1;
[ "$DAEMON" = "true" ] && kill_daemon $1;
proc=${PROC[$1]}
echo -n "stoping $proc ${PORT[$1]}.";
len=`expr length "$proc"`
ret=`checkRunning $proc ${PORT[$1]}`;
if [ $? -ne 0 ];then
for pid in "$ret"
do
if [ "$FORCE" = "true" ];then
kill -9 $pid;
elif [ "$CORE" = "true" ];then
kill -6 $pid;
else
kill -9 $pid;
fi
for((t=0; t<10; t++))
do
echo -n "."
len=`expr $len + 1`
ret=`checkRunning $proc ${PORT[$1]}`;
if [ $? -ne 0 ];then
sleep 1;
else
echo_w $len "[�[31mstopped�[0m]";
result=0;
break;
fi
if [ $t -eq 8 ];then
echo_w $len "[�[32mrunning�[0m]";
KILLFAILED=true;
fi
done
done
else
echo -n ".."
echo_w `expr $len + 2` "[�[31mstopped�[0m]";
fi
return $result;
}
start_daemon()
{
$SCRIPT_NAME -a -d ${ALIAS[$1]} >/dev/null 2>&1 &
echo "starting daemon for ${PROC[$1]}... OK";
# ret=`checkDaemonRunning ${ALIAS[$1]}`;
# if [ $? -ne 0 ];then
# echo "already a instance running ...";
# else
# $SCRIPT_NAME -a -d ${ALIAS[$1]} >/dev/null 2>&1 &
# echo "starting daemon for ${PROC[$1]}... OK";
# fi
}
start_real_daemon()
{
while true
do
start_proc $1
if [ $? = 2 ];then
echo "`date`: start daemon ${PROC[$1]} ok" >> daemon.log
elif [ $? = 3 ];then
echo "`date`: start daemon ${PROC[$1]} failed" >> daemon.log
fi
sleep $CHECK_TIME
done
}
start_proc()
{
proc=${PROC[$1]}
echo -n "starting $proc ";
len=`expr length "$proc"`
ret=`checkRunning $proc ${PORT[$1]}`;
cret=$?;
if [ "$ISLIST" != "true" ]; then
echo "`date` check $proc ${PORT[$1]} return=[$ret] [$cret]" >> $CHECK_LOGFILE
fi
if [ $cret -ne 0 ] || [ "$ret" != "" ]; then
echo -n ".."
echo_w `expr $len + 2` "[�[31mFAILED�[0m]"
echo "Error:$proc ${PORT[$1]} already have a instance (pid $ret)";
return 1
else
cd ${DIR[$1]}
nohup ./$proc ${ARGV[$1]} >/dev/null 2>&1 &
cd - >> /dev/null 2>&1
for t in 1 2 3
do
echo -n "."
len=`expr $len + 1`
sleep 1
done
echo -n "."
ret=`checkRunning $proc ${PORT[$1]}`;
if [ $? -ne 0 ];then
echo_w `expr $len + 1` "[�[32m OK �[0m]";
return 2
else
echo_w `expr $len + 1` "[�[31mFAILED�[0m]";
return 3
fi
fi
}
show_version()
{
echo "====================== ${PROC[$1]} Version Info ======================";
cd bin
./${PROC[$1]} --version
cd ..
}
do_process()
{
if [ "$KILL" = "true" ];then
kill_proc $1;
return;
fi
if [ "$RESTART" = "true" ];then
restart_proc $1;
return;
fi
if [ "$VERSION" = "true" ];then
show_version $1;
fi
if [ "$STATUS" = "true" ];then
show_status $1;
fi
if [ "$START" = "true" ];then
start_proc $1;
fi
if [ "$DAEMON" = "true" ] && [ "$EXPAND" != "true" ];then
start_daemon $1
fi
if [ "$DAEMON" = "true" ] && [ "$EXPAND" == "true" ];then
start_real_daemon $1;
fi
}
##=========================================================================================================
##=========================================================================================================
##=
##=========================================================================================================
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/lib
KILL=false;
VERSION=false;
STATUS=false;
START=true;
FORCE=false;
CORE=false;
DAEMON=false;
RESTART=false;
EXPAND=false;
WHO=`whoami`;
OWN=`stat -c %U $0`
KILLFAILED=false;
SCRIPT_NAME=$0
ISLIST=false;
while getopts :krvsahfcdo: OPTION
do
case $OPTION in
a)
EXPAND=true;
START=false;;
k)
KILL=true;
START=false;;
v)
START=false;
VERSION=true;;
s)
START=false;
STATUS=true;;
f)
FORCE=true;;
r)
START=false;
RESTART=true;;
c)
START=false;
CORE=true;;
o)
WHO=$OPTARG;;
d)
START=false;
DAEMON=true;;
h)
usage;
exit 0;;
\?)
echo "start.sh: invalid option"
echo "Tyr \"start.sh -h\" for more infomation."
exit;;
esac
done
shift `expr $OPTIND - 1`;
if [ "$#" = "0" ];then
echo "start.sh: missing operand."
echo "Try \"start.sh -h\" for more infomation."
exit 1;
fi
if [ $OWN != $WHO ];then
echo "start.sh:sorry [$WHO], the owner is [$OWN]."
echo "Add option \"-o $OWN\" to ignore this."
echo "Try \"start.sh -h\" for more infomation."
exit 1;
fi
set_ulimit;
for proc in "$@"
do
num=-1
proc=`tr A-Z a-z <<< $proc`;
if [ "$proc" = "list" ];then
ISLIST=true;
for((i=0; i<PROC_COUNT; i++))
do
show_status $i;
done
exit 0;
fi
if [ "$proc" = "all" ];then
for((i=0; i<PROC_COUNT; i++))
do
do_process $i;
done
exit 0;
fi
for((i=0; i<PROC_COUNT; i++))
do
if [ "$proc" = "${ALIAS[$i]}" ]; then
num=$i;
break;
fi
done
if [ $num -ne -1 ];then
do_process $num;
else
echo "start.sh: wrong service name [$proc]. "
echo "Try \"start.sh -h\" for more infomation."
exit 1;
fi
done
if [ "$KILLFAILED" = "true" ];then
echo " ----"
echo "If they are still running , check it later use command \"start.sh list\"";
echo "Also can use \"start.sh -kf SERVICES\" to kill them immediately"
fi
exit 0;
- 脚本说明
[redis@redis 6379]$ ./start.sh list
redis-server (pid 2620 :6379) [running]
redis-sentinel (pid 3164 :27379) [running]
[redis@redis 6379]$ ./start.sh redis
[redis@redis 6379]$ ./start.sh sentinel
网友评论