redis集群搭建及问题处理

redis主从+哨兵可以帮助我们满足很多工作场景,但是如果我们所需要处理的数据量过大的话,那么就不会满足需求,比如:我们的redis配置200G内存,但是实际的数据量达到400G那么,我们的主从是无法满足配置的(主从存储数据几乎相同)。想要满足需求的话,那么只能去添加redis机器,也就是说我们要扩充或收缩节点,那么redis的集群(cluster)可以帮我们解决这个问题。

Redis Cluster集群想要完成高可用至少需要6个节点,同时为了保障故障转移也可以说是3对主从配置,cluster需要能够完成扩容(收缩)的操作,那么我们的数据一定是分布式存储的 。

分布式存储的问题及解决方法

  • 第一,我们首先会想到这有点类似于数据库的分表操作,比如一段时间或多少条数据存为一个表,那么当我们去查询数据的时候首先要知道我们的数据是存储于哪台节点;
  • 第二,当我们成功分表后,一旦想要改变的话,比如:增加表的数量(减少单表存储的数量提高查询速度),那么我已分配的表数据就需要重新分配。这两个问题Redis Cluster的设计成功帮助我们解决了这些问题。

Redis 集群采用 Gossip(流言)协议,Gossip 协议工作原理就是节点彼此不断通信交换信息,一段时间后所有的节点都会知道集群完整的信息,这种方式类似流言传播;集群中的数据是存储在数据槽中,可以理解为我们帮一部分数据放入一个箱子,并给改箱子一个标记并记录,下次查询数据通过某种算法可以通过记录直接找到对应的箱子。在扩充或收缩的时候直接挪动箱子就好了,并不需要计算每一条数据的分布位置。

虚拟槽分区

虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,比如 Redis Cluster 槽范围是 0~16383 。槽是集群内数据管理和迁移的基本单位。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。

集群搭建(下面3部按顺序执行)

准备节点

  • 性能:这是Redis赖以生存的看家本领,增加集群功能后当然不能对性能产生太大影响,所以Redis采取了P2P而非Proxy方式、异步复制、客户端重定向等设计,而牺牲了部分的一致性、使用性。
  • 水平扩展:集群的最重要能力当然是扩展,文档中称可以线性扩展到1000结点。 可用性:在Cluster推出之前,可用性要靠Sentinel保证。有了集群之后也自动具有了Sentinel的监控和自动Failover能力。
配置信息

#节点端口
port 6379
#开启集群模式
cluster-enabled yes
#节点超时时间,单位毫秒
cluster-node-timeout 15000
#集群内部配置文件
cluster-config-file “nodes-6379.conf”

在这里插入图片描述

Redis 集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。每个节点需要开启配置 cluster-enabled yes ,让 Redis 运行在集群模式下,上面的配置都相应的给到 redis 的配置文件当中并启动。

其他配置和单机模式一致即可,配置文件命名规则 redis-{port}.conf ,准备好配置后启动所有节点,第一次启动时如果没有集群配置文件,它会自动创建一份,文件名称采用 cluster-config-file 参数项控制,建议采用 node-{port}.conf 格式定义,也就是说会有两份配置文件。

当集群内节点信息发生变化,如添加节点、节点下线、故障转移等。节点会自动保存集群状态到配置文件中。需要注意的是, Redis 自动维护集群配置文件,不要手动修改,防止节点重启时产生集群信息错乱。

节点握手

节点握手是指一批运行在集群模式下的节点通过 Gossip 协议彼此通信,达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命令:

cluster meet {ip} {port}
在这里插入图片描述
握手流程:

  1. 节点6390本地创建6391节点信息对象,并发送 meet 消息
  2. 节点6391接受到 meet 消息后,保存6390节点信息并回复 pong 消息。
  3. 之后节点6390和6391彼此定期通过 ping/pong 消息进行正常的节点通信。

注意:

  1. 每个Redis Cluster节点会占用两个TCP端口,一个监听客户端的请求,默认是6379,另外一个在前一个端口加上10000, 比如16379,来监听数据的请求,节点和节点之间会监听第二个端口,用一套二进制协议来通信。
  2. 节点建立握手之后集群还不能正常工作,这时集群处于下线状态,所有的数据读写都被禁止
  3. 设置从节点作为一个完整的集群,需要主从节点,保证当它出现故障时可以自动进行故障转移。集群模式下,Reids 节点角色分为主节点和从节点。首次启动的节点和被分配槽的节点都是主节点,从节点负责复制主节点槽信息和相关的数据。

使用 cluster replicate {nodeId} 命令让一个节点成为从节点。其中命令执行必须在对应的从节点上执行,将当前节点设置为 node_id 指定的节点的从节点

在这里插入图片描述
将3组主从建立关联后
在这里插入图片描述

分配节点数据槽

在这里插入图片描述
完成
在这里插入图片描述

