要搭建Redis集群高可用

一.部署

因为架构要求,只分配了两台服务器,要搭建Redis集群,为此针对两台服务器搭建了一套特殊的哨兵集群,特殊在不能无限切换,
只能抗住1-2次宕机或网络故障,1-2次故障之后,集群切换机制便不能使用,需要人工按后文的步骤修复;
在这里插入图片描述

1.前期准备

准备AB两台服务器部署Redis集群,选择A服务器作为主节点服务器,B服务器作为从节点服务器;

默认服务器上已安装docker环境;

1)在两台服务器创建目录

sudo mkdir -p /iids/redis
 
  • 1

2)将redis镜像文件redis_6.0.tar.gz上传到redis目录中,并导入镜像

#导入镜像
gunzip -c redis_6.0.tar.gz | docker load
 
  • 1
  • 2
2.部署主节点服务器

1)上传redis-master.sh脚本到/iids目录下(见后文)

2)赋予脚本权限

cd /iids
chmod +x redis-master.sh
 
  • 1
  • 2

3)执行脚本

./redis-master.sh 127.0.0.1 #ip修改为当前服务器地址
 
  • 1
3.部署从节点服务器

1)上传redis-slave.sh脚本到/iiids目录下(见后文)

2)赋予脚本权限

cd /iids
chmod +x redis-slave.sh
 
  • 1
  • 2

3)执行脚本

./redis-slave.sh 127.0.0.1 127.0.0.2  #ip1修改为主节点服务器地址 #ip2为当前服务器地址
 
  • 1
4.验证节点是否正常
#进入任一哨兵容器
docker exec -it redis-sentinel-26679 bash
#登录redis(替换ip)
redis-cli -h 127.0.0.1 -p 26382
#查看主节点
SENTINEL masters
#查看从节点
SENTINEL slaves mymaster
#查看集群信息
info
#退出redis
exit
#退出哨兵容器
exit
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

输入info:

显示slaves=1,sentinels=3则为正常;

image.png

或者在/iids/redis-master/sentinel-26379/log/下查看哨兵日志文件

image.png

二.维护

1.场景一:主节点(A)服务器宕机

此时redis集群主节点被选举到了B服务器上,当A服务器恢复后,在A服务器上执行以下操作:

1)删除旧镜像

docker stop redis-6379  redis-sentinel-26379 
docker rm   redis-6379  redis-sentinel-26379
 
  • 1
  • 2

2)执行脚本重启A服务器redis;

A服务器redis集群重启后,A服务器上节点都是从节点,该步骤的目的是将B服务器上redis节点的数据同步在A服务器redis节点上;避免下一步操作,重新部署A服务器上节点为主节点时,出现数据丢失

./redis-master.sh 127.0.0.1 #ip修改为当前服务器地址
 
  • 1

3)重启整个集群

A服务器:

#删除镜像
docker stop redis-6379  redis-sentinel-26379 
docker rm   redis-6379  redis-sentinel-26379
 
  • 1
  • 2
  • 3

B服务器:

#删除镜像
docker stop redis-6379  redis-sentinel-26379 redis-sentinel-26380
docker rm   redis-6379  redis-sentinel-26379 redis-sentinel-26380
 
  • 1
  • 2
  • 3

A服务器:

#执行脚本
./redis-master.sh 127.0.0.1 #ip修改为当前服务器地址
 
  • 1
  • 2

B服务器:

#执行脚本
./redis-slave.sh 127.0.0.1 127.0.0.2  #ip1修改为主节点服务器地址 #ip2为当前服务器地址
 
  • 1
  • 2

验证:

同上方式验证节点状态

1.场景二:从(B)服务器宕机

直接执行脚本重启:

#删除镜像
docker stop redis-6379  redis-sentinel-26379 redis-sentinel-26380
docker rm   redis-6379  redis-sentinel-26379 redis-sentinel-26380 

#执行脚本
./redis-slave.sh 127.0.0.1 127.0.0.2  #ip1修改为主节点服务器地址 #ip2为当前服务器地址
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

验证:

同上方式验证节点状态

三.执行脚本

redis-master.sh

#!/bin/bash

#接收外部参数
echo "===1.接收外部参数master_ip:$1===="
master_ip=$1

#主从节点port
master_port="6379"

#哨兵节点port
sentinel1_port="26379"

rm -rf /iids/redis-master
echo "===2.开始安装主从节点===="
sudo mkdir -p /iids/redis-master/redis-$master_port/db/log
sudo mkdir -p /iids/redis-master/redis-$master_port/db/data
#授权
chmod 777 /iids/redis-master/redis-$master_port/db/log
chmod 777 /iids/redis-master/redis-$master_port/db/data

#创建节点配置文件

cat > /iids/redis-master/redis-$master_port/db/redis.conf << EOF
protected-mode no
port $master_port
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/$master_port.pid
loglevel notice
logfile "/var/log/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
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
aof-use-rdb-preamble 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-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
EOF

echo "===3.开始启动节点容器===="
sudo docker run \
-d \
--network host \
--restart=always \
--name redis-$master_port \
--privileged=true \
-v /iids/redis-master/redis-$master_port/db/redis.conf:/etc/redis/redis.conf \
-v /iids/redis-master/redis-$master_port/db/data:/data  \
-v /iids/redis-master/redis-$master_port/db/log:/var/log \
-v /etc/localtime:/etc/localtime:ro \
redis:6.0 \
redis-server /etc/redis/redis.conf

