Redis主从有一个问题,如果主服务器挂掉了,从服务器只能读,不可写。采用Sentinel可以自动提升从为新主,从而达到高可用。关于Sentinel的具体搭建过程,网上教程很多,这里就不做过多阐述。
需要特别注意的是在NAT网络环境中,如果Redis和Sentinel做了端口映射,例如在Docker默认网络模式下,使用-p参数做端口映射,就需要配置一下从服务器redis.conf中的slave-announce-ip 和 slave-announce-port,对应外网的IP和外网端口。Sentinel的配置文件sentinel.conf 也需要配置sentinel announce-ip 和 sentinel announce-port ,对应外网的IP和外网端口。当然,如果Docker配置成host网络模式,就不需要配置了。附redis官网关于Docker和NAT网络的说明文档
图片来源于Redis官网

1、使用docker命令运行一个主
docker run --name redis_master -p 10086:6379 -p 10000:26379 -e MASTER_IP=8.8.8.4 -e MASTER_PORT=10086 -e SENT_PORT=10000 -d imdevops/redis-master:latest
2、使用docker命令运行一个从
docker run --name redis_node1 -p 10087:6379 -p 10001:26379 -e MASTER_IP=8.8.8.4 -e MASTER_PORT=10086 -e SLAVE_PORT=10087 -e SENT_IP=8.8.8.4 -e SENT_PORT=10001 -d imdevops/redis-slave:latest
3、使用docker命令运行第二个从
docker run --name redis_node2 -p 10088:6379 -p 10002:26379 -e MASTER_IP=8.8.8.4 -e MASTER_PORT=10086 -e SLAVE_PORT=10088 -e SENT_IP=8.8.8.4 -e SENT_PORT=10002 -d imdevops/redis-slave:latest
4、到此Redis一主两从就部署完成了
5、进到主的容器内,进行状态检查,可以看到从的信息和主的状态
6、主从切换测试。使用Python的第三方模块redis,可以自动发现Sentinel集群中当前的主从节点信息,Java程序可以使用Jedis-API。编程Python测试代码,将Sentinel的IP端口信息写到列表中,在主节点上写,在从节点上读。运行程序后,将主节点容器stop。测试结果:主从复制几乎是实时同步的,当主从切换发生时,程序会有一两秒的停顿,切换成功后程序继续运行,数据几乎没有丢失。
7、切换后状态检查。随便进入一台容器内,可以看到现在变成了一主一从,从节点2变成了新主。
8、旧主恢复后会变成从,不会发生主从切换,这样有利于稳定。如果旧主无法恢复,可以再次执行一下doker run命令加入一台新的从节点进去,环境变量MASTER_IP 和 MASTER_PORT一定要填写当前主节点的IP端口信息,这样可以继续维持一主两从的状态。
9、部署方式说明:在此例中采用的是集中式部署,即都部署在IP为8.8.8.4的同一台机器上。当然也可以主从节点分开部署,环境变量SENT_IP填写当前从节点宿主机的IP地址即可。