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

前言

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

Redis哨兵集群搭建

学此篇必看内容:

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

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

Redis结构

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

节点 IP 端口
node1 localhost 6379
node2 localhost 6380
node1的从节点 localhost 6381
node2的从节点 localhost 6382

由于我们都是在本地模拟,所以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 端口
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
  • 后面的六个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],: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

单节点下,哨兵只要监听主节点,就可以找到所有的主节点的从节点。

集群下,哨兵必须同时监听所有的主节点,才能监听到所有的节点:

#配置端口
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开发工程师,加油哦!

原文地址:https://blog.csdn.net/CodingFire/article/details/131109255

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读752次。关系型数据库关系型数据库是一个结构化的数据库,创建在关系模型(二维表模型)基础上,一般面向于记录SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作主流的关系数据库包括Oracle、Mysql、SQL Server、Microsoft Access、DB2等非关系型数据库NoSQL(nOSQL=Not Only SQL),意思是“不仅仅是SQL”,是非关系型数据库的总称。除了主流的关系型数据库外的数据库,都认为是非关系型主流的NoSQ.._redis是非关系型数据库吗
文章浏览阅读687次,点赞2次,收藏5次。商城系统中,抢购和秒杀是很常见的营销场景,在一定时间内有大量的用户访问商场下单,主要需要解决的问题有两个:1. 高并发对数据库产生的压力;2. 竞争状态下如何解决商品库存超卖;高并发对数据库产生的压力对于第一个问题,使用缓存来处理,避免直接操作数据库,例如使用 Redis。竞争状态下如何解决商品库存超卖对于第二个问题,需要重点说明。常规写法:查询出对应商品的库存,判断库存数量否大于 0,然后执行生成订单等操作,但是在判断库存是否大于 0 处,如果在高并发下就会有问题,导致库存_php库存结余并发
文章浏览阅读1.4k次。MongoTemplate开发spring-data-mongodb提供了MongoTemplate和MongoRepository两种方式访问MongoDB,MongoRepository的方式访问较为简单,MongoTemplate方式较为灵活,这两种方式在Java对于MongoDB的运用中相辅相成。_springboot插入指定的mongodb数据库
文章浏览阅读887次,点赞10次,收藏19次。1.背景介绍1. 背景介绍NoSQL数据库是一种非关系型数据库,它的特点是可以存储非结构化的数据,并且可以处理大量的数据。HBase是一个分布式、可扩展的列式存储系统,它是基于Google的Bigtable设计的。HBase是一个开源的NoSQL数据库,它的核心功能是提供高性能的随机读写访问。在本文中,我们将对比HBase与其他NoSQL数据库,例如Redis、MongoDB、Cass...
文章浏览阅读819次。MongoDB连接失败记录_edentialmechanisn-scram-sha-1
文章浏览阅读470次。mongodb抽取数据到ES,使用ELK内部插件无法获取数据,只能试试monstache抽取mongodb数据,但是monstache需要mongodb replica set 模式才能采集数据。############monstache-compose文件。#replicas set 启动服务。# 默认备份节点不能读写,可以设置。# mydb指的是需要同步的数据库。#登录主mongodb初始化rs。#primary 创建用户。# ip地址注意要修改。# ip地址注意要修改。_monstache csdn
文章浏览阅读913次,点赞4次,收藏5次。storage:fork: trueadmin登录切换数据库注意: use 代表创建并使用,当库中没有数据时默认不显示这个库删除数据库查看表清单> show tables # 或者 > show collections表创建db.createCollection('集合名称', [options])table1字段类型描述capped布尔(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。_mongodb5
文章浏览阅读862次。Centos7.9设置MongoDB开机自启(超全教程,一条龙)_mongodb centos开机启动脚本
文章浏览阅读1.3k次,点赞6次,收藏21次。NoSQL数据库使用场景以及架构介绍
文章浏览阅读856次,点赞21次,收藏20次。1.背景介绍1. 背景介绍NoSQL数据库是一种非关系型数据库,它的设计目标是为了解决传统关系型数据库(如MySQL、Oracle等)在处理大量不结构化数据方面的不足。NoSQL数据库可以处理大量数据,具有高性能、高可扩展性和高可用性。但是,与关系型数据库不同,NoSQL数据库没有固定的模式,数据结构也不一定是表格。在NoSQL数据库中,数据存储和查询都是基于键值对、列族、图形等不同的...
文章浏览阅读416次。NoSQL定义:非关系型、分布式、开放源码和具有横向扩展能力的下一代数据库。由c++编写的开源、高性能、无模式的基于分布式文件存储的文档型数据库特点:高性能、高可用性、高扩展性、丰富的查询支持、可替换已完场文档某个指定的数据字段应用场景:社交场景:使用mongodb存储用户信息游戏场景:用户信息,装备积分物流场景:订单信息,订单状态场景操作特点:数据量大;读写操作频繁;价值较低的数据,对事物性要求不高开源、c语言编写、默认端口号6379、key-value形式存在,存储非结构化数据。_nosql
文章浏览阅读1.5k次,点赞3次,收藏2次。Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: Failed to create socket. at redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:110) at redis.clients.jedis.Connection.connect(Conne_redis.clients.jedis.exceptions.jedisconnectionexception: failed to create so
文章浏览阅读6.5k次,点赞3次,收藏12次。readAnyDatabase(在所有数据库上都有读取数据的权限)、readWriteAnyDatabase(在所有数据库上都有读写数据的权限)、userAdminAnyDatabase(在所有数据库上都有管理user的权限)、dbAdminAnyDatabase(管理所有数据库的权限);:clusterAdmin(管理机器的最高权限)、clusterManager(管理和监控集群的权限)、clusterMonitor(监控集群的权限)、hostManager( 管理Server);_mongodb创建用户密码并授权
文章浏览阅读593次。Redis是一个基于内存的键值型NoSQL数据库,在实际生产中有着非常广泛的用处_搭建本地redis
文章浏览阅读919次。Key 的最佳实践[业务名]:[数据名]:[id]足够简短:不超过 44 字节不包含特殊字符Value 的最佳实践:合理的拆分数据,拒绝 BigKey选择合适数据结构Hash 结构的 entry 数量不要超过 1000(默认是 500,如果达到上限则底层会使用哈希表而不是 ZipList,内存占用较多)设置合理的超时时间批量处理的方案:原生的 M 操作Pipeline 批处理注意事项:批处理时不建议一次携带太多命令。Pipeline 的多个命令之间不具备原子性。_redis高级实战
文章浏览阅读1.2k次。MongoDB 递归查询_mongodb数据库 递归
文章浏览阅读1.2k次。通过实际代码例子介绍:如何通过MongoTemplate和MongoRepository操作数据库数据_springboot操作mongodb
文章浏览阅读687次,点赞7次,收藏2次。首先欢迎大家阅读此文档,本文档主要分为三个模块分别是:Redis的介绍及安装、RedisDesktopManager可视化工具的安装、主从(哨兵)模式的配置。_redis 主从配置工具
文章浏览阅读764次。天下武功,无坚不摧,唯快不破!我的名字叫 Redis,全称是 Remote Dictionary Server。有人说,组 CP,除了要了解她外,还要给机会让她了解你。那么,作为开发工程师的你,是否愿意认真阅读此心法抓住机会来了解我,运用到你的系统中提升性能。我遵守 BSD 协议,由意大利人 Salvatore Sanfilippo 使用 C 语言编写的一个基于内存实现的键值型非关系(NoSQL)..._redis 7.2 源码
文章浏览阅读2k次。MongoDB 的增删改查【1】_mongodb $inc