您现在的位置是:首页 >技术教程 >Java开发 - 让你少走弯路的Redis集群搭建网站首页技术教程

Java开发 - 让你少走弯路的Redis集群搭建

CodingFire 2024-09-17 12:01:06
简介Java开发 - 让你少走弯路的Redis集群搭建

前言

前文中,我们已经对Redis的单节点哨兵的搭建方式做了演示和测试,相信大家已经了解了怎么操作,虽然是单节点,但基本已经满足了部分公司的日常需要,毕竟Redis集群不是什么项目都适用,用上了Redis,也未必需要使用哨兵,甚至集群。但今天,我们还是要把Redis哨兵集群的搭建方式给大家做个分享,万一用到了呢?话不多书,咱们直接上手。

Redis哨兵集群搭建

学此篇必看内容:

Java开发 - 让你少走弯路的Redis的主从复制

Java开发 - 让你少走弯路的Redis主从实现单节点哨兵模式 

Redis结构

这里,我们需要先准备4个Redis服务,分别是2主,2从,其详情如下:

节点IP端口
node1localhost6379
node2localhost6380
node1的从节点localhost6381
node2的从节点localhost6382

由于我们都是在本地模拟,所以IP可直接用localhost,生产环境可直接使用真是IP。

Redis配置准备 

结构大家已经知道了,那么我们来准备这四个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

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

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

查看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端口
node1localhost6379
node2localhost6380
node1的从节点localhost6381
node2的从节点localhost6382
node3localhost6383
node3的从节点localhost6384

 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
  • 后面的六个ip:port,按照顺序,前面三个是主节点,后面三个是从节点,顺序不能错。
  • 数字 1 表示一个主节点只有一个从节点。和前面的配置相对应。 

以上执行命令最终为:

./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

先贴下成功的案例:

遇到的问题

问题1

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

问题1和问题算是同一个问题,直接看问题2. 

 问题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 => "你的密码")

问题3

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 boot怎么连接Redis集群

sentinel集群与连接

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多配几个,就可以了,可以自己试试。

连接redis集群

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高可用实现

Redis详解(九)------ 哨兵(Sentinel)模式详解

Redis详解(十)------ 从零开始搭建集群_从零搭建redis集群

redis 主从模式、哨兵(sentinel) 配置、cluster(集群)联系与区别

结语

到此,这篇Redis的集群搭建就给大家介绍完了,可能还存在一些细节上的不足,如果你刚好看到,刚好用到,有什么疑问的话,都可以评论区留言讨论,博主一定知无不言,言无不尽。最后,祝愿大家都能成为优秀的Java开发工程师,加油哦!

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。