Redis 集群(主从、哨兵)搭建实操

508 阅读9分钟

一、单节点实例

单节点实例还是比较简单的,平时做个测试,写个小程序如果需要用到

缓存的话,启动一个

Redis 还是很轻松的,做为一个 key/value 数据库也是可以胜任的

二、主从模式(master/slaver)

Redis 主从模式:

redis 的主从模式,使用异步复制,slave 节点异步从 master 节点复 制数据,master 节点提供读写服务,slave 节点只提供读服务(这个是默认配置,可以通过修改配置文件 slave-read-only 控制)。master 节点可以有多个从节点。配置一个 slave 节点只需要在 redis.conf 文件中指定 slaveof master-ip master-port 即可。

节点开启主从复制的方式

配置文件

在从服务器的配置文件中加入:slaveof

启动命令

redis-server 启动命令后加入:slaveof

客户端命令

Redis 服务器启动后直接通过客户端执行命令: slaveof ,则该 Redis实例成为从节点。

配置

切换到 Redis 安装路径

cd /www/server/redis/

在 config 下,新建三个配置文件

主节点配置
#新建主节点配置
vi master-6379.conf
#输入配置内容
requirepass 123456
bind 0.0.0.0
port 6379
logfile "6379.log"
dbfilename "dump-6379.rdb"
daemonize yes
rdbcompression yes

从节点配置

#新建从节点配置
vi slave-6380.conf
#输入配置内容
bind 0.0.0.0
port 6379
logfile "6379.log"
dbfilename "dump-6379.rdb"
daemonize yes
rdbcompression yes
slaveof 0.0.0.0 6379
masterauth 123456

#新建从节点配置
vi slave-6381.conf
#输入配置内容
bind 0.0.0.0
port 6381
logfile "6381.log"
dbfilename "dump-6381.rdb"
daemonize yes
rdbcompression yes
slaveof 0.0.0.0 6379
masterauth 123456

注:如果主节点设置了密码,从节点的配置文件中需要添加 masterauth <psaaword>

运行 Redis 实例

[root@localhost redis]# ./src/redis-server config/master-6379.conf 

[root@localhost redis]# ./src/redis-server config/slave-6380.conf 

[root@localhost redis]# ./src/redis-server config/slave-6381.conf

查看一下 redis 服务

[root@localhost redis]# ps aux|grep redis
redis    11575  0.0  0.7 164992  7332 ?        Ssl  18:00   0:03 /www/server/redis/src/redis-server 0.0.0.0:6379
root     13262  0.0  0.6 164992  6612 ?        Ssl  18:16   0:02 ./src/redis-server 0.0.0.0:6380
root     13275  0.0  0.4 164992  4520 ?        Ssl  18:16   0:02 ./src/redis-server 0.0.0.0:6381

测试主从模式

三个 Redis 上是否存在某个 key

[root@localhost redis]# ./src/redis-cli -p 6379 
127.0.0.1:6379> get name (nil) 
[root@localhost redis]# ./src/redis-cli -p 6380
127.0.0.1:6380> get name (nil)
[root@localhost redis]# ./src/redis-cli -p 6381 
127.0.0.1:6381> get name (nil) 
#获取的值都为空

给 master 节点 set 一个 key

[root@localhost redis]# ./src/redis-cli -p 6379
127.0.0.1:6379> set name cmy
OK
127.0.0.1:6379> get name
"cmy"

slave 节点直接读取 key 为 name 的值

[root@localhost redis]# ./src/redis-cli -p 6380
127.0.0.1:6380> get name
"cmy"
[root@localhost redis]# ./src/redis-cli -p 6381
127.0.0.1:6381> get name
"cmy"

slave 节点只提供读服务,不能进行写入操作

127.0.0.1:6381> set age 23
(error) READONLY You can't write against a read only slave.

注意:如果 master 节点未开启服务持久化,在 master 节点重启后数据会丢失,且 slave 节点会重新从 master 节点同步数据。

数据丢失的原因:因为 master 服务挂了之后,重启服务后,slave 节点会与 master 节点进行一次完整的重同步操作,所以由于 master 节点没有持久化,就导致 slave 节点上的数据也会丢失掉。所以在配置了 Redis 的主从模式的时候,应该打开主服务器的持久化功能。

三、Redis Sentinel搭建

Redis Sentinel的部署须知

  1. 一个稳健的 Redis Sentinel 集群,应该使用至少 三个 Sentinel 实例,并且保证将这些实例放到 不同的机器 上,甚至不同的 物理区域
  2. Sentinel 无法保证 强一致性
  3. 常见的 客户端应用库 都支持 Sentinel
  4. Sentinel 需要通过不断的 测试观察,才能保证高可用。

Redis Sentinel的配置文件

