Redis集群实战搭建

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: redis3 到 redis5 开始支持集群,用的是 `ruby` 写的一个脚本,所以你需要先安装 ruby。然后根据官方提供了一个工具:redis-trib.rb(/redis-3.2.1/src/redis-trib.rb) 进行敲命令,一个个安装集群扩展。redis5以后的开发者们比较幸福了,redis直接支持了命令集群,在redis的 `redis-cli` 客户端直接配置集群

相关链接

redis集群演示服务分布图:https://www.kdocs.cn/view/l/sfN4qFXA2SyN

作者的docker-compose的redis集群:https://github.com/mailjobblog/dev_redis/tree/master/clusters/%E9%9B%86%E7%BE%A4

docker-compose 文件说明

该演示示例,使用 redis6.0.10 版本进行演示

文件中容器对应关系

容器名称 IP 客户端连接端口映射 集群端口映射 预想角色
redis-c1 172.31.0.11 6301->6379 16301->16379 master
redis-c2 172.31.0.12 6302->6379 16302->16379 master
redis-c3 172.31.0.13 6303->6379 16303->16379 master
redis-c4 172.31.0.14 6304->6379 16304->16379 slave
redis-c5 172.31.0.15 6305->6379 16305->16379 slave
redis-c6 172.31.0.16 6306->6379 16306->16379 slave
redis-c7 172.31.0.17 6307->6379 16307->16379 master (演示集群伸缩中使用)
redis-c8 172.31.0.18 6308->6379 16308->16379 slave (演示集群伸缩中使用)

初始服务分布如下

集群主要配置文件说明

# 端口
port 6379
# 是否开启集群
cluster-enabled yes
# 集群超时时间
cluster-node-timeout 5000
# 更新操作后进行日志记录
appendonly yes
# 集群配置文件
cluster-config-file "/redis/log/nodes.conf"
# 是否开启外部连接
protected-mode no
# redis守护进程
daemonize no
# 本地数据库存放目录
dir "/redis/data"
# redis日志文件
logfile "/redis/log/redis.log"
daemonize 设置yes或者no区别(默认:no)

daemonize:yes:redis采用的是单进程多线程的模式。当redis.conf中选项daemonize设置成yes时,代表开启守护进程模式。在该模式下,redis会在后台运行,并将进程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将一直运行,除非手动kill该进程。
daemonize:no: 当daemonize选项设置成no时,当前界面将进入redis的命令行界面,exit强制退出或者关闭连接工具(putty,xshell等)都会导致redis进程退出。

开始搭建集群

在宿主机 /data 上传 j_cluster

如果上传到了其他目录需要更改 yml 里面的数据卷映射条件

启动项目

# 进入到项目目录
cd /data/j_cluster

# 启动项目
docker-compose up -d

查看一下各个节点的ip

docker container inspect redis-c1 redis-c2 redis-c3 redis-c4 redis-c5 redis-c6 | grep IPv4Address

可以看到和我在 yam 中定义的ip一致

开始搭建集群

这里以进入 redis-c1 为例

docker exec -it redis-c1 /bin/bash

浏览一下redis的集群命令

以下命令只有 redis5 以后才有,redis5 以后redis发布了集群搭建命令
redis5 以前如果你要搭建的话,可以采用 Ruby 脚本

# 查看集群帮助文档
root@e4d19717bbed:/redis# redis-cli --cluster help

