Redis Cluster (Redis 集群),使用Redis自带的集群功能搭建无主模式集群

文章目录

    • 一、概述
    • 二、模拟配置说明
    • [三、脚本方式创建 Redis Cluster](#三、脚本方式创建 Redis Cluster)
      • [3.1 配置创建脚本](#3.1 配置创建脚本)
      • [3.2 启动集群实例](#3.2 启动集群实例)
      • [3.3 创建集群](#3.3 创建集群)
      • [3.4 测试集群](#3.4 测试集群)
      • [3.5 停止集群实例](#3.5 停止集群实例)
      • [3.6 删除(清空)集群](#3.6 删除(清空)集群)
    • [四、手动创建集群 Redis Cluster](#四、手动创建集群 Redis Cluster)
      • [4.1 启动集群实例](#4.1 启动集群实例)
      • [4.2 手动创建集群](#4.2 手动创建集群)
      • [4.4 测试集群](#4.4 测试集群)
    • 五、集群管理
      • [5.1 移动槽位](#5.1 移动槽位)
      • [5.2 查看集群基本信息](#5.2 查看集群基本信息)
      • [5.3 查看集群详细信息](#5.3 查看集群详细信息)

如果您对Redis的了解不够深入请关注本栏目,本栏目包括Redis安装Redis配置文件说明Redis命令和数据类型说明Redis持久化配置Redis主从复制和哨兵机制

一、概述

  • Redis 是一个开源的内存数据库,支持分布式部署。Redis Cluster (Redis 集群)是 Redis 的分布式解决方案,用于提供高可用性和可扩展性。Redis Cluster 通过分片(Sharding)和数据复制(Replication)来实现数据的分布和冗余,以提供高性能和容错能力。
  • 集群的原理是数据分治,即将数据分散到多个节点以实现分布式存储和处理。然而,这种数据分散的方式可能在某些情况下导致聚合操作(例如事务)变得更加复杂。
  • 在Redis应用中,要增强可用性 可以使用主备模式和主从模式(请看Redis主从模式配置)。 这是一种全量的主从复制机制,从是主的一个镜像 。但是这种方式并不能解决随着业务增加,导数据量增加的问题(因为他们是镜像,不能扩展容量),要解决容量 问题那就么需要集群
  • Redis Cluster 是把业务数据通过逻辑规则分散到不同的主从节点,解决了单个主从节点的单点故障问题(相当于对主节点做了高可用配置)。他一方面提高了扩展性,别一方面也提高了可用性(因为数据不在同一个主从节点,那么一般就不会出现所有数据同时失效的问题)。
  • 如果没有Redis集群,我们手动实现数据分治的逻辑一般如下:
    1. 根据业务场景进行分割。如按功能分割:用户、订单、产品等分配到不同Redis主从节点。
    2. 如果按业务拆分后还不能满足要求,还可以按优先级、逻辑再拆分(如每10000个ID一个Redis主从节点)。
  • 而默认的 Redis Cluster 使用了Hash Ring(哈希环)的概念来分片和管理数据。哈希环是一种数据结构,将数据节点(Redis 实例)映射到一个环形空间上。在 Redis Cluster 中,每个节点被分配一个槽位(slot),共有 16384 个槽位。数据根据键的哈希值被映射到对应的槽位上。假设有三个主从Redis 做了集群,槽位分布如下:
  • Redis Cluster 使用一种称为 Hash Slot Sharding 的分片策略。每个节点负责管理一部分槽位和对应槽位上的数据。当客户端发送命令到 Redis Cluster 时,首先根据命令中的键计算哈希值 ,并根据哈希值确定对应的槽位。然后,客户端将命令发送到负责该槽位的节点上,完成数据操作(所以他是一种无主模式集群,即没有那个主从节点是主节点,而是根据槽位计算)。这样,数据被均匀地分布在整个集群中的各个节点上。
  • 哈希环的使用使得 Redis Cluster 具备了分布式的能力,同时保证了高可用性和可扩展性。当节点加入或离开集群时,Redis Cluster 会自动进行槽位的重新分配,以保持数据的平衡和一致性。这种分片方式使得 Redis Cluster 能够水平扩展,支持处理大规模的数据和负载。

二、模拟配置说明

  • 下面我们使用三个主从Redis构成一个Redis Cluster(官方说一个Redis Cluster至少需要三个主从Redis,Redis主从模式配置请看这里)。默认创建的Redis Cluster的端口是30001、30002、30003、30004、30005、30006,如下示意图(集群实际端口与你们不一定能对上,但是思路是这样的):

三、脚本方式创建 Redis Cluster

  • 首先我们使用Redis官方自带的脚本创建 Redis Cluster 看看效果。使用Redis官方脚本有个好处是方便,因为他会自动做我们创建三个主从R edis,然后根据三个主从Redis再创建集群。

3.1 配置创建脚本

  • 在Redis源码的 utils/create-cluster/ 目录下有一个 create-cluster 脚本,打开这个脚本修改一下配置(不修改的话,有些是创建9个Redis实例,且主机地址是127.0.0.1。不如果你嫌麻烦也可以不修改,创建后按默认的配置访问即可,我这里了演示方便修改一下)。有关Redis源码编译安装请看这里
bash 复制代码
cd utils/create-cluster/
vi create-cluster
  • 修改 create-cluster 脚本的主要内容如下:
bash 复制代码
# 测试节点总数
NODES=6
# 从机数,这里相当于三主三从(master=total/slave+1)
REPLICAS=1

# 如果不是本机测试,则如下配置十分重要(具体可参考本栏目Redis配置文件说明)
# 配置集群主机信息,192.168.8.60 根据需要改您主机的IP。
CLUSTER_HOST=192.168.8.60
# 是否开启保护模式
PROTECTED_MODE=no

3.2 启动集群实例

  • 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 start 参数启动集群实例。
bash 复制代码
./create-cluster start

[root@yiqifu-redis create-cluster]# ./create-cluster start

Starting 30001

Starting 30002

Starting 30003

Starting 30004

Starting 30005

Starting 30006

  • 因为要搭建一个Redis集群至少需要3个主节点。一般3主3从,所以最少需要6个节点。这里脚本直接帮我们创建了6个实例。

3.3 创建集群

  • 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 create 参数将Redis实例创建为集群。
bash 复制代码
./create-cluster create

[root@yiqifu-redis create-cluster]# ./create-cluster create

>>> Performing hash slots allocation on 6 nodes...

Master[0] -> Slots 0 - 5460

Master[1] -> Slots 5461 - 10922

Master[2] -> Slots 10923 - 16383

Adding replica 127.0.0.1:30005 to 127.0.0.1:30001

Adding replica 127.0.0.1:30006 to 127.0.0.1:30002

Adding replica 127.0.0.1:30004 to 127.0.0.1:30003

>>> Trying to optimize slaves allocation for anti-affinity

[WARNING] Some slaves are in the same host as their master

M: cf12868ca9b7049ba7b73757aed83cf56e3e6b09 127.0.0.1:30001

slots:[0-5460] (5461 slots) master

M: f8521587351d126ee6618fee70bdc994c598fab0 127.0.0.1:30002

slots:[5461-10922] (5462 slots) master

M: 764d51f5a7a986f424cb218794a3fcbe493913b1 127.0.0.1:30003

slots:[10923-16383] (5461 slots) master

S: 46233ddb3462efcbf37b2d1e7229f9a54e36d9e8 127.0.0.1:30004

replicates f8521587351d126ee6618fee70bdc994c598fab0

S: 31d9d8aa6927509ec33b7534a3ddeb3e921ce171 127.0.0.1:30005

replicates 764d51f5a7a986f424cb218794a3fcbe493913b1

S: 89415c9c43b4515441f49ac285d2e0e1a80b4525 127.0.0.1:30006

replicates cf12868ca9b7049ba7b73757aed83cf56e3e6b09

Can I set the above configuration? (type 'yes' to accept): yes

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join

Performing Cluster Check (using node 127.0.0.1:30001)

M: cf12868ca9b7049ba7b73757aed83cf56e3e6b09 127.0.0.1:30001

slots:[0-5460] (5461 slots) master

1 additional replica(s)

S: 31d9d8aa6927509ec33b7534a3ddeb3e921ce171 127.0.0.1:30005

slots: (0 slots) slave

replicates 764d51f5a7a986f424cb218794a3fcbe493913b1

M: 764d51f5a7a986f424cb218794a3fcbe493913b1 127.0.0.1:30003

slots:[10923-16383] (5461 slots) master

1 additional replica(s)

M: f8521587351d126ee6618fee70bdc994c598fab0 127.0.0.1:30002

slots:[5461-10922] (5462 slots) master

1 additional replica(s)

S: 46233ddb3462efcbf37b2d1e7229f9a54e36d9e8 127.0.0.1:30004

slots: (0 slots) slave

replicates f8521587351d126ee6618fee70bdc994c598fab0

S: 89415c9c43b4515441f49ac285d2e0e1a80b4525 127.0.0.1:30006

slots: (0 slots) slave

replicates cf12868ca9b7049ba7b73757aed83cf56e3e6b09

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

3.4 测试集群

  • 使用 redis-cli 连接集群测试。由于Redis Cluster 是无主模式集群,我们创建的集群是三个主从。所以在连接时随便使用任何一个主的端口都可以(如:redis-cli -c -p 30001 、 redis-cli -c -p 30002 、 redis-cli -c -p 30003)。在使用时集群会根据键(key)的哈希(hash)计算槽位,然后定位到相应的主从上存取数据。如下测试示例
bash 复制代码
# -c 表示以集群的方式连接
# -p 指定端口
redis-cli -c -p 30001

[root@yiqifu-redis create-cluster]# redis-cli -c -p 30001

127.0.0.1:30001> set aaa 111

-> Redirected to slot [10439] located at 127.0.0.1:30002

OK

127.0.0.1:30002> set bbb 222

-> Redirected to slot [5287] located at 127.0.0.1:30001

OK

127.0.0.1:30001> set ccc 333

OK

127.0.0.1:30001> set {g1}aaa 111

-> Redirected to slot [13519] located at 127.0.0.1:30003

OK

127.0.0.1:30003> set {g1}bbb 222

OK

127.0.0.1:30003> set {g1}ccc 333

OK

127.0.0.1:30003> set {g1}ddd 444

OK

127.0.0.1:30003> set {g1}eee 555

OK

127.0.0.1:30003> multi

OK

127.0.0.1:30003> set {g1}bbb 222222

QUEUED

127.0.0.1:30003> set {g1}ccc 333333

QUEUED

127.0.0.1:30003> exec

  1. OK

  2. OK

127.0.0.1:30003>

  • 在使用时还可以使用"{组名}键"将不同的键(Key)分成一组放在同一个Redis主从中。在同一个Redis主从中就可以使用事务、监控等功能。如:这里使用"{g1}"作命名空间隔离,也就将带"{g1}"的key分到同一个redis中,这样才能方便在同一Redis中开启事务等操作。
  • 通过上面测试可以发现,Redis Cluster 无主模式集群,他会根据您输入的key的值计算存储在那个主从Redis中,并会自动跳转到相应的主从Redis节点上。

3.5 停止集群实例

  • 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 stop 参数将Redis Cluster 停止。
bash 复制代码
./create-cluster stop

[root@yiqifu-redis create-cluster]# ./create-cluster stop

Stopping 30001

Stopping 30002

Stopping 30003

Stopping 30004

Stopping 30005

Stopping 30006

3.6 删除(清空)集群

  • 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 clean 参数将Redis Cluster 所有配置清除(回到原来状态)。
bash 复制代码
./create-cluster clean

四、手动创建集群 Redis Cluster

  • 在实际生产环境中,Redis 主从实服务都是手动配置,Redis Cluster 也需要手动创建。下面演示手动创建Redis Cluster。

4.1 启动集群实例

  • 这里测试时我还是使用了脚本先启动了6个实例(启动实例只是启动Redis服务,并未创建集群),在生产环境中这些Redis实例是您自己在不同的服务器上配置的。
  • 我这里6台Redis实例的IP和端口分别如下:127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006。留意这个信息,后面有创建集群有用。
bash 复制代码
./create-cluster start

[root@yiqifu-redis create-cluster]# ./create-cluster start

Starting 30001

Starting 30002

Starting 30003

Starting 30004

Starting 30005

Starting 30006

  • 如果是自己配置 redis.conf 文件,我后通过 redis-server redis.conf 来启动实例,那么以下配置要正确修改才能创建集群。

    bash 复制代码
    # port 6391
    
    cluster-enabled yes
    
    # 配置集群配置文件为 nodes.conf
    # nodes.conf 无需手动创建,集群启动时会自动创建。
    cluster-config-file nodes.conf
    
    cluster-node-timeout 5000
    
    appendonly yes

4.2 手动创建集群

  • 根据现有Redis服务实例(这些实例是您分布在不同主机的Redis服务),使用命令手动创建集群。

    bash 复制代码
    redis-cli --cluster  create  127.0.0.1:30001  127.0.0.1:30002  127.0.0.1:30003  127.0.0.1:30004  127.0.0.1:30005  127.0.0.1:30006 --cluster-replicas 1
  • 参数说明

    • --cluster create 参数表示创建集群
    • --cluster-replicas 1 指定了每个主从Redis下,从节点的个数。由此可以推算出Redis集群中主从个数=节点总数 / (每个主从模式下从节点个数 + 1) = 6 / (1+1) = 3 个主从Redis。

4.4 测试集群

  • 同脚本创建方式,请自己测试
bash 复制代码
# -c 表示以集群的方式连接
redis-cli -c -p 30001

五、集群管理

5.1 移动槽位

  • 为什么要移动槽位?我想到以下几中情况:

    • 假设您添加了一个新的 Redis主从,则您需要把原集群的某些槽位均分到这个新的Redis主从上。
    • 假设您集群中某个Redis主从坏了 ,则您需要把这个坏掉的槽位均分到集群中其他Redis主从上。
    • 假设您某个Redis主从的硬件配置较低 ,别一个Redis主从的硬件配置较高,则您可以把硬件配置较低槽位分配一些到这个硬件配置较高的Redis主从上。
  • 在 Redis 中,槽(Slots)是用于分片数据的概念。Redis Cluster使用槽位来将数据分布到多个节点,以实现水平扩展和提高系统的可伸缩性和可用性。每个 Redis Cluster 包含16384个槽,这些槽可以用于分配数据。

  • 在创建集群的时候有这样一些信息,他说明了每个主从节点所分配的槽位信息。这里如Master[0]的槽位信息是 0 ~ 5460。和每个主从节点的ID和所属关系。如下,留意这些信息,后面会用到。

Master[0] -> Slots 0 - 5460

Master[1] -> Slots 5461 - 10922

Master[2] -> Slots 10923 - 16383

M: fc253a3c9f2c301f7c5f6e72b47a338237b3447d 127.0.0.1:30001

slots:[0-5460] (5461 slots) master

M: ab3db8a2ed5fc4066c3257344618d02059e88648 127.0.0.1:30002

slots:[5461-10922] (5462 slots) master

M: 5d4d3f51cf968ca13718e378b5ffd68452d70479 127.0.0.1:30003

slots:[10923-16383] (5461 slots) master

S: a82a0b7c77addee864259f02a6c38f47745c5da0 127.0.0.1:30004

replicates 5d4d3f51cf968ca13718e378b5ffd68452d70479

S: b2944e78407304948150003bc395de9165354010 127.0.0.1:30005

replicates fc253a3c9f2c301f7c5f6e72b47a338237b3447d

S: 934fc2185bd12ff361fd40ae1b26bd0355bdf6e3 127.0.0.1:30006

replicates ab3db8a2ed5fc4066c3257344618d02059e88648

  • 移动槽位命令语法:redis-cli --cluster reshard 集群任何一个主节点

    • --cluster reshard 参数表示移动槽位
  • 如下,我们将主机( 127.0.0.1:30001) 的2000个槽位移动到主机( 127.0.0.1:30002) 的过程。

    过程要查看集群中主从的ID,如果前没有记录,可以先看5.3节看命令。

bash 复制代码
# 进入集群移动槽位命令(在我的配置环境下,以下任何一条命令都可以)
redis-cli --cluster reshard 127.0.0.1:30001
# redis-cli --cluster reshard 127.0.0.1:30002
# redis-cli --cluster reshard 127.0.0.1:30003
  • 执行上面命令后会提示"How many slots do you want to move (from 1 to 16384)?"
    • 意思是"你想移动多少个槽位(取值范围是1~16384)?",但通过日志可以看到实际是(0 - 5460),比如我填:2000。
  • 然后会提示"What is the receiving node ID?"
    • 意思是"集群中那个主从节点接受这个2000个槽位信息?",通过日志可以看到主机( 127.0.0.1:30002)的ID,比如我移动到第二个节点填:ab3db8a2ed5fc4066c3257344618d02059e88648
  • 然后提示" Source node #1:"
    • 意思是"从那个节点移出这2000个槽位",通过日志可以看到主机( 127.0.0.1:30001)的ID,比如我选择第一个节点,填:fc253a3c9f2c301f7c5f6e72b47a338237b3447d
  • 然后提示" Source node #2:" 时输入"done"。然后一路都填 yes 完成

5.2 查看集群基本信息

  • 基本语法:redis-cli --cluster info 集群任何一个主节点
bash 复制代码
redis-cli --cluster info 127.0.0.1:30001

[root@yiqifu-redis create-cluster]# redis-cli --cluster info 127.0.0.1:30001

127.0.0.1:30001 (fc253a3c...) -> 0 keys | 3461 slots | 1 slaves.

127.0.0.1:30003 (5d4d3f51...) -> 0 keys | 7461 slots | 1 slaves.

127.0.0.1:30002 (ab3db8a2...) -> 0 keys | 5462 slots | 1 slaves.

  • 这里可以看到集群基本信息和槽位总数。

5.3 查看集群详细信息

  • 基本语法:redis-cli --cluster check 集群任何一个主节点
bash 复制代码
redis-cli --cluster check 127.0.0.1:30001

[root@yiqifu-redis create-cluster]# redis-cli --cluster check 127.0.0.1:30001

127.0.0.1:30001 (fc253a3c...) -> 0 keys | 3461 slots | 1 slaves.

127.0.0.1:30003 (5d4d3f51...) -> 0 keys | 7461 slots | 1 slaves.

127.0.0.1:30002 (ab3db8a2...) -> 0 keys | 5462 slots | 1 slaves.

[OK] 0 keys in 3 masters.

0.00 keys per slot on average.

>>> Performing Cluster Check (using node 127.0.0.1:30001)

M: fc253a3c9f2c301f7c5f6e72b47a338237b3447d 127.0.0.1:30001

slots:[2000-5460] (3461 slots) master

1 additional replica(s)

M: 5d4d3f51cf968ca13718e378b5ffd68452d70479 127.0.0.1:30003

slots:[0-1999],[10923-16383] (7461 slots) master

1 additional replica(s)

S: 934fc2185bd12ff361fd40ae1b26bd0355bdf6e3 127.0.0.1:30006

slots: (0 slots) slave

replicates ab3db8a2ed5fc4066c3257344618d02059e88648

M: ab3db8a2ed5fc4066c3257344618d02059e88648 127.0.0.1:30002

slots:[5461-10922] (5462 slots) master

1 additional replica(s)

S: a82a0b7c77addee864259f02a6c38f47745c5da0 127.0.0.1:30004

slots: (0 slots) slave

replicates 5d4d3f51cf968ca13718e378b5ffd68452d70479

S: b2944e78407304948150003bc395de9165354010 127.0.0.1:30005

slots: (0 slots) slave

replicates fc253a3c9f2c301f7c5f6e72b47a338237b3447d

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

  • 这里可以看到集群详细信息。每个主从槽位的具体范围,如:slots:[0-1999],[10923-16383] (7461 slots) master
相关推荐
路有瑶台几秒前
MySQL数据库学习(持续更新ing)
数据库·学习·mysql
数字扫地僧16 分钟前
WebLogic 版本升级的注意事项与流程
数据库
Viktor_Ye33 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
努力算法的小明1 小时前
SQL 复杂查询
数据库·sql
斗-匕1 小时前
MySQL 三大日志详解
数据库·mysql·oracle
代码中の快捷键1 小时前
MySQL数据库存储引擎
数据库·mysql
只因在人海中多看了你一眼1 小时前
数据库体系
数据库
尘浮生2 小时前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
六月闻君2 小时前
MySQL 报错:1137 - Can‘t reopen table
数据库·mysql
SelectDB技术团队2 小时前
兼顾高性能与低成本,浅析 Apache Doris 异步物化视图原理及典型场景
大数据·数据库·数据仓库·数据分析·doris