# 哨兵sentinel实例运行的端口,默认26379  
port 26379
# 哨兵sentinel的工作目录
dir ./

# 哨兵sentinel监控的redis主节点的 
## ip:主机ip地址
## port:哨兵端口号
## master-name:可以自己命名的主节点名字(只能由字母A-z、数字0-9 、这三个字符".-_"组成。)
## quorum:当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了  
# sentinel monitor <master-name> <ip> <redis-port> <quorum>  
sentinel monitor mymaster 127.0.0.1 6379 2

# 当在Redis实例中开启了requirepass <foobared>,所有连接Redis实例的客户端都要提供密码。
# sentinel auth-pass <master-name> <password>  
sentinel auth-pass mymaster 123456  

# 指定主节点应答哨兵sentinel的最大时间间隔,超过这个时间,哨兵主观上认为主节点下线,默认30秒  
# sentinel down-after-milliseconds <master-name> <milliseconds>
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

# 当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本。一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
# 对于脚本的运行结果有以下规则:  
## 1. 若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10。
## 2. 若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。  
## 3. 如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
# sentinel notification-script <master-name> <script-path>  
sentinel notification-script mymaster /var/redis/notify.sh

# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

Redis Sentinel的节点规划

角色IP地址端口号
Redis Master192.168.1.2306379
Redis Slave1192.168.1.676379
Redis Slave2192.168.1.1186379
Redis Sentinel1192.168.1.23026379
Redis Sentinel2192.168.1.6726379
Redis Sentinel3192.168.1.23026379

Redis Sentinel的配置搭建

Redis-Server的配置管理

主节点 192.168.1.230:redis.conf

daemonize yes
pidfile /var/run/redis-6379.pid
logfile /var/log/redis/redis-6379.log
port 6379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-6379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456

从节点 192.168.1.67:redis.conf

daemonize yes
pidfile /var/run/redis-6379.pid
logfile /var/log/redis/redis-6379.log
port 6379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-6379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456

从节点 192.168.1.118:redis.conf

daemonize yes
pidfile /var/run/redis-6379.pid
logfile /var/log/redis/redis-6379.log
port 6379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-6379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456

如果要做 自动故障转移,建议所有的 redis.conf 都设置 masterauth。因为 自动故障 只会重写 主从关系,即 slaveof,不会自动写入 masterauth。如果 Redis 原本没有设置密码,则可以忽略。

Redis-Server 启动验证

以主节点 Redis 为例

[root@localhost redis]# ps -ef | grep redis
redis     4603     1  0 10:34 ?        00:00:09 /www/server/redis/src/redis-server 0.0.0.0:6379
root      9823  2649  0 11:27 pts/0    00:00:00 grep --color=auto redis

Sentinel 配置管理

因为监听同一个主节点,所以三个 sentinel 节点的配置文件相同

protected-mode no
bind 0.0.0.0
port 26379
daemonize yes
sentinel monitor master 192.168.1.230 6379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /var/log/redis/sentinel-26379.log

Sentinel 启动验证

[root@localhost redis]# ps -ef | grep redis-sentinel
root      2818     1  0 10:17 ?        00:00:15 src/redis-sentinel 0.0.0.0:26379 [sentinel]
root     10639  2649  0 11:35 pts/0    00:00:00 grep --color=auto redis-sentinel

Redis Sentinel 故障切换与恢复

[root@localhost redis]# ps -ef | grep redis
redis     4603     1  0 10:34 ?        00:00:09 /www/server/redis/src/redis-server 0.0.0.0:6379
root      9823  2649  0 11:27 pts/0    00:00:00 grep --color=auto redis

192.168.1.230 主节点的 redis 进程 ID 为 4603。为了模拟 Redis 服务宕机,主动 kill 这个进程。

[root@localhost redis]# kill -9 4603

使用 redis-cli 客户端命令进入 sentinel-26379 节点,查看 Redis 节点 的状态信息。

[root@localhost redis]# redis-cli -p 26379
127.0.0.1:26379> SENTINEL master master
 1) "name"
 2) "master"
 3) "ip"
 4) "192.168.1.230"
 5) "port"
 6) "6379"
 7) "runid"
 8) "8f91932f47c89c6a362c7401aabcb15ac5a416a8"
 9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "40"
19) "last-ping-reply"
20) "40"
21) "down-after-milliseconds"
22) "5000"
23) "info-refresh"
24) "3857"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "4299779"
29) "config-epoch"
30) "3"
31) "num-slaves"
32) "2"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "180000"
39) "parallel-syncs"
40) "1"

更多验证性的操作就不具体放出来了,有兴趣的小伙伴可以参考下面老哥的文章,很详实!

参考

深入剖析Redis系列(二) - Redis哨兵模式与高可用集群