Cluster常用命令

  • CLUSTER info: 打印集群的信息。
  • CLUSTER nodes: 列出集群当前已知的所有节点(node)的相关信息。
  • CLUSTER meet : 将ip和port所指定的节点添加到集群当中。
  • CLUSTER addslots [slot …]: 将一个或多个槽(slot)指派(assign)给当前节点。
  • CLUSTER delslots [slot …]: 移除一个或多个槽对当前节点的指派。
  • CLUSTER slots: 列出槽位、节点信息。
  • CLUSTER slaves <node_id>: 列出指定节点下面的从节点信息。
  • CLUSTER replicate <node_id>: 将当前节点设置为指定节点的从节点。
  • CLUSTER saveconfig: 手动执行命令保存保存集群的配置文件,集群默认在配置修改的时候会自动保存配置文件。
  • CLUSTER keyslot : 列出key被放置在哪个槽上。
  • CLUSTER flushslots: 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
  • CLUSTER countkeysinslot : 返回槽目前包含的键值对数量。
  • CLUSTER getkeysinslot : 返回count个槽中的键。
  • CLUSTER setslot node <node_id> 将槽指派给指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指
  • 派。
  • CLUSTER setslot migrating <node_id> 将本节点的槽迁移到指定的节点中。
  • CLUSTER setslot importing <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
  • CLUSTER setslot stable 取消对槽 slot 的导入(import)或者迁移(migrate)。
  • CLUSTER failover: 手动进行故障转移。
  • CLUSTER forget <node_id>: 从集群中移除指定的节点,这样就无法完成握手,过期时为60s,60s后两节点又会继续完成握手。
  • CLUSTER reset [HARD|SOFT]: 重置集群信息,soft是清空其他节点的信息,但不修改自己的id,hard还会修改自己的id,不传该参数则使用soft方式。
  • CLUSTER count-failure-reports <node_id>: 列出某个节点的故障报告的长度。
  • CLUSTER SET-CONFIG-EPOCH: 设置节点epoch,只有在节点加入集群前才能设置。

redis-trib.rb 搭建集群

我们可以利用上述的命令搭建集群,但逐条的输入命令难免会令人烦躁。同dockr-compose一样,我们可以通过其他方式统一建立我们所需的集群。

redis-trib.rb 是采用 Ruby 实现的 Redis 集群管理工具。内部通过 Cluster 相关命令帮我们简化集群创建、检查、槽迁移和均衡等常见运维操作,使用之前需要安装 Ruby 依赖环境。

redis-trib.rb create --replicas 1 127.0.0.1:6391 127.0.0.1:6392

该命令后加入IP:PORT ,可一次性加入所有需要关联的节点,作用与上述的CLUSTER MEET相同,完成握手。

注意:redis-trib.rb如使用该文件,如果你的节点设置了密码,需要优先设置密码, 否则无法建立集群 Sorry, can’t connect to node。
在这里插入图片描述
该文件命令会帮助我们分配好主从以及虚拟槽的大小,如我们通常建立的3主从分配,会以前3个节点为主节点,将16384节点平均分配于3个节点:
在这里插入图片描述

加入集群

redis-trib.rb add-node + IP:PORT(新节点ip地址)+ IP:PORT(原集群内节点ip地址)
在这里插入图片描述

重新分配虚拟槽

通过上述命令我们向集群内添加了2个新的节点,那么我们需要重新分配虚拟槽,redis-trib.rb reshard + ip:port (我们要重新分配的节点)

在这里插入图片描述
这里会询问我们需要分配多少虚拟槽,之前帮助我们将16384平均分成3份,那么分成4份的话我们需要迁移多少个虚拟槽到该节点,这个数量由我们自己计算,这里我们首先指定分配多少,接下来会指定从哪个节点去取该数量的虚拟槽。
在这里插入图片描述
通过上面的图片我们可以知道,我们将1364个虚拟槽分配到 node ID为839 这个节点上,node ID为我们建立好握手时分配的节点ID。我们可以输入node ID来指定节点,输入done结束,当然也可以输入all全部转出。
在这里插入图片描述
通过这个图片我们可以了解新的虚拟槽已经分配完毕,从这个我们可以看出,在从指定的节点取出时并不是按顺序取出,这里保证的每个节点虚拟槽的数量

删除集群节点

redis-trib.rb del-node + ip:port
我们可以通过该命令来对已经分配好的节点进行删除,前提时该节点上不能由已分配好的虚拟槽。我们通过上面的reshard命令将该节点上的虚拟槽分配给其他的节点,最后执行上述命令。

集群常见问题

集群功能限制

Redis 集群相对单机在功能上存在一些限制,需要开发人员提前了解,在使用时做好规避。限制如下:

  • key 批量操作支持有限。如 mset、mget,目前只支持具有相同 slot 值的 key 执行批量操作。对于映射为不同 slot 值的 key 由于执行 mget、mset、delete 等操作可能存在于多个节点上因此不被支持。
  • key 事务操作支持有限。同理只支持多 key 在同一节点上的事务操作,当多个 key 分布在不同的节点上时无法使用事务功能。
  • 不支持多数据库空间。单机下的 Redis 可以支持16个数据库,集群模式下只能使用一个数据库空间,即 db0。
  • 复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值