一文搞定现网项目最新版本Redis7集群800节点实践案例总结

2024-08-01 12:40:12 浏览数 (2)

概述

截至目前本人接触到的最大Redis7集群节点规模已达800 ,Redis官方宣称最大集群节点规模可达1000。本文以最小规模集群为例,进行完整的项目实践总结记录。欢迎关注微信公众号:大数据从业者

Redis是一种基于内存的数据存储,已经被数百万开发人员用于缓存、向量数据库、文档数据库、流媒体引擎和消息队列等场景。Redis具有主从复制协议和不同级别的磁盘持久性机制。Redis支持复杂的数据类型(如:字符串、哈希、列表、集合、排序集合和JSON),并在这些数据类型上定义了原子操作。

Redis安装支持多种操作系统、多种安装方式,如下:

说明:RedisStack基于Redis进行扩展整合RediSearch、RedisJSON、RedisTimeSeries 和 RedisBloom等,启动脚本如下:

而RedisInsight用于可视化Redis或Redis Stack中的数据,如下图所示:

Redis官方并没有提供界面化向导安装方式,我这里使用源码编译安装。

源码安装

Redis版本选择最新的7.0.15,相关release notes,感兴趣请自行阅读:

代码语言:javascript复制
https://raw.githubusercontent.com/redis/redis/7.0/00-RELEASENOTES

下载源码

代码语言:javascript复制
wget https://download.redis.io/releases/redis-7.0.15.tar.gz
tar -xvf redis-7.0.15.tar.gz && redis-7.0.15

编译安装

代码语言:javascript复制
make -j 8
make install PREFIX=/home/myHadoopCluster/redis7
代码语言:javascript复制
cp redis.conf /home/myHadoopCluster/redis7/
ln -s /home/myHadoopCluster/redis7/bin/redis-cli /usr/bin/redis-cli
ln -s /home/myHadoopCluster/redis7/bin/redis-server /usr/bin/redis-server

集群部署

主机

felixzh

felixzh1

felixzh2

端口1

6378

6378

6378

端口2

6379

6379

6379

cp redis.conf redis6378.conf

redis6378.conf配置如下:

代码语言:javascript复制
cluster-enabled yes
cluster-config-file /home/myHadoopCluster/redis7/nodes6378.conf
bind 0.0.0.0
protected-mode no
port 6378
daemonize yes
pidfile /var/run/redis_6378.pid
logfile /var/log/redis/redis_6378.log
dbfilename dump6378.rdb    
appendonly yes
appendfilename appendonly6378.aof

cp redis6378.conf redis6379.conf

redis6379.conf配置如下:

代码语言:javascript复制
sed -i 's/6378/6379/' redis6379.conf                  

创建必要的目录,如mkdir /var/log/redis

分发/home/myHadoopCluster/redis7到所有集群节点

启动所有集群节点的Redis实例

代码语言:javascript复制
[root@felixzh redis7]# redis-server redis6378.conf && redis-server redis6379.conf
[root@felixzh1 redis7]# redis-server redis6378.conf && redis-server redis6379.conf
[root@felixzh2 redis7]# redis-server redis6378.conf && redis-server redis6379.conf             

如果需要停止单节点Redis实例,如下:

代码语言:javascript复制
ps -ef|grep redis-server|grep -v grep|awk '{print $2}' |xargs kill -9              

创建Redis集群

代码语言:javascript复制
[root@felixzh redis7]# redis-cli --cluster create ip1:6378 ip1:6379 ip2:6378 ip2:6379 ip3:6378 ip3:6379 --cluster-replicas 1

查看集群状态

代码语言:javascript复制
[root@felixzh redis7]# redis-cli -h felixzh -p 6378 cluster info

如上图,集群状态正常,集群实例数为6,集群节点数为3。

界面化工具

考虑到License限制,我们内部自研界面化管理平台。开源项目众多,需要的话,可以自行部署,比如RedisInsight等等。

数据备份迁移

Redis官方提供备份工具cluster backup,可以直接使用。而数据迁移可以使用redis-shake,支持离线迁移和在线迁移、同构集群和异构集群。

