Redis的三种集群方式配置

Redis有三种集群方案,主从复制,哨兵,cluster集群。

一. Redis 主从复制

1.1 什么是主从复制

主从复制是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点( master ),后者称为从节点( slave ),数据的复制是单向的,只能由主节点到从节点。默认情况下,每台 Redis 服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

1.2 全量同步

Redis 全量复制一般发生在 Slave 初始化阶段,这时 Slave 需要将 Master 上的所有数据都复制一份。具体步骤如下:

  1. 从服务器连接主服务器,发送 SYNC 命令;

  2. 主服务器接收到 SYNC 命名后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令;

  3. 主服务器 BGSAVE 执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;

  4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;

  5. 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;

  6. 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令。

1.3 增量同步

Redis 增量复制是指 Slave 初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

二. 如何配置 Redis 主从复制

2.1 Redis Master 服务器

bind 公网ip 127.0.0.1
绑定 redis 服务器网卡IP,默认为127.0.0.1,即本地回环地址。这样的话,访问 redis服务只能通过本机的客户端连接,而无法通过远程连接。如果 bind 选项为空的话,那会接受所有来自于可用网络接口的连接
== protected-mode no ==
保护模式,默认是开启状态,只允许本地客户端连接
daemonize yes
默认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成 yes。当 redis 作为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面。
appendonly yes
#默认 redis 使用的是 rdb 方式持久化,这种方式在许多应用中已经足够用了。但是redis 如果中途宕机,会导致可能有几分钟的数据丢失,根据 save 来策略进行持久化,Append Only File 是另一种持久化方式,可以提供更好的持久化特性。Redis 会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时 Redis 都会先把这个文件的数据读入内存里,先忽略 RDB 文件。
如果需要设置密码,则添加 requirepass 123456(自己的密码)

重启 redis 服务器(先杀死进程,在加载配置文件启动)

2.2 Redis Slave 服务器

