Redis高可用及集群

时间:2021-09-24 04:56:34

Redis主从复制

  • 使用异步复制
  • 一个服务器可以有多个从服务器
  • 从服务器也可以有自己的从服务器
  • 复制功能不会阻塞主服务器
  • 可以通过服务功能来上主服务器免于持久化操作,由从服务器去执行持久化操作即可。

Redis高可用及集群

以下是关于Redis复制功能的几个重要方面:

  • Redis使用异步复制。从Redis 2.8开始,从服务器会以每秒一次的频率向主服务器报告复制流(replication stream)的处理进度。
  • 一个主服务器可以有多个从服务器。
  • 不仅主服务器可以有从服务器,从服务器也可以有自己的从服务器,多个从服务器之间可以构成一个图状结构。
  • 复制功能不会阻塞主服务器: 即使有一个或多个从服务器正在进行初次同步, 主服务器也可以继续处理命令请求。
  • 复制功能也不会阻塞从服务器: 只要在 redis.conf 文件中进行了相应的设置, 即使从服务器正在进行初次同步, 服务器也可以使用旧版本的数据集来处理命令查询。
  • 不过, 在从服务器删除旧版本数据集并载入新版本数据集的那段时间内, 连接请求会被阻塞。
  • 你还可以配置从服务器, 让它在与主服务器之间的连接断开时, 向客户端发送一个错误。
  • 复制功能可以单纯地用于数据冗余(data redundancy), 也可以通过让多个从服务器处理只读命令请求来提升扩展性(scalability): 比如说, 繁重的 SORT 命令可以交给附属节点去运行。
  • 可以通过复制功能来让主服务器免于执行持久化操作: 只要关闭主服务器的持久化功能, 然后由从服务器去执行持久化操作即可。

环境准备

首先需要准备环境,我这里准备四个redis实例:

主节点:6379

从节点:6380 - 6382

port:6379-6382 4个实例:

[root@192.168.32.130 /etc/redis]$ netstat -tunlp|grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 123988/redis-server
tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 107646/redis-server
tcp 0 0 127.0.0.1:6381 0.0.0.0:* LISTEN 108096/redis-server
tcp 0 0 127.0.0.1:6382 0.0.0.0:* LISTEN 108110/redis-server

启动多个实例的方法:

启动脚本:	复制到你的脚本中即可
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem. REDISPORT=$1
EXEC=/data/app/redis/src/redis-server
CLIEXEC=/data/app/redis/src/redis-cli PIDFILE=/var/run/redis_${REDISPORT}.pid
CONF="/etc/redis/${REDISPORT}.conf"
PWD="root" case "$2" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
$EXEC $CONF
fi
;;
stop)
#PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -a ${PWD} -p $REDISPORT shutdown
echo "Redis stopped"
;;
*)
echo "Please use start or stop as first argument"
;;
esac
[root@192.168.32.130 /etc/redis]$  cp 6379.conf 6380.conf
[root@192.168.32.130 /etc/redis]$ cp 6379.conf 6381.conf
[root@192.168.32.130 /etc/redis]$ cp 6379.conf 6382.conf # 批量修改端口号
[root@192.168.32.130 /etc/redis]$ sed -i 's/6379/6380/g' 6380.conf
[root@192.168.32.130 /etc/redis]$ sed -i 's/6379/6381/g' 6381.conf
[root@192.168.32.130 /etc/redis]$ sed -i 's/6379/6382/g' 6382.conf

启动多个redis实例:

[root@192.168.32.130 /etc/redis]$ /etc/init.d/redis 6380 start
Starting Redis server...
[root@192.168.32.130 /etc/redis]$ /etc/init.d/redis 6381 start
Starting Redis server...
[root@192.168.32.130 /etc/redis]$ /etc/init.d/redis 6382 start
Starting Redis server...

主从复制命令

命令行临时生效

