当前位置: 首页 > news >正文

redis 集群——redis cluster(去中心化)

redis cluster(去中心化)

  • 一、Redis 集群介绍
    • 1、背景
    • 2、概念
    • 3、优势
    • 4、数据分布式存储
  • 二、实现Redis集群
    • 1、项目环境
    • 2、配置集群
    • 3、故障转移
    • 4、集群扩容
    • 5、集群缩容

一、Redis 集群介绍

1、背景

从最开始的一主N从,读写分离,再到Sentinel哨兵机制,单实例的Redis缓存足以应对大多数的使用场景,也能实现主从故障迁移。

但是,在某些场景下,单实例存Redis缓存会存在的几个问题:

(1)写并发:Redis单实例读写分离可以解决读操作的负载均衡,但对于写操作,仍然是全部落在了master节点上面,在海量数据高并发场景,一个节点写数据容易出现瓶颈,造成master节点的压力上升。

(2)海量数据的存储压力: 单实例Redis本质上只有一台Master作为存储,如果面对海量数据的存储,一台Redis服务器就应付不过来了,而且数据量太大意味着持久化成本高,严重时可能会阻塞服务器,造成服务请求成功率下降,降低服务的稳定性。

针对以上的问题,Redis集群提供了较为完善的方案,解决了存储能力受到单机限制,写操作无法负载均衡的问题。

2、概念

Redis3.0加入了Redis的集群模式,通过数据的分布式存储实现去中心化的思想。redis通过对数据进行分片,将不同的数据存储在不同的master节点上面,从而解决了海量数据的存储问题。Redis也内置了高可用机制,支持N个master节点,每个master节点都可以挂载多个slave节点,当master节点挂掉时,集群会提升它的某个slave节点作为新的master节点。

redis集群没有中心节点的说法,对于客户端来说,整个集群可以看成一个整体,可以连接任意一个节点进行操作,就像操作单一Redis实例一样,不需要任何代理中间件,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node。

官网文档地址:https://redis.io/docs/manual/scaling/

3、优势

  • 自动分割数据到不同的节点上。
  • 整个集群的部分节点失败或者不可达的情况下能够继续处理命令。

在这里插入图片描述

4、数据分布式存储

Redis 集群引入了哈希槽(slots)实现数据的分布式存储。

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽(slot = CRC16(key)%16384)。集群的每个节点负责一部分hash槽,比如当前集群有3个节点,那么:

  • 节点 A 包含 0 到 5460号哈希槽。
  • 节点 B 包含5461 到 10922号哈希槽。
  • 节点 C 包含10923 到 16383号哈希槽。

这种结构很容易添加或者删除节点。比如想新添加个节点D,只需要从节点 A、B、C中得到部分哈希槽并分配到D上即可。 如果想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

[!Warning]

假设具有A、B、C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用(注意:整个集群都不可用)

然而如果在集群创建的时候(或者过一段时间)为每个节点添加一个从节点A1、B1、C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了。

不过当B和B1 都失败后,集群是不可用的。

二、实现Redis集群

1、项目环境

主机说明主机IP端口
master1192.168.83.206379
slave1192.168.83.206380
master2192.168.83.216379
slave2192.168.83.216380
master3192.168.83.226379
slave3192.168.83.226380

2、配置集群

2.1 Redis主机配置

编辑主配置文件

#1、编辑主配置文件
[root@master1 ~]# vim /etc/redis/redis.conf
port 6379   # 修改端口号
pidfile /var/run/redis_6379.pid  # 修改pid文件名
dir /var/lib/redis  		# 持久化文件存放目录
dbfilename dump_6379.rdb   	# 修改持久化文件名
bind 0.0.0.0  	 # 绑定地址
daemonize yes		# 让redis后台运行
protected-mode no	# 关闭保护模式
logfile /var/log/redis/redis_6379.log  # 指定日志
cluster-enabled yes  # 开启集群功能
cluster-config-file nodes-6379.conf   #设定节点配置文件名,不需要我们创建,由redis自己维护
cluster-node-timeout 10000   # 节点心跳失败的超时时间,超过该时间(毫秒),集群自动进行主从切换# 启动第一个redis实例
[root@master1 ~]# systemctl restart redis# 查看端口号
[root@master1 ~]# ss -lntup | grep redis
tcp   LISTEN 0      511          0.0.0.0:6379       0.0.0.0:*    users:(("redis-server",pid=34021,fd=6))127.0.0.1:6379> set haha 1
(error) MOVED 3662 192.168.83.20:6379
# 未开启集群
# 加上-c表示启用集群模式[root@master1 ~]# redis-cli -c
127.0.0.1:6379> set master cluster
-> Redirected to slot [5565] located at 192.168.83.21:6379
OK