Redis-shake文档见:

代码语言:javascript复制
https://tair-opensource.github.io/RedisShake/zh/guide/introduction.html

Redis-shake源码编译,如下:

代码语言:javascript复制
git clone https://github.com/alibaba/RedisShake
cd RedisShake
sh build.sh       

实践案例如下:

1.生成测试数据

批量生成10万测试数据到redis1集群

代码语言:javascript复制
[root@felixzh redis7]# cat batchSet.sh
#!/bin/sh
for((i=0;i<100000;i  ))
do
   echo "value" |redis-cli -c -h felixzh -p 6379 -x set key$i
done

通过UI工具查看集群中Key数量为10万,如下:

2.使用cluster backup备份redis1数据

代码语言:javascript复制
[root@felixzh redis7]# mkdir rdbback
[root@felixzh redis7]# redis-cli --cluster backup:6378 ./rdbback/

上述命令会触发所有master进行bgsave,并将相应rdb拷贝到当前节点指定目录,如下图所示:

3.离线迁移

将上述备份数据rdb迁移到新集群(redis2)

代码语言:javascript复制
cd RedisShake/bin
cp shake.toml shake-rdb.toml

编辑shake-rdb.toml,设置rdb_reader节点和redis_writer节点

开始rdb数据迁移

代码语言:javascript复制
./redis-shake shake-rdb.toml

由于rdb_reader节点filepath只能配置一个文件全路径,需要执行n=rdb个数次!!离线迁移完成,通过UI查看redis2集群key数量,如下:

4.在线迁移

先清空redis2集群所有数据

代码语言:javascript复制
redis-cli --cluster call felixzh:6380 flushall
cp shake.toml shake-sync.toml

编辑shake-sync.toml,设置sync_reader节点和redis_writer节点

开始在线数据迁移

代码语言:javascript复制
./redis-shake shake-sync.toml

在线数据迁移默认先同步全量数据(rdb)、再同步增量数据(aof),那么怎么判断同步数据的一致性呢?

方法1:上图日志可以观察到diff为0,表示没有数据同步了。

方法2:对比源端与目的端Key数量是否相等,如果相等,认为一致。

不过,如果Key带有过期时间,会导致Key数量不一致。原因:

因为过期算法限制,源端中可能存在一些 Key 已经过期但实际上没有被删除,这批 Key 在目的端可能会被删除,导致目的端 Key 数量少于源端。

源端和目的端独立运行,各自的过期算法独立运行,过期算法具有随机性,会导致源端和目的端删除的 Key 不一致,导致 Key 数量不一致。

在实践中,带有过期时间的 Key 一般认为是允许不一致的,不会影响业务,所以可以仅校验不带有过期时间的 Key 数量是否一致。如下所示,应当分别计算源端和目的端的 keys-expires 的值是否一样。

代码语言:javascript复制
127.0.0.1:6379> info keyspace
# Keyspace
db0:keys=4463175,expires=2,avg_ttl=333486

常用命令

1.查看集群状态

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 CLUSTER INFO

2.查看集群节点

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 CLUSTER NODES    

3.查看key所属slot

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 CLUSTER KEYSLOT 1    

4.查看所有keys

代码语言:javascript复制
redis-cli --cluster call felixzh:6378  dbsize
redis-cli --cluster call felixzh:6380 keys *       

5.查看key数据类型

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 type key90888

6.查看key过期时间(ttl:s,pttl:ms)

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 ttl key90888
redis-cli -c -h felixzh -p 6378 pttl key90888         

7.设置key过期时间(s)

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 expire key90888 60

8.取消key过期设置

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 persist key90888

9.查看key占用内存(byte)

代码语言:javascript复制
redis-cli -c -h felixzh -p 6378 memory usage key90888

10.查看集群类型命令帮助

代码语言:javascript复制
redis-cli --cluster help

11.创建集群

代码语言:javascript复制
redis-cli --cluster create ip1:7001 ip1:7002 --cluster-replicas 0

12.检查集群

代码语言:javascript复制
redis-cli --cluster check ip1:7001    

13.查看集群信息