[root@192.168.32.130 /etc/redis]$ redis-cli -a root -p 6380
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
[root@192.168.32.130 /etc/redis]$ redis-cli -a root -p 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
[root@192.168.32.130 /etc/redis]$ redis-cli -a root -p 6382
127.0.0.1:6382> SLAVEOF 127.0.0.1 6379
OK

修改配置文件重启永久生效

# 向各个实例的配置文件中追加配置:
[root@192.168.32.130 /etc/redis]$ echo 'slaveof 127.0.0.1 6379' >> 6380.conf
[root@192.168.32.130 /etc/redis]$ echo 'slaveof 127.0.0.1 6379' >> 6381.conf
[root@192.168.32.130 /etc/redis]$ echo 'slaveof 127.0.0.1 6379' >> 6382.conf # 因为主节点有密码,所有需要使用密码验证:
[root@192.168.32.130 /etc/redis]$ echo 'masterauth root' >> 6380.conf
[root@192.168.32.130 /etc/redis]$ echo 'masterauth root' >> 6381.conf
[root@192.168.32.130 /etc/redis]$ echo 'masterauth root' >> 6382.conf # redis全部实例重启
[root@192.168.32.130 /etc/redis]$ killall redis-server
[root@192.168.32.130 /etc/redis]$ /etc/init.d/redis 6379 start
Starting Redis server...
[root@192.168.32.130 /etc/redis]$ /etc/init.d/redis 6380 start
Starting Redis server...
[root@192.168.32.130 /etc/redis]$ /etc/init.d/redis 6381 start
Starting Redis server...
[root@192.168.32.130 /etc/redis]$ /etc/init.d/redis 6382 start
Starting Redis server... [root@192.168.32.130 /etc/redis]$ netstat -tunlp|grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 109549/redis-server
tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 109563/redis-server
tcp 0 0 127.0.0.1:6381 0.0.0.0:* LISTEN 109577/redis-server
tcp 0 0 127.0.0.1:6382 0.0.0.0:* LISTEN 109591/redis-server [root@192.168.32.130 /etc/redis]$ redis-cli -a root -p 6379 info Replication
# Replication
role:master
connected_slaves:3 # 表示有三个从节点
slave0:ip=127.0.0.1,port=6380,state=online,offset=155,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=155,lag=1
slave2:ip=127.0.0.1,port=6382,state=online,offset=155,lag=0 [root@192.168.32.130 /etc/redis]$ redis-cli -a root -p 6380 info Replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up # 表示已经连接到主节点 [root@192.168.32.130 /etc/redis]$ redis-cli -a root -p 6381 info Replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up # 表示已经连接到主节点 [root@192.168.32.130 /etc/redis]$ redis-cli -a root -p 6382 info Replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up # 表示已经连接到主节点 主从复制状态监控命令:
info replication
-a :指定密码连接
-p :指定端口连接 主从切换:
slaveof no one

Redis Sentinel

Redis-Sentinel是Redis官方推荐的高可用性(HA)接近方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,他能监控多个master-slave集群,发现master宕机后能进行自动切换。

Sentinel是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。

Redis高可用及集群

功能

  • 监控(Monitoring)

    Sentinel会不断地检查你的主服务器和从服务器是否运作正常。

  • 提醒(Notification)

    当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。

  • 自动故障迁移(Automatic failover)

    当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效服务器的其他从服务器改为负值新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器。

Redis Sentinel配置

