概述
截至目前本人接触到的最大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/