Redis 4 种模式简单了解

/ RedisClusterSentinel / 1 条评论 / 15503浏览

Redis 模式(Redis Mode)

Redis 有很多种部署方式,单点(Standalone)、主从(Master-Slave)、哨兵(Sentinel)、集群(Cluster)。

单点(Standalone)

最简单的方式,同时也是风险最高的方式,相比其他几种方式做不到HA、Failover、,也不能读写分离,也不能对应高吞吐量。安装方式也很简单这里就不赘述了。

主从模式(Master Slave)

2019729172044-Redis-master-slave

主从模式同样不具备HA、Failover、等,单可用于读写分离的场景,写操作走Master节点,读操作走Slave节点,能在一定程度提高读写的吞吐量。

主要配置(Master Slaver Config)

vim redis.conf
# 以守护进程的方式运行
daemonize yes
port 6379
# 绑定的主机地址
bind 0.0.0.0
# 指定当本机为slave服务时,设置master服务的IP地址及端口,在redis启动的时候他会自动跟master进行数据同步
slaveof <masterip> <masterport>
# 当master设置了密码保护时,slave服务连接master的密码
masterauth <master-password>
# 设置redis连接密码,如果配置了连接密码,客户端在连接redis是需要通过AUTH<password>命令提供密码,默认关闭
requirepass footbared

注意上面的 slaveof <masterip> <masterport> 填写的是 master 节点的 IP 和端口,也就是说填写这两个参数的节点是 Slave 节点。 为了简单验证,可以单独拷贝一份配置文件,目录如下:

➜  redis-master-slave tree
.
├── 6380
│   ├── redis-master.conf
│   ├── redis-master.log
│   └── redis-server.pid
├── 6381
│   ├── redis-server.pid
│   ├── redis-slave.conf
│   └── redis-slave.log
└── start.sh
# 启动脚本
redis-server ./6380/redis-master.conf
redis-server ./6381/redis-slave.conf

哨兵模式(Sentinel)

2019729201954-redis-sentinel

Ubuntu 安装(Sentinel Install)

sudo apt-get install redis-sentinel

配置(Sentinel Config)

主要配置

vim sentinel-26379.conf
pidfile /home/xxx/Documents/company/redis-sentinel/26379/redis-sentinel.pid
logfile /home/xxx/Documents/company/redis-sentinel/26379/redis-sentinel.log
bind 0.0.0.0
port 26379
# 哨兵 sentinel 监控的 redis 主节点的 
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
# 这个2代表,当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了。
sentinel monitor mymaster 10.201.12.66 6380 2
# 当在Redis实例中开启了requirepass <foobared>,所有连接Redis实例的客户端都要提供密码。
sentinel auth-pass mymaster test@123456
# 指定主节点应答哨兵sentinel的最大时间间隔,超过这个时间,哨兵主观上认为主节点下线,默认30秒 
# Default is 30 seconds.
sentinel down-after-milliseconds mymaster 30000
# 指定了在发生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

启动脚本(Start Script)

一个简单的启动脚本

echo "Starting sentinel-26380"
redis-sentinel /home/xxx/Documents/company/redis-sentinel/26380/sentinel-26380.conf
echo "Starting sentinel-26381"
redis-sentinel /home/xxx/Documents/company/redis-sentinel/26381/sentinel-26381.conf
echo "Starting sentinel-26382"
redis-sentinel /home/xxx/Documents/company/redis-sentinel/26382/sentinel-26382.conf

日志(Sentinel Log)

部分 sentinel 节点日志

6258:X 30 Jul 11:21:01.003 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
6258:X 30 Jul 11:21:01.003 # Sentinel runid is 0984fa31f919e6a66891d7c44623a22cd1bd1718
6258:X 30 Jul 11:21:01.003 # +monitor master mymaster 10.201.12.66 6380 quorum 2
6258:X 30 Jul 11:21:01.004 * +slave slave 10.201.12.66:6381 10.201.12.66 6381 @ mymaster 10.201.12.66 6380
6258:X 30 Jul 11:21:03.028 * +sentinel sentinel 10.201.12.66:26382 10.201.12.66 26382 @ mymaster 10.201.12.66 6380
6258:X 30 Jul 11:21:03.050 * +sentinel sentinel 10.201.12.66:26381 10.201.12.66 26381 @ mymaster 10.201.12.66 6380

