Redis的集群

Redis集群提供分布式解决方案,缓解单机内存和并发限制。采用一致性哈希解决扩容问题,通过虚拟节点实现更均匀的数据分布。虚拟槽分区进一步优化了数据分布,减少了扩容时的数据迁移。然而,集群存在key批量操作和事务操作的限制,且节点握手过程确保集群稳定性。

概述

集群是Redis在3.0版本正式推出的分布式解决方案,有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以得到有效解决,并且集群模式有效解决了哨兵模式中哨兵的消耗和哨兵工作的低效率性。
集群服务是Redis多机运行的最完美的终极方案, 其完全抛弃了主从同步和哨兵模式, 真正实现了多主多从。

分布式存储

分布式数据库首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集。
假设有10万个用户在该网站登录, 如果要存储这些数据需要的空间一定是较大的, 单机肯定是不行的, 必须使用分布式存储, 比分布10台机器, 每台机器存储1万个用户。

  • 简单哈希
    我们可以采用除留余数法来完成一个映射,key值为用户账号,余数为机器数量,得到的结果就是应该存储的机器的编号。
    缺点
    当需要进行扩容的时候,比如我们新增加一台机器,那由于哈希函数是和机器数相关的,我们就必须把全部数据进行一个全部重新再散列,这开销是无法想象的,所以有了一致性哈希算法。
  • 一致性哈希算法
    为了解决上述问题,一致性哈希将哈希构造成一个0~2^32-1的环形结构,并将余数从原来的机器数量修改值为整型最大值(也可以是比这个更大的)。因为这个数据足够大,所以不需要考虑因为机器数增加导致的完全rehash问题。
    机器号 = hash(账号) % 2^32
    我们将环中的某一区间去映射到某台服务器,让这台服务器负责这个区间的管理。当我们要查询某个数据的时候,根据哈希函数算出的映射位置来找到包含该位置的那个区间所对应的服务器,然后在那个服务器中进行操作即可。
    如果原先的服务器不够用了,此时增加1个服务器,也不需要像之前一样对所有机器的数据进行迁移,我们只需要迁移负载重的机器即可, 将原先这台机器负责的区间进行划分一人再负责一半区间, 然后将原先服务器的数据进行rehash即可。
    这样就大大提高了效率,对于增加和删除节点只影响相邻节点。
    缺点
    1.当使用少量节点时,节点变化将大范围影响哈希环中数据映射,因此这种方式不适合少量数据节点的分布式方案, 此时就会出现这种情况,部分节点数据过少,而部分节点数据过多,此时的数据大量集中在一个节点上,因为节点分布不均匀而导致数据倾斜问题。
    虚拟节点
    可以考虑在不增加服务器的基础上多增加几个节点,所以为了解决这问题,一致性哈希又引入了虚拟节点。我们不需要改变数据定位的算法,只需要将虚拟节点与服务节点进行映射,将定位到虚拟节点的节点再定位回服务节点即可。
    并且还有一个好处就是用虚拟节点要增加或者减少服务器的时候就可以可以将原来的虚拟节点变成一个真的节点, 将原来由这个虚拟节点映射过来的数据直接复制到新节点上, 就省去了rehash的操作
    2.因为redis是一个高速的存储服务器 , 即使使用一致性hash在扩容的时候还是会导致一个节点的部分时间不可用。
    虚拟槽分区
    虚拟槽中的槽就是大量的虚拟节点的抽象化, 将原来的虚拟节点变成一个槽, redis内置是有16383个槽也就是有16383个虚拟节点。
    虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中。这样每个槽映射的数据就是比较均匀的。
    当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;
    当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;
    中间也不需要停掉任何一个节点服务。

集群缺点

  • key批量操作支持有限。如mset(批量赋值)、mget(批量取值),目前只支持具有相同slot值的 key执行批量操作。
  • key事务操作支持有限。同理只支持多key在同一节点上的事务操作,当多个key分布在不同的节点上时无法使用事务功能