在该主机上启动另外一个6380端口的实例

#1、在该主机上启动另外一个6380端口的实例
[root@master1 ~]# cp /etc/redis/redis.conf /etc/redis/redis-6380.conf
#2、将6379都修改为6380
#方法一
[root@master1 ~]# vim /etc/redis/redis-6380.conf
# 进入命令端:%s/6379/6380/g修改#方法二
sed -i 's/6379/6380/ ' /etc/redis/redis-6380.conf#3、启用6380端口
[root@master1 ~]# redis-server  /etc/redis/redis-6380.conf# 使用命令启动6380实例并将其放在后台
[root@master1 ~]# redis-server  /etc/redis/redis-6380.conf  &#4、查看是否有两个redis实例
[root@master1 ~]# ss -lntup | grep redis
tcp   LISTEN 0      511          0.0.0.0:6380       0.0.0.0:*    users:(("redis-server",pid=34098,fd=6))
tcp   LISTEN 0      511          0.0.0.0:6379       0.0.0.0:*    users:(("redis-server",pid=34021,fd=6))

在这里插入图片描述

将文件复制到两外两台主机依次启动

#1、复制文件到master2和master3
[root@master1 ~]# scp /etc/redis/redis.conf /etc/redis/redis—6380.conf  root@192.168.83.21:/etc/redis
root@192.168.83.21's password:
redis.conf                                       100%   92KB  43.0MB/s   00:00
redis-6380.conf                                  100%   92KB  32.7MB/s   00:00
[root@master1 ~]# scp /etc/redis/redis.conf /etc/redis/redis-6380.conf  root@192.168.83.22:/etc/redis#2、master2上操作
[root@master2 ~]# systemctl restart redis
[root@master2 ~]# redis-server  /etc/redis/redis-6380.conf  &#3、查看redis是否运行
[root@master2 ~]# ss -lntup |  grep  redis
tcp   LISTEN 0      511          0.0.0.0:6379       0.0.0.0:*    users:(("redis-server",pid=33931,fd=6))
tcp   LISTEN 0      511          0.0.0.0:6380       0.0.0.0:*    users:(("redis-server",pid=33989,fd=6))#4、master3重复上述操作

启动好全部 Redis 服务器后,接下来就是如何把这 6 个服务器按预先规划的结构来组合成集群了。在做接下来的操作之前,一定要先确保所有 Redis 实例都已经成功启动,并且对应实例的节点配置文件都已经成功生成。

# 使用如下命令在所有主机上都可以看到所有实例生成的rdb文件和nodes文件
# ls /var/lib/redis/
dump_6380.rdb  dump.rdb  nodes-6379.conf  nodes-6380.conf

2.2 创建集群命令格式:

redis-cli --cluster create --cluster-replicas 副本数 主机IP:端口号 主机IP:端口号#create 创建集群
#`节点总数 ÷ (replicas + 1)` 得到的就是master的数量。节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master。(Redis 的分配原则是:尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。)

创建集群:

[root@master1 ~]# redis-cli --cluster create --cluster-replicas 1 192.168.83.20:6379 192.168.83.21:6379 192.168.83.22:6379  192.168.83.20:6380  192.168.83.21:6380 192.168.83.22:6380# 最后成功输出如下
>>> Performing Cluster Check (using node 192.168.83.20:6379)
M: 49abc1fe5b4b8c393df995d64dc79046ff9c16d6 192.168.83.20:6379slots:[0-5460] (5461 slots) master1 additional replica(s)
S: 6aa30ba97bbe310961aede67ef1f340c74d6ff68 192.168.83.22:6380slots: (0 slots) slavereplicates 3dd8e51de962edf42476e65bf636817c6fb13b68
M: 77f8f27f62b0c9e598041b3839786f23b8e53e63 192.168.83.22:6379slots:[10923-16383] (5461 slots) master1 additional replica(s)
M: 3dd8e51de962edf42476e65bf636817c6fb13b68 192.168.83.21:6379slots:[5461-10922] (5462 slots) master1 additional replica(s)
S: d728c8b7e5938ff96bc4b271c019fc7094b1607d 192.168.83.20:6380slots: (0 slots) slavereplicates 77f8f27f62b0c9e598041b3839786f23b8e53e63
S: 72fdbc7928adc57673010ebf68f204f98a641646 192.168.83.21:6380slots: (0 slots) slavereplicates 49abc1fe5b4b8c393df995d64dc79046ff9c16d6
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