bind 公网ip 127.0.0.1
slaveof 主节点ip 6379(主节点的ip和端口)
#此处为自己的云服务对外网的ip,如果你用的是局域网搭建,则写自己局域网Master 绑定的ip,端口6379
因为 Master 服务器设置了密码,所以 Slave 还需要加上
masterauth 123456 (验证 Master 的密码,此密码为 Master 的密码
requirepass 123456 (给 Slave 设置密码,可设置可不设置,自己选择)

重启 redis 服务器(先杀死进程,在加载配置文件启动)

2.3 测试主从读写功能,主(读写),从(只读)

在主节点cli输入 info relication 去查看主从是否生效,生效后测试主节点功能(读写)

测试从节点功能(只读)

三. Redis 哨兵集群

哨兵是 Redis 的一种运行模式,它专注于对 Redis 实例(主节点、从节点)运行状态的监控,并能够在主节点发生故障时通过一系列的机制实现选主及主从切换,实现故障转移,确保整个 Redis 系统的可用性。结合 Redis 的 官方文档:https://redis.io/topics/sentinel 可以知道 Redis 哨兵具备的能力有如下几个:

  • 监控:持续监控 master 、slave 是否处于预期工作状态。

  • 自动切换主库:当 Master 运行故障,哨兵启动自动故障恢复流程:从 slave 中选择一台作为新 master。

  • 通知:让 slave 执行 replicaof ,与新的 master 同步;并且通知客户端与新 master 建立连接。

Sentinel 监控 master,slave 的工作状态有以下几种方式:

  1. 周期性检查:哨兵定期向Redis主从节点发送PING命令,来检查节点是否还活着。如果节点在一定时间内没有响应,哨兵将标记节点为不可用,然后继续监控其状态。

  2. 故障检测:哨兵集群会在一段时间内持续监控主节点的状态。如果主节点在一定时间内没有响应,哨兵将进行故障检测,并尝试执行自动故障转移。

  3. 客从连接状态:哨兵也会监视主从节点之间的连接状态。当从节点与主节点失去连接时,哨兵将会主动寻找其他可用的从节点,并将其晋升为新的主节点。

  4. 事件订阅:哨兵通过订阅Redis节点的事件通知,可及时获取节点状态的变化,如主从切换、连接状态改变等。

除了上述的监控方式,当哨兵集群发现某个节点状态异常时,还会经历以下一些特定的故障转移过程:

  1. 选举:当哨兵发现主节点不可用时,它会向其他哨兵节点发起选举,选出新的主节点。

  2. 故障转移:选出新的主节点后,哨兵会通知集群中的客户端来连接新的主节点,并更新集群的状态信息。

四. 如何配置 Redis 哨兵集群

配置哨兵实例运行的配置文件# 哨兵sentinel实例运行的端口 默认26379

port 26379

# 将`daemonize`由`no`改为`yes`

daemonize yes

# 哨兵sentinel监控的redis主节点的 ip port

# master-name 可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。

# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了

# sentinel monitor <master-name> <ip> <redis-port> <quorum>

sentinel monitor mymaster192.168.181.130 6379 2

#可选

# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提供密码

# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码

# sentinel auth-pass <master-name> <password>

sentinel auth-pass mymasterMySUPER--secret-0123passw0rd (可选)

# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒,改成3秒

# sentinel down-after-milliseconds <master-name> <milliseconds>

sentinel down-after-milliseconds mymaster 3000

# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。

# sentinel parallel-syncs <master-name> <numslaves>

sentinel parallel-syncs mymaster 1

# 故障转移的超时时间 failover-timeout 可以用在以下这些方面:

#1. 同一个sentinel对同一个master两次failover之间的间隔时间。

#2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。

#3.当想要取消一个正在进行的failover所需要的时间。

#4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了

# 默认三分钟

# sentinel failover-timeout <master-name> <milliseconds>

sentinel failover-timeout mymaster 180000

需要注意的是因为配置了哨兵集群,所以每个 Redis 实例都需要配置 requirepass 和 masterauth,这样可以确保哨兵切换主从时不会发生无法连接。

之前配的主从复制是这样的

当我们将7001端口的 Redis 进程杀死,当哨兵主观认为主Redis已下线时,它会向其他哨兵节点发送通知,请求进行故障转移的投票。这个投票过程可以确保多个哨兵节点对于故障转移操作达成共识。通常情况下,需要超过半数的哨兵节点同意才能进行故障转移,以免因为个别节点的网络波动造成误判。

之后选举出7002端口的 Redis 变为主Redis,这样就完成了故障转移的过程,保障了Redis的高可用性和可靠性。

五. 如何配置 Redis 分片集群

5.1.集群结构

分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点。

IP

PORT

角色

192.168.150.101

7001

master

192.168.150.101

7002

master

192.168.150.101

7003

master

192.168.150.101

8001

slave

192.168.150.101

8002

slave

192.168.150.101

8003

slave

5.2.准备实例和配置

删除之前的7001、7002、7003这几个目录,重新创建出7001、7002、7003、8001、8002、8003目录:

# 进入/tmp目录

cd /tmp

# 删除旧的,避免配置干扰

rm -rf 7001 7002 7003

# 创建目录

mkdir 7001 7002 7003 8001 8002 8003

在/tmp下准备一个新的redis.conf文件,内容如下:

port 6379

# 开启集群功能

cluster-enabled yes

# 集群的配置文件名称,不需要我们创建,由redis自己维护

cluster-config-file /tmp/6379/nodes.conf

# 节点心跳失败的超时时间

cluster-node-timeout 5000

# 持久化文件存放目录

dir /tmp/6379

# 绑定地址

bind 0.0.0.0

# 让redis后台运行

daemonize yes

# 注册的实例ip

replica-announce-ip 192.168.150.101

# 保护模式

protected-mode no

# 数据库数量

databases 1

# 日志

logfile /tmp/6379/run.log

将这个文件拷贝到每个目录下:

# 进入/tmp目录

cd /tmp

# 执行拷贝

echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:

# 进入/tmp目录

cd /tmp

# 修改配置文件

printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf

5.3.启动

因为已经配置了后台启动模式,所以可以直接启动服务:

# 进入/tmp目录

cd /tmp

# 一键启动所有服务

printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf

通过ps查看状态:

ps -ef | grep redis

发现服务都已经正常启动:

如果要关闭所有进程,可以执行命令:

ps -ef | grep redis | awk '{print $2}' | xargs kill

或者(推荐这种方式):

printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown

5.4.创建集群

虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。

我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。

1)Redis5.0之前

Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

# 安装依赖

yum -y install zlib ruby rubygems

gem install redis

然后通过命令来管理集群:

# 进入redis的src目录

cd /tmp/redis-6.2.4/src

# 创建集群

./redis-trib.rb create --replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

2)Redis5.0以后

我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:

redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003

命令说明:

  • redis-cli --cluster或者./redis-trib.rb:代表集群操作命令

  • create:代表是创建集群

  • --replicas 1或者--cluster-replicas 1 :指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master

运行后的样子:

这里输入yes,则集群开始创建:

通过命令可以查看集群状态:

redis-cli -p 7001 cluster nodes

5.5.测试

集群操作时,需要给redis-cli加上-c参数才可以:

redis-cli -c -p 7001

这次可以了: