前文中,我们已经对Redis的单节点哨兵的搭建方式做了演示和测试,相信大家已经了解了怎么操作,虽然是单节点,但基本已经满足了部分公司的日常需要,毕竟Redis集群不是什么项目都适用,用上了Redis,也未必需要使用哨兵,甚至集群。但今天,我们还是要把Redis哨兵集群的搭建方式给大家做个分享,万一用到了呢?话不多书,咱们直接上手。
学此篇必看内容:
Java开发 - 让你少走弯路的Redis主从实现单节点哨兵模式
这里,我们需要先准备4个Redis服务,分别是2主,2从,其详情如下:
| 节点 | IP | 端口 |
| node1 | localhost | 6379 |
| node2 | localhost | 6380 |
| node1的从节点 | localhost | 6381 |
| node2的从节点 | localhost | 6382 |
由于我们都是在本地模拟,所以IP可直接用localhost,生产环境可直接使用真是IP。
结构大家已经知道了,那么我们来准备这四个Redis的配置:
- 节点1
- ----------------------------------------------------
- #配置端口
- port 6379
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6379.pid
- #日志文件名
- logfile "redis_6379.log"
- #rdb备份文件名
- dbfilename "dump_6379.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6379.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no
-
-
- 节点2
- ----------------------------------------------------
- #配置端口
- port 6380
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6380.pid
- #日志文件名
- logfile "redis_6380.log"
- #rdb备份文件名
- dbfilename "dump_6380.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6380.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no
-
-
- 节点1的从节点
- ----------------------------------------------------
- #配置端口
- port 6381
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6381.pid
- #日志文件名
- logfile "redis_6381.log"
- #rdb备份文件名
- dbfilename "dump_6381.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6381.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no
-
-
- 节点2的从节点
- ----------------------------------------------------
- #配置端口
- port 6382
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6382.pid
- #日志文件名
- logfile "redis_6382.log"
- #rdb备份文件名
- dbfilename "dump_6382.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6382.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no

以上四个文件就是我们配置好的两对主从,但切记不要配置他们的主从关系,否则启动redis会报错:

如果配置了主从的,一定要去掉主从相关的配置,然后再启动 :

ps -ef | grep redis

此时可以看到四个Redis已经启动。
此时,你要先确定你的Redis的版本,Redis5之前,使用redis-trib.rb脚本搭建,5及之后的使用redis-cli,因为redis5.0之后已经将redis-trib.rb 脚本的功能全部集成到redis-cli中 。
如不确定版本,也可通过以下命令确认:
- redis-cli --version
- 或
- redis-server --version
博主使用的是低版本的redis,所以先试用redis-trib.rb脚本给大家演示,使用此脚本,需要ruby环境,不过我相信大家基本应该都是吧?不确定的可以运行此脚本查看:
ruby -v
能输出版本号就说明安装了此环境,没安装的请自行安装。
接着还需要gem安装下redis:
gem install redis
否则脚本执行会失败,报如下信息:

安装完成后,命令执行成功:

运行的时候要记得前面需要加上./,否则无法执行,此时你会看到创建集群失败了,这是因为创建集群需要至少6个redis节点,这是我们一开始没有想到的,为了不误导后来人,此时博主就在这里添加两个新的节点,最终的结构如下:
| 节点 | IP | 端口 |
| node1 | localhost | 6379 |
| node2 | localhost | 6380 |
| node1的从节点 | localhost | 6381 |
| node2的从节点 | localhost | 6382 |
| node3 | localhost | 6383 |
| node3的从节点 | localhost | 6384 |
redis配置如下:
- 节点3
- ----------------------------------------------------
- #配置端口
- port 6383
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6383.pid
- #日志文件名
- logfile "redis_6383.log"
- #rdb备份文件名
- dbfilename "dump_6383.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6383.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no
-
-
- 节点3的从节点
- ----------------------------------------------------
- #配置端口
- port 6384
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6384.pid
- #日志文件名
- logfile "redis_6384.log"
- #rdb备份文件名
- dbfilename "dump_6384.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6384.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no
启动新配置的redis并查看状态:

此时,我们重新运行集群的脚本命令:
./redis-trib.rb create --replicas 1 localhost:6379 localhost:6380 localhost:6383 localhost:6381 localhost:6382 localhost:6384
以上执行命令最终为:
./redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6383 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6384
区别在于使用的IP不同。 如遇问题,请到下方问题里面寻找解决办法⬇️。
若是redis5,执行命令如下:
redis-cli -a 123456 --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6383 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6384 1
先贴下成功的案例:

ERR Invalid node address specified: localhost:6379 (Redis::CommandError)