Sentinel 状态(Sentinel State)

# redis-cli 连接 Sentinel
redis-cli -h 10.201.12.66 -p 26380 -a 'test@123456'
# 查看当前主节点
10.201.12.66:26380> SENTINEL get-master-addr-by-name mymaster
1) "10.201.12.66"
2) "6380"

#显示被监控的所有 主节点 以及它们的状态。
SENTINEL masters
# 显示指定 主节点 的信息和状态。
SENTINEL master <master_name>
# 显示指定 主节点 的所有 从节点 以及它们的状态。
SENTINEL slaves <master_name>

故障切换测试(Failover Test)

# 查看当前主节点
10.201.12.66:26380> SENTINEL get-master-addr-by-name mymaster
1) "10.201.12.66"
2) "6380"
# kill master 节点
➜ kill 27832
# 查看当前主节点
10.201.12.66:26380> SENTINEL get-master-addr-by-name mymaster
1) "10.201.12.66"
2) "6381"

查看哨兵节点日志

6258:X 30 Jul 11:44:43.782 # +sdown master mymaster 10.201.12.66 6380
6258:X 30 Jul 11:44:43.872 # +odown master mymaster 10.201.12.66 6380 #quorum 2/2
6258:X 30 Jul 11:44:43.872 # +new-epoch 1
6258:X 30 Jul 11:44:43.872 # +try-failover master mymaster 10.201.12.66 6380
6258:X 30 Jul 11:44:43.875 # +vote-for-leader 0984fa31f919e6a66891d7c44623a22cd1bd1718 1
6258:X 30 Jul 11:44:43.875 # 10.201.12.66:26381 voted for 014b4a1dca557af06293c1e2e84cfe8233e38c2f 1
6258:X 30 Jul 11:44:43.880 # 10.201.12.66:26382 voted for 014b4a1dca557af06293c1e2e84cfe8233e38c2f 1
6258:X 30 Jul 11:44:44.970 # +config-update-from sentinel 10.201.12.66:26381 10.201.12.66 26381 @ mymaster 10.201.12.66 6380
6258:X 30 Jul 11:44:44.970 # +switch-master mymaster 10.201.12.66 6380 10.201.12.66 6381
6258:X 30 Jul 11:44:44.970 * +slave slave 10.201.12.66:6380 10.201.12.66 6380 @ mymaster 10.201.12.66 6381
6258:X 30 Jul 11:45:15.015 # +sdown slave 10.201.12.66:6380 10.201.12.66 6380 @ mymaster 10.201.12.66 6381

从以上日志可以清楚的看到故障恢复成功,Slave 节点切换成了 Master 节点,并且能正常读写

重启节点

重启被 kill 掉的节点,发现该节点变成了 Slave 节点,并且是只读的,默认的配置中 Slave 节点是只读的。

哨兵节点部分日志

6258:X 30 Jul 14:18:42.387 # -sdown slave 10.201.12.66:6380 10.201.12.66 6380 @ mymaster 10.201.12.66 6381

Spring Boot 整合

参考 Github 代码

Cluster Mode

集群模式有多种实现方法,比如:

这里我们使用查询路由方案:客户端随机地 请求任意一个 Redis 实例,然后由 Redis 将请求 转发 给 正确 的 Redis 节点。Redis Cluster 实现了一种 混合形式 的 查询路由,但并不是 直接 将请求从一个 Redis 节点 转发 到另一个 Redis 节点,而是在 客户端 的帮助下直接 重定向( redirected)到正确的 Redis 节点。 Cluster 模式数据是分布在所有节点,为了达到一定程度上的高可用,需要给 Master 节点备份一个 Slave 节点;在 Cluster 模式下当 Master 节点 Down 掉的时候,并不会自动切换,需要手动切换。 因此在使用时需要考虑自己的使用场景。

Deploy Cluster

这里只是测试就在一个机器上进行部署测试

新建集群安装目录

$ mkdir {16001,16002,16003}
# 拷贝原配置文件到各个目录
sudo cp /etc/redis/redis.conf 16001/redis-01.conf
sudo cp /etc/redis/redis.conf 16002/redis-02.conf
sudo cp /etc/redis/redis.conf 16003/redis-03.conf 

配置节点集群(Config Cluster)