# 集群相关命令如下
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN   #创建集群
                 --cluster-replicas <arg>      #从节点个数
  check          host:port                     #检查集群
                 --cluster-search-multiple-owners #检查是否有槽同时被分配给了多个节点
  info           host:port                     #查看集群状态
  fix            host:port                     #修复集群
                 --cluster-search-multiple-owners #修复槽的重复分配问题
  reshard        host:port                     #指定集群的任意一节点进行迁移slot,重新分slots
                 --cluster-from <arg>          #需要从哪些源节点上迁移slot,可从多个源节点完成迁移,以逗号隔开,传递的是节点的node id,还可以直接传递--from all,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提示用户输入
                 --cluster-to <arg>            #slot需要迁移的目的节点的node id,目的节点只能填写一个,不传递该参数的话,则会在迁移过程中提示用户输入
                 --cluster-slots <arg>         #需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。
                 --cluster-yes                 #指定迁移时的确认输入
                 --cluster-timeout <arg>       #设置migrate命令的超时时间
                 --cluster-pipeline <arg>      #定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10
                 --cluster-replace             #是否直接replace到目标节点
  rebalance      host:port                                      #指定集群的任意一节点进行平衡集群节点slot数量 
                 --cluster-weight <node1=w1...nodeN=wN>         #指定集群节点的权重
                 --cluster-use-empty-masters                    #设置可以让没有分配slot的主节点参与,默认不允许
                 --cluster-timeout <arg>                        #设置migrate命令的超时时间
                 --cluster-simulate                             #模拟rebalance操作,不会真正执行迁移操作
                 --cluster-pipeline <arg>                       #定义cluster getkeysinslot命令一次取出的key数量,默认值为10
                 --cluster-threshold <arg>                      #迁移的slot阈值超过threshold,执行rebalance操作
                 --cluster-replace                              #是否直接replace到目标节点
  add-node       new_host:new_port existing_host:existing_port  #添加节点,把新节点加入到指定的集群,默认添加主节点
                 --cluster-slave                                #新节点作为从节点,默认随机一个主节点
                 --cluster-master-id <arg>                      #给新节点指定主节点
  del-node       host:port node_id                              #删除给定的一个节点,成功后关闭该节点服务
  call           host:port command arg arg .. arg               #在集群的所有节点执行相关命令
  set-timeout    host:port milliseconds                         #设置cluster-node-timeout
  import         host:port                                      #将外部redis数据导入集群
                 --cluster-from <arg>                           #将指定实例的数据导入到集群
                 --cluster-copy                                 #migrate时指定copy
                 --cluster-replace                              #migrate时指定replace
  help           

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

注意:Redis Cluster最低要求是3个主节点

创建集群主从节点

redis-cli --cluster create 172.31.0.11:6379  172.31.0.12:6379  172.31.0.13:6379 172.31.0.14:6379 172.31.0.15:6379 172.31.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.31.0.15:6379 to 172.31.0.11:6379
Adding replica 172.31.0.16:6379 to 172.31.0.12:6379
Adding replica 172.31.0.14:6379 to 172.31.0.13:6379
M: 50fa88c4a01f968df6ab7e8bd02e1bb51c85f13f 172.31.0.11:6379
   slots:[0-5460] (5461 slots) master
M: 04a2118b3f7b7521a55cf77171f1c50fe1a80f4d 172.31.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: b83a282329830e2ea686889cb8aa9eafa3441b8f 172.31.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 9b0a2284c341efa7055dd2046aec2e1c43ee6f9b 172.31.0.14:6379
   replicates b83a282329830e2ea686889cb8aa9eafa3441b8f
S: 09aca472595a229e7ceda2792aed98f88d757d45 172.31.0.15:6379
   replicates 50fa88c4a01f968df6ab7e8bd02e1bb51c85f13f
S: 2ce485e6a5bc5a3f300347c123ce911e605bf164 172.31.0.16:6379
   replicates 04a2118b3f7b7521a55cf77171f1c50fe1a80f4d
Can I set the above configuration? (type 'yes' to accept):

--cluster create : 表示创建集群
--cluster-replicas 0 : 表示只创建n个主节点,不创建从节点
--cluster-replicas 1 : 表示为集群中的每个主节点创建一个从节点(例:master[172.31.0.11:6379] -> slave[172.31.0.14:6379])

查看集群

# 查看节点主从关系
127.0.0.1:6379> cluster nodes
b83a282329830e2ea686889cb8aa9eafa3441b8f 172.31.0.13:6379@16379 master - 0 1612778025467 3 connected 10923-16383
04a2118b3f7b7521a55cf77171f1c50fe1a80f4d 172.31.0.12:6379@16379 master - 0 1612778025000 2 connected 5461-10922
50fa88c4a01f968df6ab7e8bd02e1bb51c85f13f 172.31.0.11:6379@16379 myself,master - 0 1612778024000 1 connected 0-5460
9b0a2284c341efa7055dd2046aec2e1c43ee6f9b 172.31.0.14:6379@16379 slave b83a282329830e2ea686889cb8aa9eafa3441b8f 0 1612778024565 3 connected
2ce485e6a5bc5a3f300347c123ce911e605bf164 172.31.0.16:6379@16379 slave 04a2118b3f7b7521a55cf77171f1c50fe1a80f4d 0 1612778024465 2 connected
09aca472595a229e7ceda2792aed98f88d757d45 172.31.0.15:6379@16379 slave 50fa88c4a01f968df6ab7e8bd02e1bb51c85f13f 0 1612778024000 1 connected