问题1和问题算是同一个问题,直接看问题2.
[ERR] Sorry, can't connect to node 192.168.0.103:6379

执行:
ps -ef | grep redis

创建集群的命令应该使用上面的IP,而不能随意使用,生产环境下使用真是IP即可,本地才会有此问题。由于差了不少资料,对redis设置了密码,添加了这两项:
- #主从连接密码
- masterauth 123456
- #redis连接密码
- requirepass 123456
建议设置一致,使用 redis-trib.rb脚本创建时命令中不能插入密码,所以要对此文件进行修改:
- @r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60)
- 改为
- @r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60, :password => "你的密码")
-
ERR Slot 0 is already busy (Redis::CommandError)

解决办法:
分别连接并清空slot槽,因为上面设置了密码,所以需要密码链接。

这之后,执行创建命令才成功,这是因为一开始创建4个集群的时候失败,导致slot槽已分配导致的,重置后再次执行创建命令则成功。
查看集群状态:
redis-cli -h 127.0.0.1 -p 6379 -a 123456 cluster node

图上可以看到主从配对,和我们一开始的设定是一样的,大家可以自己看看,slave后面那一串id匹配master前面的id。
查看集群信息:
redis-cli -h 127.0.0.1 -p 6379 -a 123456 cluster info

现在,我们来杀死一个id,就选择6380master的端口来杀死,看看会发生什么。
查看进程号:
ps -ef | grep redis

杀死6380对应的进程号:
kill 98534
然后查看集群节点信息:

接着我们发现,6380端口死了,它的从节点6382被提升为了新的master。
现在,重启6380端口并查看集群节点:

6380成了6382的从节点。从上到下,先自动选主,再切换主从,舒服~
我们现在再准备两个redis的配置文件,端口分别是6385主和6386从:
- 节点4
- ----------------------------------------------------
- #配置端口
- port 6385
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6385.pid
- #日志文件名
- logfile "redis_6385.log"
- #rdb备份文件名
- dbfilename "dump_6385.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6385.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no
-
-
- 节点4的从节点
- ----------------------------------------------------
- #配置端口
- port 6386
- #以守护进程模式启动
- daemonize yes
- #pid的存放文件
- pidfile /var/run/redis_6386.pid
- #日志文件名
- logfile "redis_6386.log"
- #rdb备份文件名
- dbfilename "dump_6386.rdb"
- #开启集群功能
- cluster-enabled yes
- #集群配置文件,节点自动维护
- cluster-config-file nodes-6386.conf
- #集群能够运行不需要集群中所有节点都是成功的
- cluster-require-full-coverage no
接着启动这两个新的redis配置:
- redis-server redis_master4.conf
- redis-server redis_slave4.conf
并查看redis运行状态:

已成功启动,下面我们把这两个redis添加到我们上面的集群中:
./redis-trib.rb add-node 127.0.0.1:6385 127.0.0.1:6379
./redis-trib.rb add-node 127.0.0.1:6386 127.0.0.1:6379
添加时,新的节点需要一个已经存在的节点的IP和port做为参照物来添加进去。
redis5.0使用此命令:
redis-cli -a 123456 -p 6379 --cluster add-node 127.0.0.1:6385 127.0.0.1:6379
redis-cli -a 123456 -p 6379 --cluster add-node 127.0.0.1:6386 127.0.0.1:6379
a后面位密码,新的节点需要一个已经存在的节点的IP和port做为参照物来添加进去。

添加成功,查看新添加的主节点:

给新添加的节点增加主从关系,redis-trib.rb只在创建集群的时候会帮我们自动设置主从关系,扩容操作就不会帮我们自动设置主从了,所以只能使用redis原生命令去设置主从关系,这个优点废,建议用高版本的去做。我们手动设置6376为6385的从节点:
- redis-cli -h 127.0.0.1 -p 6386
- auth 123456
- #后面为6386的id
- cluster replicate 365de2bd278e3e80147b366bad6fe13a86138148
退出并查看节点状态,此时,主从已经设置完成。

redis5的命令:
redis-cli -p 6386 -a 123456 cluster replicate 365de2bd278e3e80147b366bad6fe13a86138148
p是从节点的端口,a是密码,最后面是主节点的id。
眼尖的童鞋可能会看出来问题了,新添加主节点没有分配槽,额,好烦,因为redis5.0的命令会自动分配槽给新的节点,我为什么要选3.x的版本?啊?为啥?5.0分配时会有提示,和下面差不多。
下面开始迁移:
./redis-trib.rb reshard 127.0.0.1:6385

一共16384个槽,目前4个主节点,除以4是4096。 如果除不尽,需要做一个平衡,有微笑的误差,你在输入此命令时会有提示:
./redis-trib.rb rebalance ip:port