echo "===4.开始安装哨兵节点===="
 

#创建宿主机挂在目录
sudo mkdir -p /iids/redis-master/sentinel-$sentinel1_port/log
sudo mkdir -p /iids/redis-master/sentinel-$sentinel1_port/data
#授权
chmod 777 /iids/redis-master/sentinel-$sentinel1_port/log
chmod 777 /iids/redis-master/sentinel-$sentinel1_port/data

#创建哨兵配置文件
cat > /iids/redis-master/sentinel-$sentinel1_port/sentinel.conf << EOF
port $sentinel1_port
protected-mode no
daemonize yes
logfile "/var/log/sentinel-$sentinel1_port.log"
#注意修改为本机内网IP
sentinel announce-ip $master_ip
sentinel announce-port $sentinel1_port
#注意修改为主节点IP
sentinel monitor mymaster ${master_ip} ${master_port} 1
sentinel down-after-milliseconds mymaster 5000
EOF
echo "===5.开始启动哨兵容器===="

#启动哨兵容器

sudo docker run -it \
--name redis-sentinel-$sentinel1_port \
--net=host \
--restart=always \
-v /iids/redis-master/sentinel-$sentinel1_port/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
-v /iids/redis-master/sentinel-$sentinel1_port/log:/var/log \
-v /etc/localtime:/etc/localtime:ro \
-d redis:6.0 /bin/bash




echo "===6.开始启动哨兵===="

#启动哨兵
sudo docker exec -it redis-sentinel-$sentinel1_port /bin/bash -c 'redis-sentinel /usr/local/etc/redis/sentinel.conf'
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151

redis-slave.sh

#!/bin/bash

#接收外部参数
echo "===1.接收外部参数master_ip:$1 local_ip:$2===="
master_ip=$1
local_ip=$2

#主从节点port
master_port="6379"
slave1_port="6379"

#哨兵节点port
sentinel1_port="26379"
sentinel2_port="26380"

rm -rf /iids/redis-slave
echo "===2.开始安装从节点===="
sudo mkdir -p /iids/redis-slave/redis-$slave1_port/db/log
sudo mkdir -p /iids/redis-slave/redis-$slave1_port/db/data
#授权
chmod 777 /iids/redis-slave/redis-$slave1_port/db/log
chmod 777 /iids/redis-slave/redis-$slave1_port/db/data

#创建节点配置文件
cat > /iids/redis-slave/redis-$slave1_port/db/redis.conf << EOF
replicaof ${master_ip} ${master_port}
protected-mode no
port $slave1_port
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_$slave1_port.pid
loglevel notice
logfile "/var/log/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 10
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
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
aof-use-rdb-preamble 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-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
EOF




echo "===3.开始启动节点容器===="

sudo docker run \
-d \
--network host \
--restart=always \
--name redis-$slave1_port \
--privileged=true \
-v /iids/redis-slave/redis-$slave1_port/db/redis.conf:/etc/redis/redis.conf \
-v /iids/redis-slave/redis-$slave1_port/db/data:/data  \
-v /iids/redis-slave/redis-$slave1_port/db/log:/var/log \
-v /etc/localtime:/etc/localtime:ro \
redis:6.0 \
redis-server /etc/redis/redis.conf



echo "===4.开始安装哨兵节点===="
 
for port in {$sentinel1_port,$sentinel2_port}
do
#创建宿主机挂在目录
sudo mkdir -p /iids/redis-slave/sentinel-$port/log
sudo mkdir -p /iids/redis-slave/sentinel-$port/data
#授权
chmod 777 /iids/redis-slave/sentinel-$port/log
chmod 777 /iids/redis-slave/sentinel-$port/data

#创建哨兵配置文件
cat > /iids/redis-slave/sentinel-$port/sentinel.conf << EOF
port $port
protected-mode no
daemonize yes
logfile "/var/log/sentinel-$port.log"
#注意修改为本机内网IP
sentinel announce-ip ${local_ip}
sentinel announce-port $port
#注意修改为主节点IP
sentinel monitor mymaster ${master_ip} ${master_port} 1
sentinel down-after-milliseconds mymaster 5000
EOF
done


echo "===5.开始启动哨兵容器===="

#启动哨兵容器
for port in {$sentinel1_port,$sentinel2_port}
do
sudo docker run -it \
--name redis-sentinel-$port \
--net=host \
--restart=always \
-v /iids/redis-slave/sentinel-$port/sentinel.conf:/usr/local/etc/redis/sentinel.conf \
-v /iids/redis-slave/sentinel-$port/log:/var/log \
-v /etc/localtime:/etc/localtime:ro \
-d redis:6.0 /bin/bash
done


echo "===6.开始启动哨兵===="
for port in {$sentinel1_port,$sentinel2_port}
do
#启动哨兵
sudo docker exec -it redis-sentinel-$port /bin/bash -c 'redis-sentinel /usr/local/etc/redis/sentinel.conf'
done
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
 
posted @ 2023-08-23 17:02  MaskerFan  阅读(51)  评论(0编辑  收藏  举报