在这里插入图片描述

查看集群状态

[root@master1 ~]# redis-cli  -p 6379 cluster nodes
49abc1fe5b4b8c393df995d64dc79046ff9c16d6 192.168.83.20:6379@16379 myself,master - 0 1757573878000 1 connected 0-5460
6aa30ba97bbe310961aede67ef1f340c74d6ff68 192.168.83.22:6380@16380 slave 3dd8e51de962edf42476e65bf636817c6fb13b68 0 1757573877790 2 connected
77f8f27f62b0c9e598041b3839786f23b8e53e63 192.168.83.22:6379@16379 master - 0 1757573876000 3 connected 10923-16383
3dd8e51de962edf42476e65bf636817c6fb13b68 192.168.83.21:6379@16379 master - 0 1757573878797 2 connected 5461-10922
d728c8b7e5938ff96bc4b271c019fc7094b1607d 192.168.83.20:6380@16380 slave 77f8f27f62b0c9e598041b3839786f23b8e53e63 0 1757573877000 3 connected
72fdbc7928adc57673010ebf68f204f98a641646 192.168.83.21:6380@16380 slave 49abc1fe5b4b8c393df995d64dc79046ff9c16d6 0 1757573877000 1 connected

2.3 测试

#连接集群存储数据
[root@master1 ~]# redis-cli  -p 6379
127.0.0.1:6379> set cluster 3
(error) MOVED 14041 192.168.83.22:6379  #结果报错
########说明######
#在集群环境下,由于 redis-cli 每次录入、查询键值时,Redis 都会计算出该 key 对应的插槽值,并交给对应插槽所在的节点进行处理。如果不是该客户端对应服务器的插槽 Redis 会报错,并告知应前往的 Redis 实例地址和端口。
##########说明结束######
#加上-c表示启用集群模式
[root@master1 ~]# redis-cli  -p 6379 -c
192.168.83.22:6379> set cluster zhangjin192.168.83.22:6379> get cluster
"zhangjin"# 查看集群信息
192.168.168.22:6379> cluster nodes
77f8f27f62b0c9e598041b3839786f23b8e53e63 192.168.83.22:6379@16379 myself,master - 0 1757574171000 3 connected 10923-16383
3dd8e51de962edf42476e65bf636817c6fb13b68 192.168.83.21:6379@16379 master - 0 1757574171079 2 connected 5461-10922
6aa30ba97bbe310961aede67ef1f340c74d6ff68 192.168.83.22:6380@16380 slave 3dd8e51de962edf42476e65bf636817c6fb13b68 0 1757574172790 2 connected
d728c8b7e5938ff96bc4b271c019fc7094b1607d 192.168.83.20:6380@16380 slave 77f8f27f62b0c9e598041b3839786f23b8e53e63 0 1757574170000 3 connected
49abc1fe5b4b8c393df995d64dc79046ff9c16d6 192.168.83.20:6379@16379 master - 0 1757574170775 1 connected 0-5460
72fdbc7928adc57673010ebf68f204f98a641646 192.168.83.21:6380@16380 slave 49abc1fe5b4b8c393df995d64dc79046ff9c16d6 0 1757574171783 1 connected

3、故障转移

模拟master1宕机

# 模拟master1宕机
[root@master1 ~]# redis-cli -p 6379
127.0.0.1:6379> shutdown
not connected> [root@master1 ~]# redis-cli  -p 6380
127.0.0.1:6380> CLUSTER nodes
# 可以看到master切换到了192.168.168.21:6380

在这里插入图片描述

再次启动master1

[root@master1 ~]# systemctl start redis
[root@master1 ~]# redis-cli  -p 6379
127.0.0.1:6379> cluster nodes
# 可以发现master1变成了从

在这里插入图片描述

[!Important]

问:如果所有某段插槽的主从节点都宕机了,Redis 服务是否还能继续?

答:当发生某段插槽的主从都宕机后,如果在 redis.conf 配置文件中的 cluster-require-full-coverage 参数的值为 yes ,那么整个集群都挂掉;如果参数的值为 no ,那么该段插槽数据全都不能使用,也无法存储。

4、集群扩容

4.1 我们向现有集群中添加两个节点,这两个节点做一主一从。主节点的端口号为 6381,从节点的端口号为 6382。