节点握手

Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。
当我们启动6个节点,但每个节点彼此并不知道对方的存在,通过节点握手让6个节点彼此建立联系从而组成一个集群
节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信, 达到感知对方的过程,并会交换一些彼此信息。

  • meet消息:用于通知新节点加入。消息发送者通知接收者加到当前集群,meet消息通信正常完成后,接收节点会加入到集群中并进行周期性的 ping、pong消息交换
  • ping消息:集群内每个节点每秒向多个其 他节点发送ping消息,用于检测节点是否在线和交换彼此状态信息。ping消息发送封装了自身节点和部分其他节点的状态数据。
  • pong消息:当接收到ping、meet消息时,作为响应消息回复给发送方确认消息正常通信。pong消息内部封装了自身状态数据。节点也可以向集群内 广播自身的pong消息来通知整个集群对自身状态进行更新
  • fail消息:当节点判定集群内另一个节点下线时,会向集群内广播一个 fail消息,其他节点接收到fail消息之后把对应节点更新为下线状态。
### Redis 集群的搭建与配置 #### 一、Redis 集群简介 Redis 是一种高性能的键值存储系统,支持多种数据结构操作。通过集群模式可以实现分布式存储和高可用性。Redis 集群允许多个 Redis 实例协同工作,提供更高的吞吐量和更强的数据持久化能力。 --- #### 二、环境准备 在开始之前,需确认以下条件已满足: - 所有服务器的操作系统版本一致(如 CentOS 7 或 Windows),并安装了相同版本的 Redis 软件。 - 已关闭防火墙或开放必要的端口(默认 Redis 使用 6379 及其衍生端口)。 - 每服务器上至少有两个 Redis 实例运行,分别作为主节点和从节点[^1]。 --- #### 三、具体步骤 ##### 1. 下载并解压 Redis 文件 下载指定版本的 Redis 压缩包(如 Redis 6.2.5 或更高版本),将其解压到目标路径下。例如,在 Linux 中执行以下命令: ```bash wget http://download.redis.io/releases/redis-6.2.5.tar.gz tar -zxvf redis-6.2.5.tar.gz cd redis-6.2.5 make ``` ##### 2. 创建多个实例目录 为每个 Redis 实例创建独立的工作目录,并复制 `redis.conf` 至对应文件夹中。例如: ```bash mkdir -p /service/redis/{6379,6380} cp redis.conf /service/redis/6379/ cp redis.conf /service/redis/6380/ ``` ##### 3. 修改配置文件 编辑每个实例下的 `redis.conf` 文件,设置不同的监听端口号和其他必要参数。以下是关键配置项: - 设置绑定 IP 地址:`bind 0.0.0.0` - 关闭保护模式:`protected-mode no` - 开启集群功能:`cluster-enabled yes` - 指定集群配置文件位置:`cluster-config-file nodes-{port}.conf` - 设定日志级别:`loglevel notice` ##### 4. 启动 Redis 实例 依次启动各个 Redis 实例。例如: ```bash redis-server /service/redis/6379/redis.conf redis-server /service/redis/6380/redis.conf ``` 如果是在多物理机上部署,则需要远程登录每机器重复上述过程[^2]。 ##### 5. 构建集群拓扑 利用 `redis-cli` 的集群管理工具完成初始化操作。假设当前存在六个节点分布在三主机上,则可输入如下指令构建集群关系: ```bash redis-cli --cluster create \ 192.168.x.y:6379 192.168.x.z:6379 ... \ --replicas 1 ``` 其中 `--replicas` 参数表示每个主节点分配几个副本[^4]。 ##### 6. 验证集群状态 最后可以通过以下方式验证集群是否正常运作: ```bash redis-cli -c -h {任意IP} -p {任一口号} CLUSTER INFO CLUSTER NODES PING SET key value GET key ``` --- #### 四、注意事项 - 如果使用 Docker 容器来部署 Redis 集群,请确保容器间网络互通良好。 - 对于 Windows 平上的开发测试场景,可通过批处理脚本来简化服务启动流程[^3]。 --- #### 五、示例代码片段 下面展示了一个简单的 Python 程序用于连接至 Redis 集群并向其中写入一条记录: ```python import redis r = redis.StrictRedisCluster(startup_nodes=[{"host": "127.0.0.1", "port": "6379"}], decode_responses=True) r.set('foo', 'bar') print(r.get('foo')) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lhj_loveFang_1105

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值