# 列出槽和节点信息
127.0.0.1:6379> cluster slots
1) 1) (integer) 10923
   2) (integer) 16383
   3) 1) "172.31.0.13"
      2) (integer) 6379
      3) "b83a282329830e2ea686889cb8aa9eafa3441b8f"
   4) 1) "172.31.0.14"
      2) (integer) 6379
      3) "9b0a2284c341efa7055dd2046aec2e1c43ee6f9b"
2) 1) (integer) 5461
   2) (integer) 10922
   3) 1) "172.31.0.12"
      2) (integer) 6379
      3) "04a2118b3f7b7521a55cf77171f1c50fe1a80f4d"
   4) 1) "172.31.0.16"
      2) (integer) 6379
      3) "2ce485e6a5bc5a3f300347c123ce911e605bf164"
3) 1) (integer) 0
   2) (integer) 5460
   3) 1) "172.31.0.11"
      2) (integer) 6379
      3) "50fa88c4a01f968df6ab7e8bd02e1bb51c85f13f"
   4) 1) "172.31.0.15"
      2) (integer) 6379
      3) "09aca472595a229e7ceda2792aed98f88d757d45"

数据存储

# 直接存储提示槽信息不对
127.0.0.1:6379> set name libin
(error) MOVED 5798 172.31.0.12:6379

# 客户端连接加入 -c 数据可以直接被重定向到槽服务器
root@00bfb4f9402a:/redis# redis-cli -c
127.0.0.1:6379> set name libin
-> Redirected to slot [5798] located at 172.31.0.12:6379
OK

# 存储多个key的时候,由于不同的槽服务器,报错问题
172.31.0.12:6379> mset k1 v1 k2 v2
(error) CROSSSLOT Keys in request don't hash to the same slot

# 加入一个 tag 即可解决
172.31.0.12:6379> mset {
   
   r}k1 v1 {
   
   r}k2 v2
OK

集群伸缩

1、准备新的redis节点服务器
2、加入到集群中
3、分配数据槽和迁移数据

加入一个新的 master 节点

redis-cli -h 172.31.0.17 --cluster add-node 172.31.0.17:6379 172.31.0.11:6379
  • 这里的新加入的master节点是 172.31.0.17
  • 172.31.0.11 代表的事现在存在的集群中的任意一个 master 节点

为新加入的 master 节点添加一个 slave 节点

redis-cli -h 172.31.0.17 --cluster add-node 172.31.0.18:6379 172.31.0.17:6379 --cluster-slave
  • 172.31.0.17 代表上面行加入的 master 节点
  • 172.31.0.18 代表为 master(172.31.0.17)加入的从节点
  • --cluster-slave 代表是 slave(从节点)的身份

删除 slave 节点

redis-cli -h 172.31.0.18 --cluster del-node 172.31.0.18:6379 3a12f6b4ed5f26b83525681e73ee23750bcbcfbf
  • 3a12f6b4ed5f26b83525681e73ee23750bcbcfbf 是通过 cluster nodes 命令得到的节点ID
  • 如果上面有数据的话,无法删除,需要先迁移数据

为节点分配槽

# 指定分配
redis-cli -h 172.31.0.11 --cluster reshard 172.31.0.11:6379

# 平均分配
redis-cli -h 172.31.0.11 --cluster rebalance 172.31.0.11:6379
  • 172.31.0.11 这个只要是随便一个 master 节点都可以操作集群

分配槽演示

# 可以先看到节点信息

>>> Performing Cluster Check (using node 172.31.0.11:6379)
M: 9af405be84c1d448988117f88f78fa588d49a196 172.31.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 3a12f6b4ed5f26b83525681e73ee23750bcbcfbf 172.31.0.18:6379
   slots: (0 slots) slave
   replicates 34a33c9df9d909e69e5cad8965d905b72959c677