[root@master1 ~]# cp /etc/redis/redis.conf /etc/redis/redis-6381.conf
[root@master1 ~]# cp /etc/redis/redis.conf /etc/redis/redis-6382.conf
[root@master1 ~]# sed -i 's/6379/6381/ ' /etc/redis/redis-6381.conf
[root@master1 ~]# sed -i 's/6379/6382/ ' /etc/redis/redis-6382.conf# 启动实例
[root@master1 ~]# redis-server  /etc/redis/redis-6381.conf &
[2] 28795
[root@master1 ~]# redis-server  /etc/redis/redis-6382.conf &
[3] 28800
[root@master1 ~]# ss -lntup | grep redis
tcp   LISTEN 0      511          0.0.0.0:6379       0.0.0.0:*    users:(("redis-server",pid=2491,fd=6))
tcp   LISTEN 0      511          0.0.0.0:6381       0.0.0.0:*    users:(("redis-server",pid=2560,fd=6))
tcp   LISTEN 0      511          0.0.0.0:6380       0.0.0.0:*    users:(("redis-server",pid=2404,fd=6))
tcp   LISTEN 0      511          0.0.0.0:6382       0.0.0.0:*    users:(("redis-server",pid=2566,fd=6))

4.2 添加节点到集群的语法格式为:

redis-cli --cluster add-node new_host:new_port existing_host:existing_port--cluster-slave--cluster-master-id <arg>

add-node命令用于添加节点到集群中,参数说明如下:

  • new_host:被添加节点的主机地址
  • new_port:被添加节点的端口号
  • existing_host:目前集群中已经存在的任一主机地址
  • existing_port:目前集群中已经存在的任一端口地址
  • –cluster-slave:用于添加从(Slave)节点
  • –cluster-master-id:指定主(Master)节点的ID(唯一标识)字符串

添加主节点

[root@master1 ~]#  redis-cli  --cluster add-node  192.168.83.20:6381 192.168.83.20:6379

添加从节点

#需要先查看6381节点的ID值
[root@master1 ~]# redis-cli  -p 6381
127.0.0.1:6381> CLUSTER nodes
49402647b0a7a55d0b00b187cf56befdd16c56c7 192.168.83.20:6381@16381 myself,master - 0 1757575355000 0 connected# 将192.168.83.20:6382作为拥有此ID的49402647b0a7a55d0b00b187cf56befdd16c56c7的slave身份加入192.168.83.20:6379所在集群
[root@master1 ~]# redis-cli --cluster add-node 192.168.83.20:6382 192.168.83.20:6379 --cluster-slave --cluster-master-id 49402647b0a7a55d0b00b187cf56befdd16c56c7

由于集群中增加了新节点,需要对现有数据重新进行分片操作。重新分片的语法如下:

redis-cli --cluster reshard  host:port--cluster-from <arg>--cluster-to <arg>--cluster-slots <arg>--cluster-yes--cluster-timeout <arg>--cluster-pipeline <arg>--cluster-replace

reshard命令用于重新分片,参数说明如下:

  • host:集群中已经存在的任意主机地址
  • port:集群中已经存在的任意主机对应的端口号
  • –cluster-from:表示slot目前所在的master节点node ID,多个ID用逗号分隔
  • –cluster-to:表示需要分配节点的node ID
  • –cluster-slot:分配的slot数量
  • –cluster-yes:指定迁移时的确认输入
  • –cluster-timeout:设置migrate命令的超时时间
  • –cluster-pipeline:定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10
  • –cluster-replace:是否直接replace到目标节点
#分配100个插槽
[root@master1 ~]# redis-cli --cluster reshard 192.168.83.21:6379 --cluster-from 3dd8e51de962edf42476e65bf636817c6fb13b68 --cluster-to 49402647b0a7a55d0b00b187cf56befdd16c56c7 --cluster-slots 200 --cluster-yes --cluster-timeout 10000 --cluster-pipeline 10 --cluster-replace

在这里插入图片描述

可以查看插槽分配情况

[root@master1 ~]# redis-cli  -p 6379
127.0.0.1:6379> cluster nodes

在这里插入图片描述

5、集群缩容

添加节点的时候是先添加node节点到集群,然后分配槽位,删除节点的操作与添加节点的操作正好相反,是先将被删除的Redis node上的槽位迁移到集群中的其他Redis node节点上,然后再将其删除,如果一个Redis node节点上的槽位没有被完全迁移,删除该node的时候会提示有数据且无法删除。

# 查看要被迁移的节点上有多少插槽
[root@master1 ~]# redis-cli --cluster check 192.168.83.20:6379192.168.83.20:6381 (49402647...) -> 0 keys | 200 slots | 1 slaves.   # 分配200个插槽# 查看到6381上面的插槽编号,计算出数量
M: 49402647b0a7a55d0b00b187cf56befdd16c56c7 192.168.83.20:6381slots:[5461-5660] (200 slots) master1 additional replica(s)[root@master1 ~]# redis-cli --cluster reshard 192.168.83.20:6379 --cluster-from 49402647b0a7a55d0b00b187cf56befdd16c56c7 --cluster-to 72fdbc7928adc57673010ebf68f204f98a641646 --cluster-slots 100
Do you want to proceed with the proposed reshard plan (yes/no)? yes  #此处输入yes

