为什么使用集群?就算使用“主从复制+哨兵”,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。为了最大化利用内存,可以采用集群,就是分布式存储。集群内的redis节点分量存储,各自承担一部分数据。这是集群与主从+哨兵最显著的区别!
redis-cluster集群模式需要redis 3.0以上版本支持,由多个Redis服务器组成的分布式网络服务集群。每一个Redis服务器称为节点Node,节点之间会相互通信,两两相连。redis-cluster集群采用无中心结构,无中心节点,每个节点有两种角色可选:主节点master node、从节点slave node,其中主节点用于存储数据,从节点是某个主节点的复制品。当需要处理更多的读请求时,可以添加从节点,例如7000主节点可以添加7006从节点、7007从节点,以扩展系统的读性能。这一点跟主从复制道理是一样的,从节点会同步主节点的数据
(注意:上图只是解释,redis-cluster至少需要3个主节点)
redis-cluster集群的主节点内置了类似redis-sentinel的节点故障检测和自动故障转移功能,当集群中的某个主节点下线时,集群中的其它在线主节点会监测到,并对已下线的主节点进行故障转移。集群进行故障转移的方法和Redis-Sentinel进行故障转移的方法基本一样,不同的是,在集群里面,故障转移是由集群中其它在线的主节点负责进行的,因此集群不需要额外使用Sentinel。
redis-cluster集群将整个数据库分为16384个分片solt,所有Key都可以匹配这些slot中的一个,key的分片计算公式:slot_num=crc16(key)%16384,其中crc16为16位的循环冗余校验和函数。集群中的每个主节点都可以处理0~16383个分片,但是集群中一般是所有主节点平均分担16384个分片,当16384个分片都有节点在负责处理时,集群就可以工作了!
例如:
(所以redis-cluster集群一般会搭建奇数个主节点)
redis-cluster集群无中心节点,每个节点都可以接受请求并且具备一定的路由能力。当客户端访问的key不在对应Redis节点的slot中,Redis返回给Client一个moved命令,告知其正确的路由信息,然后客户端根据路由信息包含的地址和端口重新向真正负责的节点发起请求:
在redis.conf中配置集群参数:
①cluster-enabled
集群模式;若为no,则以单机模式启动redis服务
②cluster-config-file
而是Redis集群节点每次发生更改时自动保留集群配置(基本上为状态)的
文件,以便能够在启动时重新读取它。该文件列出了群集中其它节点,它们的
状态,持久变量等等。在节点收到一些消息后此文件就会被重写。
③cluster-node-timeout
若集群内某个节点的响应时间超过最大值,则被判定为不可达(已宕机);
若此节点为master节点,则它的slave节点会取代它成为新的master节点。
此配置十分重要,集群中的很多配置依赖于超时配置。
④cluster-slave-validity-factor
否有资格在master宕机后选举新的master节点。主要是为了防止短线后
slave节点与master节点太久未通信,导致数据不一致,则该slave节点就
不应该取代master成为新的master节点。如果设置为0,则表示不介意这
个断线时间的长短,slave节点都会尝试故障转移成为新的master节点;如
果设置为一个正数(大于0),则会和超时时间cluster-node-timeout相乘,
乘积作为评判标准。例如设置为5,超时时间设置为10s,则与master节点
断开连接超过50s的slave节点不会进行故障转移,选举成为新的master
节点。注意,此选项有风险:任何非0值的设置,都可能导致master节点出
现故障后,它的slave节点又没有资格故障转移选举为新的master节点,整
个集群一直处于不可用状态。在这种情况下,只有原始master节点重新加入
集群时,集群才可以正常使用。
⑤cluster-migration-barrier
有的slave节点数。一个master只有它的slave节点数达到该参数设置的
值,在它宕机后,它的slave节点才会进行故障转移选举成为新的master。
例如:此参数设为2,那么只有当一个master节点拥有2个可工作的slave
节点时,在它宕机后,它的一个slave节点才会尝试故障迁移。
⑥cluster-require-full-coverage
分片slot没有被master节点完全分配完,如果此选项设置为yes,则集群
不可用,拒绝提供服务;如果此选项设置为no,集群可用,继续提供服务。
环境要求:
①redis-cluster至少需要3个主节点,因为投票容错机制要求超过半数主节点认为某个主节点挂了,该主节点才算挂了,所以2个主节点无法构成集群
②集群是为了保障高可用,所以每个主节点必须要有一个从节点,所以搭建集群至少需要6个节点,其中3个为主节点,3个为从节点
③redis-cluster集群分片需要ruby脚本支持,所以需要安装ruby环境
因为是在单机,所以只能创建6个文件夹,每个文件夹表示一个redis服务再创建一个文件夹,用于保存redis的脚本文件(直接拷贝之前安装好的redis的bin目录即可)
每个文件夹代表对应的redis服务端口,例如9001代表redis的服务端口是9001。每个文件夹里面,创建一个redis.conf配置文件,文件内容至少为:
cluster-enabled yes ##表示开启集群
port 900x ##对应每个redis服务的端口
对于集群信息的额外配置可用查看集群配置参数。在所有文件的redis.conf配置完以后,启动这6个redis服务:
通过命令ss -tanl | grep 900,如下图所示:
900x是提供给客户端的端口
900x+10000后的端口是集群内各节点通信的端口
集群中的槽位分配需要通过redis-trib执行ruby写的脚本来完成,首先需要准备ruby环境,执行下面两个命令:
yum install ruby rubygems –y(在线安装ruby环境和ruby包安装工具)
gem install redis (这是安装ruby连接redis的工具包,也可以直接到rubygems官网下载 :http://rubygems.org/gems/redis)
安装好ruby环境就可以使用redis自带的ruby脚本执行:redis-trib.rb。这个脚本在redis源码包的src目录下:
通过该脚本执行命令:
./redis-trib.rb create --replicas 1 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005 127.0.0.1:9006
(IP改为服务器所在IP,因为我是在本机,所以用的是127.0.0.1)
如果搭建成功,可以看到如下的信息输出:
①连接到集群中:redis-cli -p 9002 -c
端口号随便写,集群无中心节点,连接哪个节点都行,参数-c表示连接集群模式,一定要写。当我们连接到从节点,或者该主节点负责的槽位不匹配时:
②测试集群中主节点宕机
从上面的配置知道:主9001-从9004,主9002-从9005,主9003-从9006。当我们把主节点9001停掉以后,从节点9004会变成新的主节点:(当节点9001宕机重启后,会变成9004节点的从节点)
但是,如果把9004节点也停掉,那没辙了,集群会因为slot槽位没有分配完而停止工作:
redis-trib.rb是redis官方推出的管理redis集群的工具,集成在redis的源码src目录下,是基于redis提供的集群命令封装成简单、便捷、实用的操作工具。redis-trib.rb是redis作者用ruby完成的,只用了1600行左右的代码,就实现了强大的集群操作。在使用redis-trib.rb,使用help命令可以告诉我们使用方式和命令参数,大部分命令的参数都需要用host:port参数,指定集群内的某一节点,redis-trib.rb从该节点来获取集群的信息。使用redis-trib.rb的语法为:
redis-trib
①创建集群命令-create
先使用help命令查看如何使用create命令:
create命令有可选replicas参数, replicas表示需要有几个slave
因为redis cluster默认是至少需要3个主节点,所以
当replicas=1,说明每个主节点需要1个从节点,所以总共需要6个节点;
当replicas=2,说明每个主节点需要2个从节点,所以总共需要9个节点;
②查看集群信息命令-info
先使用help命令查看如何使用info命令
说明只需要指定集群内的一个节点即可,如下:
③关闭集群,使用call命令
先使用help命令查看如何使用call命令
所以可以使用下面的命令去关闭集群内的所有节点
④集群重启就有点蛋疼了,试了cluster命令和redis-trib.rb工具都出错了,暂时没解决。只能把原先节点的dumb.rdb和nodes.conf删掉后重启节点。
连接上去redis节点,进入命令行窗口
命令 |
作用 |
cluster info |
打印集群的信息 |
cluster nodes |
打印集群内的所有节点信息(包括ip、port和主从关系) |
cluster meet |
将ip和port指定的节点添加当前集群当中 |
cluster forget |
从集群中移除node_id指定的节点 |
cluster replicate |
将当前从节点设置为master_id指定的主节点的从节点。只能针对从节点操作 |
cluster saveconfig |
将节点的配置文件保存到硬盘里面 |
cluster addslots |
将一个或多个槽(slot)指派给当前节点 |
cluster delslots |
移除已指派给当前节点的一个或多个槽(slot) |
cluster flushslots |
移除已指派给当前节点的所有slot,使其成为一个没有指派任何slot的节点 |
cluster setslot |
将solt指派给node_id指定的节点,若槽已经指派给另一个节点,会先让另一个节点删除该槽再进行指派 |
cluster setslot migrating |
将本节点的槽slot迁移到node_id指定的节点中 |
cluster setslot importing |
从node_id指定的节点中导入槽slot到本节点 |
cluster setslot |
取消对槽slot的导入(import)或迁移(migrate) |
cluster keyslot |
计算键key应该被放置在哪个槽上 |
cluster countkeysinslot |
返回槽slot目前包含的键值对数量 |
cluster getkeysinslot |
返回count个slot槽中的键 |