S: 7c35cf01519c5747ca262769ed47dbbe44eeb830 172.31.0.14:6379
   slots: (0 slots) slave
   replicates 780d17c7c9ca86f68b6119762f0958f00093702a
M: 780d17c7c9ca86f68b6119762f0958f00093702a 172.31.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 34a33c9df9d909e69e5cad8965d905b72959c677 172.31.0.17:6379
   slots: (0 slots) master
   1 additional replica(s)
S: a4956784b0221598c23d18fbcad844e18eefab63 172.31.0.15:6379
   slots: (0 slots) slave
   replicates 9af405be84c1d448988117f88f78fa588d49a196
M: ddf46bbdf6794d12debe824ce4e30ea96cd70212 172.31.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: a2820f32aa18e7ec2d880aedc8d91c9db840dcd9 172.31.0.16:6379
   slots: (0 slots) slave
   replicates ddf46bbdf6794d12debe824ce4e30ea96cd70212
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
  • 可以看到这里新加入的master 172.31.0.17 没有数据槽
# 询问要迁移的槽的数量(我在这里迁移了500个)
How many slots do you want to move (from 1 to 16384)? 500
# 询问被迁移的槽的ID(我这里迁移的是:172.31.0.11)
What is the receiving node ID? 34a33c9df9d909e69e5cad8965d905b72959c677
# 请输入所有源节点ID
Please enter all the source node IDs.
   # 键入“all”将所有节点用作哈希槽的源节点
  Type 'all' to use all the nodes as source nodes for the hash slots.
   # 输入所有源节点ID后键入“done”。
  Type 'done' once you entered all the source nodes IDs.
# 输入源的ID后,进行迁移
Source node #1: 9af405be84c1d448988117f88f78fa588d49a196
Source node #2: done
  • 用这个方法,也可以把某一个源的槽都迁移后。那么该槽就可以进行删除了

搭建问题

创建集群主从节点报错

[ERR] Node 172.31.0.11:6379 is not configured as a cluster node
查看配置文件的配置问题

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
127 0
|
21天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
48 5
|
27天前
|
缓存 NoSQL Java
Spring Boot与Redis:整合与实战
【10月更文挑战第15天】本文介绍了如何在Spring Boot项目中整合Redis,通过一个电商商品推荐系统的案例,详细展示了从添加依赖、配置连接信息到创建配置类的具体步骤。实战部分演示了如何利用Redis缓存提高系统响应速度,减少数据库访问压力,从而提升用户体验。
69 2
|
2月前
|
缓存 NoSQL 应用服务中间件
Redis实战篇
Redis实战篇
|
3月前
|
SQL 存储 NoSQL
Redis6入门到实战------ 一、NoSQL数据库简介
这篇文章是关于NoSQL数据库的简介,讨论了技术发展、NoSQL数据库的概念、适用场景、不适用场景,以及常见的非关系型数据库。文章还提到了Web1.0到Web2.0时代的技术演进,以及解决CPU、内存和IO压力的方法,并对比了行式存储和列式存储数据库的特点。
Redis6入门到实战------ 一、NoSQL数据库简介
|
3月前
|
NoSQL 算法 安全
Redis6入门到实战------ 四、Redis配置文件介绍
这篇文章详细介绍了Redis配置文件中的各种设置,包括单位定义、包含配置、网络配置、守护进程设置、日志记录、密码安全、客户端连接限制以及内存使用策略等。
Redis6入门到实战------ 四、Redis配置文件介绍
|
3月前
|
NoSQL Redis 数据安全/隐私保护
Redis6入门到实战------ 二、Redis安装
这篇文章详细介绍了Redis 6的安装过程,包括下载、解压、编译、安装、配置以及启动Redis服务器的步骤。还涵盖了如何设置Redis以在后台运行,如何为Redis设置密码保护,以及如何配置Redis服务以实现开机自启动。
Redis6入门到实战------ 二、Redis安装
|
3月前
|
NoSQL Java Redis
Redis6入门到实战------思维导图+章节目录
这篇文章提供了Redis 6从入门到实战的全面学习资料,包括思维导图和各章节目录,涵盖了NoSQL数据库、Redis安装配置、数据类型、事务、持久化、主从复制、集群等核心知识点。
Redis6入门到实战------思维导图+章节目录
|
3月前
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
3月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