输入一个id就回车一次,结束用done。

然后就开始了漫长的迁移过程,等一会儿就好了。

终于结束了,我们来看看迁移情况:

可以看到主节点都已经分配了槽。
扩容说完了,我们来说说缩容,新添加的节点怎么去除呢?比如我的这个节点太卡,我想换个新的节点,要去除节点,就要先把槽给别的节点才行:
./redis-trib.rb reshard --from 365de2bd278e3e80147b366bad6fe13a86138148 --to 994325203cc78fc79894e8ef9427244ba18be267 --slots 4096 127.0.0.1:6385
一次性把所有槽都给6379:

输入yes:
接着就开始迁移槽了:

然后结束:

查看目前的槽分配情况:

6385已经没有槽了,此时可以移除了,但是移除的时候,如果有从节点,需要先移除 从节点:
./redis-trib.rb del-node 127.0.0.1:6386 d344bd2a331a20653402239030a32dd2dc30aa54

接着移除主节点6385:
./redis-trib.rb del-node 127.0.0.1:6385 365de2bd278e3e80147b366bad6fe13a86138148
redis5.0这么做:
redis-cli -p 6379 -a 123 --cluster reshard --cluster-from 被移除的节点id --cluster-to 槽需要迁移到的节点id --cluster-slots 需要迁移的槽数量 IP:port
此时,查看集群的状态:
redis-cli -h 127.0.0.1 -p 6379 -a 123456 cluster nodes

6385和6386已经没有了,接下来查看运行的redis有哪些:
ps -ef | grep redis

此时6385和6386的redis服务器已经被关闭了。
- spring:
- redis:
- database: 0
- password: 123456
- sentinel:
- master: mymaster
- # 四个redis-sentinel
- nodes: ip:port,ip:port,ip:port,ip:port
单节点下,哨兵只要监听主节点,就可以找到所有的主节点的从节点。
集群下,哨兵必须同时监听所有的主节点,才能监听到所有的节点:
- #配置端口
- port 26379
- # 设置为守护进程模式,可先注释,看投票选主的过程
- #daemonize yes
- #日志文件名
- logfile "redis_sentinel.log"
- #存放备份文件以及日志等文件的目录
- dir "/opt/redis/data"
- # redis_sentinel表示hostname,自己随意取名
- # 数字1表示当主机宕机后,在从机中进行投票选主,票数大于1的晋升为主机
- sentinel monitor redis_sentinel1 127.0.0.1 6380 1
- sentinel monitor redis_sentinel2 127.0.0.1 6381 1
- sentinel monitor redis_sentinel3 127.0.0.1 6382 1
- #30秒ping不通主节点的信息,主观认为master宕机
- sentinel down-after-milliseconds redis_sentinel1 30000
- sentinel down-after-milliseconds redis_sentinel2 30000
- sentinel down-after-milliseconds redis_sentinel3 30000
- #故障转移后重新主从复制,1表示串行,>1并行
- sentinel parallel-syncs redis_sentinel1 1
- sentinel parallel-syncs redis_sentinel2 1
- sentinel parallel-syncs redis_sentinel3 1
- #故障转移三分钟内没有完成,认为转移失败
- sentinel failover-timeout redis_sentinel1 180000
- sentinel failover-timeout redis_sentinel2 180000
- sentinel failover-timeout redis_sentinel3 180000
这就是博主之前为什么只讲了单节点sentinel的原因,需要sentinel集群的话就上面一模一样的sentinel多配几个,就可以了,可以自己试试。
- spring:
- redis:
- cluster:
- nodes:
- - 127.0.0.1:6379
- - 127.0.0.1:6380
- - 127.0.0.1:6381
- - 127.0.0.1:6382
- - 127.0.0.1:6383
- - 127.0.0.1:6384
- max-redirects: 6 #节点数量
- jedis:
- pool:
- max-active: 16 #最大的连接数
- max-wait: 3000 #最大的等待时间
- max-idle: 8 #最大空闲数
- min-idle: 0 #最小空闲数
结尾给大家推荐几篇写得不错的redis集群博客:
Redis详解(九)------ 哨兵(Sentinel)模式详解
Redis详解(十)------ 从零开始搭建集群_从零搭建redis集群
redis 主从模式、哨兵(sentinel) 配置、cluster(集群)联系与区别
到此,这篇Redis的集群搭建就给大家介绍完了,可能还存在一些细节上的不足,如果你刚好看到,刚好用到,有什么疑问的话,都可以评论区留言讨论,博主一定知无不言,言无不尽。最后,祝愿大家都能成为优秀的Java开发工程师,加油哦!