[root@192.168.32.130 /usr/local/redis]$ cp /usr/local/redis/sentinel.conf /etc/redis/
# 去掉空行和注释后的配置文件:
[root@192.168.32.130 /etc/redis]$ cat sentinel.conf | grep -v "#" | grep -v "^$" > sentinel_26379.conf # 编辑添加以下内容:
port 26379
bind 127.0.0.1
dir './'
pidfile /var/run/redis-sentinel.pid
daemonize yes
logfile "sentinel_26379.log" sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster root sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000 # 拷贝其他端口的
[root@192.168.32.130 /etc/redis]$ cp sentinel_26379.conf sentinel_26380.conf
[root@192.168.32.130 /etc/redis]$ cp sentinel_26379.conf sentinel_26381.conf
[root@192.168.32.130 /etc/redis]$ cp sentinel_26379.conf sentinel_26382.conf
[root@192.168.32.130 /etc/redis]$
[root@192.168.32.130 /etc/redis]$ sed -i 's/26379/26380/g' sentinel_26380.conf
[root@192.168.32.130 /etc/redis]$ sed -i 's/26379/26381/g' sentinel_26381.conf
[root@192.168.32.130 /etc/redis]$ sed -i 's/26379/26382/g' sentinel_26382.conf [root@192.168.32.130 /usr/local/redis/src]$ cp /usr/local/redis/src/redis-sentinel /usr/bin/ [root@192.168.32.130 /usr/local/redis/src]$ redis-sentinel /etc/redis/sentinel_26380.conf
[root@192.168.32.130 /usr/local/redis/src]$ redis-sentinel /etc/redis/sentinel_26381.conf
[root@192.168.32.130 /usr/local/redis/src]$ redis-sentinel /etc/redis/sentinel_26382.conf [root@192.168.32.130 /usr/local/redis/src]$ netstat -tunlp|grep redis
tcp 0 0 127.0.0.1:26379 0.0.0.0:* LISTEN 111670/redis-sentin
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 109993/redis-server
tcp 0 0 127.0.0.1:26380 0.0.0.0:* LISTEN 111701/redis-sentin
tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 110007/redis-server
tcp 0 0 127.0.0.1:26381 0.0.0.0:* LISTEN 111714/redis-sentin
tcp 0 0 127.0.0.1:6381 0.0.0.0:* LISTEN 110022/redis-server
tcp 0 0 127.0.0.1:26382 0.0.0.0:* LISTEN 111727/redis-sentin
tcp 0 0 127.0.0.1:6382 0.0.0.0:* LISTEN 110037/redis-server # 都配置好之后,再来看配置文件,发现配置文件被重写了。:
# 出现以下像md5值一样的字符串就说明已经配置好了。
[root@192.168.32.130 /etc/redis]$ cat sentinel_26379.conf
port 26379
bind 127.0.0.1
dir "/usr/local/redis/src"
pidfile "/var/run/redis-sentinel.pid"
daemonize yes
logfile "sentinel_26379.log" sentinel myid 3067717f666b6cb157172e270f85441ecaa0c692
sentinel monitor mymaster 127.0.0.1 6379 2 sentinel auth-pass mymaster root
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-slave mymaster 127.0.0.1 6382
sentinel known-sentinel mymaster 127.0.0.1 26381 97cad0c94d3ee7927e11eb9d6edd90d3cfb16f01
sentinel known-sentinel mymaster 127.0.0.1 26382 62c515d8e0f7098fc1b66a81282c28ba83be24fd
sentinel known-sentinel mymaster 127.0.0.1 26380 b5514c5530497046ce6f9407a1386e0573b2b82f
sentinel current-epoch 0 像 port、daemonize、logfile、dir、bind 这些我就不介绍了,之前也介绍过了,这边重点介绍一下sentinel的配置
sentinel monitor <master-name> <ip> <redis-port> <quorum>
告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效 sentinel auth-pass <master-name> <password>
设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。 sentinel down-after-milliseconds <master-name> <milliseconds>
这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒 sentinel parallel-syncs <master-name> <numslaves>
这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。 sentinel failover-timeout <master-name> <milliseconds>
failover-timeout 可以用在以下这些方面:
1. 同一个sentinel对同一个master两次failover之间的间隔时间。
2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
3.当想要取消一个正在进行的failover所需要的时间。
4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。

Redis集群

Redis集群略,

请移步:

redis cluster集群部署

redis cluster 集群畅谈(一)

redis cluster 集群畅谈(二)

redis cluster 集群畅谈(三) 之 水平扩容、slave自动化迁移