Redis分布式系统的特点和限制
多主多从,去中心化,从节点作为备用,复制主节点,不做读写操作,不提供服务;
支持动态扩容节点;
节点之间相互通信,相互选举,保证及时故障转移,不再依赖sentinel;
对数据进行分片(sharding),不同节点存储的数据是不一样的;
仅支持 0 号数据库;
不支持处理多个key:因为数据分散在多个节点,在数据量大高并发的情况下会影响性能;
分区仅限于 key;
事务支持有限;
不支持分级管理。
系统搭建与运行
系统搭建
Redis集群至少需要3个master节点,并且推荐master节点数为奇数。一般是3主3从6个节点。
以下示例为搭建在同一机器上的伪集群。
1. 删除持久化文件
先将之前在 Redis 安装目录下生成的 RDB 持久化文件 dump.rdb 与 AOF 持久化文件删除。因为 Redis 分布式系统要求创建在一个空的数据库之上。注意,AOF持久化文件全部在 appendonlydir 目录中。
2. 创建集群目录并复制配置文件
cd /usr/local/redis/
mkdir cluster && cp redis.conf cluster && cd cluster
3. 修改redis.conf
# 首先是修改远程连接的配置,无访问密码,任意远程主机都能通过本机IP连接
sed -i s/"bind 127.0.0.1 -::1"/"bind * -::*"/g redis.conf
sed -i s/"protected-mode yes"/"protected-mode no"/g redis.conf
# 然后需要修改的几个配置
# dir:指定工作目录为前面创建的cluster目录,持久化文件、节点配置文件将来都会在工作目录中自动生成。默认是在redis-server启动时所在目录。
dir /usr/local/redis/cluster
# cluster-enabled:该属性用于开启 Redis 的集群模式。解开注释即可。
cluster-enabled yes
# cluster-config-file:该属性用于指定“集群节点”的配置文件。该文件会在第一次节点启动时自动生成,其生成的路径是在 dir 属性指定的工作目录中。在集群节点信息发生变化后(如节点下线、故障转移等),节点会自动将集群状态信息保存到该配置文件中。不过,该属性在这里仍保持注释状态。在后面的每个节点单独的配置文件中配置它。
# cluster-node-timeout:用于指定“集群节点”间通信的超时时间阈值,单位毫秒。解开注释即可。
cluster-node-timeout 15000
4. 创建节点子配置文件
和主从集群的配置文件区别就是多了一行 cluster-config-file 属性。
vi redis6380.conf
include redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb
appendfilename "appendonly6380.aof"
replica-priority 90
logfile access6380.log
cluster-config-file nodes-6380.conf
5. 复制5个配置文件并依次修改
cp redis6380.conf redis6381.conf && cp redis6380.conf redis6382.conf && cp redis6380.conf redis6383.conf && cp redis6380.conf redis6384.conf && cp redis6380.conf redis6385.conf
sed -i s/6380/6381/g redis6381.conf && sed -i s/6380/6382/g redis6382.conf && sed -i s/6380/6383/g redis6383.conf && sed -i s/6380/6384/g redis6384.conf && sed -i s/6380/6385/g redis6385.conf
6. 启动节点
脚本启动
这里使用了脚本启动这个伪集群,如果是线上环境肯定是多机器分布式部署了。手动执行也是一样的。
vi cluster_redis.sh
#!/bin/bash
case $1 in
start)
rm -rf dump638*.rdb
rm -rf appendonlydir
rm -rf nodes-638*.conf
redis-server redis6380.conf
redis-server redis6381.conf
redis-server redis6382.conf
redis-server redis6383.conf
redis-server redis6384.conf
redis-server redis6385.conf
redis-cli --cluster create --cluster-replicas 1 192.168.52.130:6380 192.168.52.130:6381 192.168.52.130:6382 192.168.52.130:6383 192.168.52.130:6384 192.168.52.130:6385
;;
stop)
redis-cli -p 6380 shutdown
redis-cli -p 6381 shutdown
redis-cli -p 6382 shutdown
redis-cli -p 6383 shutdown
redis-cli -p 6384 shutdown
redis-cli -p 6385 shutdown
ps aux|grep redis|grep -v grep|grep -v cluster_redis.sh
if [ $? -eq 0 ];then
echo "请检查redis进程!"
else
echo "redis集群已停止。"
fi
;;
*)
echo "参数有误!请输入 start or stop 。"
;;
esac
脚本的内容很简单,启动就是删除掉dump.rdb和aof以及nodes文件,重新创建集群。停止就是挨个执行shutdown命令。
创建集群的命令解析
- --cluster create:用于将指定的 6 个节点连接为一个分布式系统。
- --cluster replicas 1:指定每个 master 会带有一个 slave 作为副本,这样意味着6个节点是3主3从。
- 后面的IP端口则是填写所有节点的,前3个为主节点,后3个为从节点,master 与 slave 的配对关系,在系统搭建成功后会自动分配。
启动
根据提示可以看到设置的前3个节点为master,后3个节点为slave,输入 yes 确认,系统就会将以上显示的动态配置信息真正的应用到节点上。
7. 连接集群
与之前单机连接相比的唯一区别就是增加了参数 -c ,指定任意节点皆可连接集群。
redis-cli -c -p 6381
通过 cluster nodes 命令可以查看到系统中各节点的关系及连接情况。
redis-cli -c -p 6381 cluster nodes
只要能看到每个节点给出 connected,就说明分布式系统已经成功搭建。
但是以上信息不能看出主从的对应关系,要查看对应关系只能上每个节点使用 info replication 命令了。
8. 故障测试
执行 redis-cli -p 6381 info replication 可以看到6381这个master节点的slave节点是6385。
将 6381 关闭,redis-cli -p 6381 shutdown
6385已晋升为 master,当6381节点恢复上线后,会自动转为 slave节点。
9. 全覆盖需求
如果某 slot 范围对应节点的 master 与 slave 全部宕机,那么整个分布式系统是否还可以对外提供读服务,就取决于 redis.conf 文件中属性 cluster-require-full-coverage 的设置。
该属性有两种取值:
- yes:默认值。要求所有 slot 节点必须全覆盖的情况下系统才能运行。
- no:slot 节点不全的情况下系统也可以提供查询服务。
10. 集群的重启
如果是已经上线的集群,逐个redis-cli shutdown 再逐个 redis-server redis638*.conf 启动即可,不要像上面示例中的脚本一样,删除了数据文件,这样只能重建集群了。
注意点:
- appendfilename和dbfilename参数,每个节点文件名需唯一,这个已经在子配置文件中配置过了,不然会出现不同节点之间数据文件覆盖导致数据丢失问题,因为节点之间的数据是不同的。
- redis.conf中的dir参数需要配置,因为默认RDB文件和AOF文件会在执行redis-server启动命令的路径下创建,否则每次启动时所在目录不一致,无法正确加载持久化文件。
redis-cluster相关的集群命令
- cluster info :打印集群的信息
- cluster nodes :列出集群当前已知的所有节点( node),以及这些节点的相关信息。
- cluster meet
:将 ip 和 port 所指定的节点添加到集群当中。 - cluster forget <node_id> :从集群中移除 node_id 指定的节点。
- cluster replicate <master_node_id> :将当前从节点设置为 node_id 指定的master节点的slave节点。只能针对slave节点操作。
- cluster saveconfig :将节点的配置文件保存到硬盘里面。
- cluster addslots
[slot ...] :将一个或多个槽( slot)指派( assign)给当前节点。 - cluster delslots
[slot ...] :移除一个或多个槽对当前节点的指派。 - cluster flushslots :移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
- cluster setslot
node <node_id> :将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给 - cluster setslot
migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中。 - cluster setslot
importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点。 - cluster setslot
stable :取消对槽 slot 的导入( import)或者迁移( migrate)。 - cluster keyslot
:计算键 key 应该被放置在哪个槽上。 - cluster countkeysinslot
:返回槽 slot 目前包含的键值对数量。 - cluster getkeysinslot
:返回 count 个 slot 槽中的键 。