vim redis-01.conf
# 更改以下配置
bind 0.0.0.0
port 16001
daemonize yes
cluster-enabled yes
cluster-config-file  nodes-16001.conf
cluster-node-timeout 15000
appendonly yes
logfile /home/aozhang/Documents/company/redis-cluster/16001/redis-server-01.log

# 类似的配置配置其他两个节点,更改对应的 port、logfile、cluster-config-file

Start Nodes

sudo redis-server redis-01.conf
sudo redis-server redis-02.conf
sudo redis-server redis-03.conf

启动完成后,三个节点还是独立的,还需要建立集群 使用 /usr/share/doc/redis-tools/examples/redis-trib.rb 建立集群(适合Redis3、4版本,5可以直接使用)下面命令建立

redis5 建立集群

redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1

redis3、4 建立集群

/usr/share/doc/redis-tools/examples/redis-trib.rb create 10.201.12.66:16001 10.201.12.66:16002 10.201.12.66:16003

输出如下日志:

➜ /usr/share/doc/redis-tools/examples/redis-trib.rb create 10.201.12.66:16001 10.201.12.66:16002 10.201.12.66:16003
/usr/share/doc/redis-tools/examples/redis-trib.rb:1573: warning: key "threshold" is duplicated and overwritten on line 1573
>>> Creating cluster
>>> Performing hash slots allocation on 3 nodes...
Using 3 masters:
10.201.12.66:16001
10.201.12.66:16002
10.201.12.66:16003
M: 27f5657223f50af58de671a8f34b7160541c78e2 10.201.12.66:16001
   slots:0-5460 (5461 slots) master
M: 1fe62e7267f766c02ba956457a4c2473e73e9623 10.201.12.66:16002
   slots:5461-10922 (5462 slots) master
M: d4846a74d7433afc87168bc4ace9d1de9733b17a 10.201.12.66:16003
   slots:10923-16383 (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join...
>>> Performing Cluster Check (using node 10.201.12.66:16001)
M: 27f5657223f50af58de671a8f34b7160541c78e2 10.201.12.66:16001
   slots:0-5460 (5461 slots) master
M: 1fe62e7267f766c02ba956457a4c2473e73e9623 10.201.12.66:16002
   slots:5461-10922 (5462 slots) master
M: d4846a74d7433afc87168bc4ace9d1de9733b17a 10.201.12.66:16003
   slots:10923-16383 (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

这里没有指定副本拷贝,如果需要副本考本的话,再建3个节点,一个6个节点,启动后执行如下命令

➜ /usr/share/doc/redis-tools/examples/redis-trib.rb create --replicas 10.201.12.66:16001 10.201.12.66:16002 10.201.12.66:16003 10.201.12.66:16004 10.201.12.66:16005 10.201.12.66:16006

查看节点状态

➜  ~  redis-cli -c -h 10.201.12.66 -p 16001
10.201.12.66:16001> cluster nodes
1fe62e7267f766c02ba956457a4c2473e73e9623 10.201.12.66:16002 master - 0 1562816528369 2 connected 5461-10922
27f5657223f50af58de671a8f34b7160541c78e2 10.201.12.66:16001 myself,master - 0 0 1 connected 0-5460
d4846a74d7433afc87168bc4ace9d1de9733b17a 10.201.12.66:16003 master - 0 1562816527366 3 connected 10923-16383
10.201.12.66:16001> 

Spring Boot 整合

参考 Github 代码

小结

以上步骤就完成了 Redis 几种模式的部署搭建,可具体根据需求选择对应的模式;如果是存储一些敏感信息比如 Web 应用的 Session 等需要高可用,但并发量又不是特别大的场景就可以使用哨兵模式。 如果是用于高速缓存,秒杀等场景对性能要求较高,但可用性不是很高的场景则可以使用 Sentinel 模式。

参考文档(Refrence)

官方文档

Redis Cluster

Redis Sentinel & Redis Cluster - what?

Redis Sentinel, Standalone or Cluster, which is best for session?

Redis Sentinel Support

  1. 总结那里「如果是存储一些敏感信息比如 Web 应用的 Session 等需要高可用,但并发量又不是特别大的场景就可以使用哨兵模式。 如果是用于高速缓存,秒杀等场景对性能要求较高,但可用性不是很高的场景则可以使用 Sentinel 模式。」Sentinel 不就是哨兵模式吗……

    回复