删除节点的语法格式为:

redis-cli --cluster del-node       host:port node_id

del-node命令用于从集群中删除节点,参数说明如下:

  • host:集群中已经存在的主机地址
  • port:集群中已经存在的主机对应的端口号
  • node_id:要删除的节点ID
# 先删除从节点,如果先删除主节点,从会故障转移
[root@master1 ~]# redis-cli --cluster del-node 192.168.168.20:6379 db877460361b3755502fa8f0cea523b99e9da032
[root@master1 ~]# redis-cli --cluster del-node 192.168.168.20:6379 3fb85117061c248a338ac7dfc3b460bc31e1a6d2

文章转载自:

http://MjlGS5jD.jfkwp.cn
http://oEpsi70B.jfkwp.cn
http://KNer07pk.jfkwp.cn
http://oGYJCm7O.jfkwp.cn
http://RPiG75xr.jfkwp.cn
http://Pw7ubs9i.jfkwp.cn
http://Bk7AvMhs.jfkwp.cn
http://zGd2Abwi.jfkwp.cn
http://J0ThpukD.jfkwp.cn
http://K1aYcCbj.jfkwp.cn
http://fRycTibE.jfkwp.cn
http://wOhGGx9G.jfkwp.cn
http://cqPqNvTl.jfkwp.cn
http://yg8GSpps.jfkwp.cn
http://rPTTx3AA.jfkwp.cn
http://K7cd0mGx.jfkwp.cn
http://RKVJVQ84.jfkwp.cn
http://ASX1sl0F.jfkwp.cn
http://IccumiZ4.jfkwp.cn
http://uEeZX5fp.jfkwp.cn
http://o9OfcBsc.jfkwp.cn
http://rNfZA3xM.jfkwp.cn
http://H6ObfTms.jfkwp.cn
http://llHvMAAv.jfkwp.cn
http://hmDstL3Y.jfkwp.cn
http://vEu5dLDG.jfkwp.cn
http://GOWZQTmZ.jfkwp.cn
http://134gk9zV.jfkwp.cn
http://pB1IhuXc.jfkwp.cn
http://E8m1ClaH.jfkwp.cn
http://www.dtcms.com/a/378351.html

相关文章:

  • k8s部署kafka三节点集群
  • 11.ImGui-加载字体和中文
  • 大模型推理革命
  • 项目-sqlite类的实现
  • 物联网领域中PHP框架的最佳选择有哪些?
  • ARM1.(ARM体系结构)
  • Linux开机启动设置全攻略
  • 解决Pytest参数化测试中文显示乱码问题:两种高效方法
  • PHP弱类型比较在CTF比赛中的深入分析与实战应用
  • 科大讯飞一面
  • html块标签和内联标签的通俗理解
  • 【C++】STL--Vector使用极其模拟实现
  • QT子线程与GUI线程安全交互
  • 论 Intel CPU 进化史:德承工控机全面进化 搭载新一代 Intel® Core™ Ultra 7/5/3 处理器
  • 论文阅读/博弈论/拍卖:《Truthful Auction for Cooperative Communications》
  • 【论文阅读】Towards Privacy-Enhanced and Robust Clustered Federated Learning
  • [论文阅读] 告别“数量为王”:双轨道会议模型+LS,破解AI时代学术交流困局
  • 【UE】2D SphereNormalsMap - 实时计算2D “球形法线” 贴图
  • 保护模式下的特权级_考研倒计时 100 days
  • 中科米堆CASAIM高精度蓝光3D扫描激光抄数服务逆向三维建模
  • 【Canvas与几何图案】六钩内嵌大卫之星黑白图案
  • 智能体工作流画布:提升企业业务流程自动化效率
  • 如何从 iPhone 打印联系人信息
  • FOC系列(六)----学习DRV8313/MS8313芯片,绘制驱动板
  • Android开发值Android官方模拟器启动失败问题跟踪排查
  • hardhat 项目目录介绍
  • IROS 2025 多智能体深度强化学习算法实现Crazyflie无人机在复杂环境中协同追逐
  • 光平面标定 (Laser Plane Calibration) 的原理和流程
  • sqbks二面(准备)
  • Linux云计算系统安全:PAM