代码语言:javascript复制
redis-cli --cluster info ip1:7001  

14.修复集群

代码语言:javascript复制
redis-cli --cluster fix ip1:7001
可选参数:
   --cluster-search-multiple-owners :是否修复多个拥有者的槽位。当集群中的槽位在迁移过程中,出现意外时,可使用该参数。一般情况下,默认即可。
   --cluster-fix-with-unreachable-masters :是否修复不可达的主节点上的槽位。例如,集群中某个主节点就是坏掉了,也没有故障转移成功。可以使用该参数修复槽位但是之前的数据会丢失,慎用!

15. 迁移槽位

代码语言:javascript复制
redis-cli --cluster  reshard  host:port
       --cluster-from                #源节点node id列表,逗号分隔或all代表所有节点
       --cluster-to                  #目的节点node id,仅支持一个
       --cluster-slots                #所有源节点迁移槽位总个数
       --cluster-yes          #默认集群内部迁移计划
       --cluster-timeout                #迁移超时时间,ms
       --cluster-pipeline               #迁移key时,批次大小,默认10
       --cluster-replace           #是否直接replace到目标节点

功能:迁移一个或多个源节点上的槽位至一个目标节点上。示例如下:

代码语言:javascript复制
redis-cli --cluster reshard felixzh:6380 --cluster-from 33359014f3ec0e634dbda6586ff43c76a5bff284,b36cb6e55905b3304b2f700987d05b985ece6fff --cluster-slots 10 --cluster-replace --cluster-to 278fd94ac15642c43484faac903d7fe9b4114292 --cluster-yes        

16.集群均衡

代码语言:javascript复制
redis-cli --cluster rebalance host:port
    --cluster-weight      
    --cluster-use-empty-masters
    --cluster-timeout                  #超时时间,ms
    --cluster-simulate      #模拟再平衡过程而不会实际执行,方便测试评估
    --cluster-pipeline                 #迁移key批次个数,默认值10
    --cluster-threshold             
    --cluster-replace          #是否直接replace到目标节点
说明:    
--cluster-weight:node id权重(浮点型),如node1=1.0,node2=1.0,node3=2.0表示总权重为4.0,node1与node2将分配到 (16384*1/4) 个槽位,node3是(16384*2/4)个槽位。
 --cluster-threshold: 平衡触发阈值条件,默认2.00%。如node1该有4096个槽位,但是现在不够且缺少个数超过 (4096*0.02 )则会触发自平衡。 

17.集群扩容

代码语言:javascript复制
redis-cli --cluster add-node newHost:newPort #待加入的节点
       host:port  #集群任意节点
       --cluster-salve #新节点为salve,默认随机master    
       --cluster-master-id             #不随机master,可以指定master

增加master:
redis-cli --cluster add-node 10.121.198.220:6381 10.121.198.220:6380
增加slave:
redis-cli --cluster add-node 10.121.198.220:6381 10.121.198.220:6380 --cluster-slave

18.集群缩容

代码语言:javascript复制
redis-cli --cluster del-node host:port  #集群任意节点 node_id  #待删除节点

注意:如果删除master,需要先使用reshard将node_id上的槽位迁移到别的master

19.集群范围命令

代码语言:javascript复制
redis-cli --cluster call host:port command arg arg .. arg   #集群所有节点执行命令集合

       --cluster-only-masters      #只master执行

       --cluster-only-replicas      #只slave执行

如:redis-cli --cluster call felixzh:6380 keys *

20.集群超时时间

代码语言:javascript复制
redis-cli --cluster set-timeout host:port  ms    

21.非集群Redis实例导入到集群

代码语言:javascript复制
redis-cli --cluster import srcIP:port --cluster-from dstIP:port --cluster-copy
The source node should not be a cluster node.
不常用,建议使用redis-shake工具。

22.集群数据备份

代码语言:javascript复制
redis-cli --cluster host:port backupPath
功能:将所有master rdb备份到当前主机的backupPath

Redis数据类型

数据类型及每种数据类型支持的命令类型,详见见官方文档:

代码语言:javascript复制
https://redis.io/docs/latest/develop/data-types/

0 人点赞