Redis集群

Redis 集群是 Redis 官方提供的分布式数据库解决方案,在 3.0 版本中被正式引入。它的主要目标是解决单点 Redis 实例在数据存储容量、高可用性和并发处理能力上的瓶颈。


一、为什么需要 Redis 集群?

想象一下,你只有一个 Redis 实例:

  1. 数据容量瓶颈:所有数据都存在这一台服务器的内存里。当数据量超过服务器物理内存时,就无法再存储新数据了。
  2. 性能瓶颈:所有读写请求都由这一台服务器处理。当并发请求数量巨大时,CPU、网络带宽和内存都会成为性能瓶颈,导致响应变慢。
  3. 可用性瓶颈:这是最致命的问题。如果这台服务器宕机或者网络中断,那么整个 Redis 服务就不可用了,所有依赖它的应用都会瘫痪。这就是“单点故障”(Single Point of Failure)。

Redis 集群就是为了解决以上三个核心问题而生的。


二、Redis 集群的核心概念

理解 Redis 集群,首先要掌握以下几个关键概念:

1. 数据分片

这是解决容量和性能瓶颈的核心思想。Redis 集群将整个数据集自动分割成 16384 个哈希槽。

  • 什么是哈希槽? 你可以把它想象成一个虚拟的“格子”或“桶”,整个集群的数据都存放在这些格子里。集群固定有 16384 个槽(编号 0-16383)。
  • 如何分配? 这些哈希槽会被平均分配到集群中的各个主节点上。
    • 例如,一个有 3 个主节点的集群:
      • 节点 A 可能包含槽 0 到 5460。
      • 节点 B 可能包含槽 5461 到 10922。
      • 节点 C 可能包含槽 10923 到 16383。
  • 数据如何存储? 当你要存储一个键值对(如 SET mykey "hello")时,Redis 会执行以下步骤:
    1. 计算键 mykey 的 CRC16 校验和。
    2. 将校验和对 16384 取模,得到一个数字 HASH_SLOT = CRC16("mykey") % 16384
    3. 根据计算出的 HASH_SLOT,找到负责这个槽的节点。
    4. 将该键值对存储到对应的节点上。

好处

  • 水平扩展:当数据量增大时,只需向集群中添加新的主节点,并将一部分哈希槽从旧节点迁移到新节点,即可实现扩容。
  • 负载均衡:读写请求被分散到不同的节点上,充分利用了多台服务器的计算能力。
2. 主从复制

这是解决高可用性的核心思想。Redis 集群采用主从复制模型,但它是基于分片的主从复制

  • 结构:集群中的每个主节点都可以有一个或多个从节点。
  • 数据同步:从节点会实时复制其主节点上的所有数据和操作。数据是异步复制的。
  • 故障转移:这是关键。当一个主节点宕机时:
    1. 集群中的其他节点会检测到该主节点失联。
    2. 该主节点的从节点之间会进行选举(基于 Raft 算法的共识机制)。
    3. 其中一个从节点会被选举为新的主节点。
    4. 新的主节点会接管原来主节点负责的所有哈希槽,并继续提供服务。
    5. 整个过程对客户端是自动、透明的,通常只需要几秒钟到几十秒。

好处

  • 高可用:即使某个主节点挂了,它的从节点能立即顶上,保证服务不中断。
  • 数据冗余:数据在主从节点上都有备份,避免了单点数据丢失的风险。
3. 一个典型的 Redis 集群架构

一个最基本、高可用的 Redis 集群通常需要 6 个节点:3 个主节点 + 3 个从节点(每个主节点配 1 个从节点)。

      +-------------+       +-------------+
      |  Master A   | ----> |  Slave A1   |
      | (Slots 0-5460) |     +-------------+
      +-------------+
             |
             | (Gossip Protocol)
             |
+-------------+       +-------------+
|  Master B   | ----> |  Slave B1   |
| (Slots 5461-10922) |   +-------------+
+-------------+
             |
             |
+-------------+       +-------------+
|  Master C   | ----> |  Slave C1   |
| (Slots 10923-16383)|   +-------------+
+-------------+
4. Gossip 协议

集群中的节点之间需要通信,以交换状态信息(如节点是否在线、负责哪些槽等)。Redis 集群使用 Gossip 协议来完成这件事。

  • 工作方式:每个节点都会定期与其他几个随机节点交换信息。
  • 传播内容:节点会把自己所知道的关于集群的信息(包括其他节点的状态)告诉对方。
  • 效果:就像谣言一样,信息会迅速、可靠地传播到整个集群中的所有节点,最终所有节点都能达成一致的集群视图。这使得集群能够快速发现故障节点和新的节点。

三、Redis 集群的特性与限制

主要特性
  • 自动分片:数据自动分割到多个节点。
  • 高可用:主节点故障时,从节点能自动提升为主节点,继续服务。
  • 在线扩容/缩容:可以动态地添加或删除节点,并重新分配哈希槽,不影响服务(或影响很小)。
  • 部分可用性:即使集群中有一部分节点(例如一个主节点和它的所有从节点)发生故障,只要大部分主节点还在,集群仍然可以处理那些指向可用节点的请求。
重要限制(使用时必须注意)
  1. 不支持多数据库空间:单机 Redis 默认有 16 个数据库(db0-db15)。但在集群模式下,只能使用 db0SELECT 命令被禁用。这是因为集群需要明确知道每个键属于哪个哈希槽,而多数据库空间会使这个映射变得复杂。

  2. 涉及多个键的操作受限:由于一个键可能分布在不同的节点上,所以那些需要同时操作多个键的命令会受到限制。

    • 不允许:跨槽位的 MGETMSETSUNION 等操作。
    • 允许:如果所有键都在同一个哈希槽中,那么多键操作是允许的。如何保证?使用哈希标签
      • 哈希标签:如果一个键包含 {},例如 user{1000}:profile 和 user{1000}:orders,Redis 只会计算 {} 内部字符串(这里是 1000)的哈希槽。因此,这两个键会被存储在同一个节点上,可以安全地进行多键操作。
  3. 事务是单节点的MULTI/EXEC 事务中的所有命令都必须在同一个节点上执行(即所有键的哈希槽相同)。否则事务会失败。

  4. Keys 命令的性能问题KEYS * 命令在集群中变得非常危险和低效。因为它需要在每个节点上执行,然后合并结果,可能会阻塞整个集群。在生产环境中,应该使用 SCAN 命令代替。

  5. 客户端需要支持集群模式:普通的 Redis 客户端无法直接连接 Redis 集群。客户端必须实现“集群感知”(Cluster-aware)功能,能够:

    • 连接到集群中的任意一个节点。
    • 发送命令后,如果收到 -MOVED 或 -ASK 重定向错误,能自动解析错误信息,找到正确的节点,并重新发送命令。
    • 大多数现代编程语言的 Redis 客户端库(如 Jedis, Lettuce for Java; redis-py for Python)都提供了对集群的支持。

四、如何搭建和管理 Redis 集群?

1. 搭建方式
  • 手动搭建(不推荐):通过配置文件和 redis-cli 命令手动创建节点、分配槽、建立主从关系。过程繁琐,容易出错。
  • 使用 redis-trib.rb(旧版):在 Redis 5.0 之前,官方推荐使用 Ruby 脚本 redis-trib.rb 来创建和管理集群。
  • 使用 redis-cli(推荐):从 Redis 5.0 开始,集群管理功能被集成到了原生的 redis-cli 中,不再依赖 Ruby。这是目前最标准、最简单的方式。
2. 使用 redis-cli 创建集群的简要步骤

假设你有 6 台机器(或一台机器的 6 个不同端口),已经启动了 6 个 Redis 实例。

# 假设 6 个节点的 IP 和端口如下
# 192.168.1.10:7000, 192.168.1.10:7001
# 192.168.1.11:7002, 192.168.1.11:7003
# 192.168.1.12:7004, 192.168.1.12:7005

# 1. 创建集群
# --cluster-replicas 1 表示为每个主节点创建 1 个从节点
# 命令会自动将前 3 个节点作为主节点,后 3 个作为它们的从节点
redis-cli --cluster create 192.168.1.10:7000 192.168.1.10:7001 192.168.1.11:7002 192.168.1.11:7003 192.168.1.12:7004 192.168.1.12:7005 --cluster-replicas 1

# 2. 检查集群状态
redis-cli --cluster check 192.168.1.10:7000

# 3. 查看集群信息
redis-cli -c -p 7000 cluster info
redis-cli -c -p 7000 cluster nodes
3. 扩容示例:添加一个新主节点
# 1. 启动一个新的 Redis 实例,端口为 7006
# 2. 将新节点添加到集群中
redis-cli --cluster add-node 192.168.1.13:7006 192.168.1.10:7000

# 3. 重新分配哈希槽
# 将一部分槽从旧节点迁移到新节点
redis-cli --cluster reshard 192.168.1.10:7000
# 然后根据提示输入要迁移的槽数量、接收槽的目标节点ID等

五、总结:单机、主从、哨兵、集群如何选择?

方案优点缺点适用场景
单机部署简单,性能高存在单点故障,容量和性能有上限开发、测试环境,或数据量极小、可用性要求不高的场景。
主从复制读写分离,提高了读性能,数据有备份故障转移需要手动干预,写操作依然是单点读多写少,且对自动故障转移要求不高的场景。
哨兵自动故障转移,系统高可用写操作依然是单点,难以实现水平扩容对高可用有要求,但数据量不大,写并发不高的场景。
集群数据分片,解决了容量和性能瓶颈;高可用,自动故障转移架构复杂,有功能限制(多键操作等),运维成本高生产环境首选。数据量大、并发高、对可用性和扩展性有严格要求的场景。

简单来说

  • 如果你的数据量在单机内存范围内,且对高可用有要求,用 哨兵
  • 如果你的数据量超过了单机内存,或者并发量极高,那么 集群 是你唯一的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值