1、概述
- redis是一个开源的key value存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群,我这里用的是redis3.0.0版本;
- redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;
- redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;
- 为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;
- 那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;
- 那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。
- 综上所述,每个Redis集群理论上最多可以有16384个节点。
- Redis 集群(包括很多小集群)实现了对 Redis 的水平扩容,即启动 N 个 redis 节点,将整个数据库分布存储在这 N 个节点中,每个节点存储总数据的 1/N,即一个小集群存储 1/N 的数据,每个小集群里面维护好自己的 1/N 的数据。
- Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
- 该模式的 redis 集群特点是:分治、分片。
- Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
2、搭建集群环境
- Redis集群至少需要3个节点,因为投票容错机制要求超过半数节点认为某个节点挂了该节点才是挂了,所以2个节点无法构成集群。
- 要保证集群的高可用,需要每个节点都有从节点,也就是备份节点,所以Redis集群至少需要6台服务器
3、搭建集群流程
模拟创建的集群包括6个节点,端口分别是6380-6385。
1)创建myredsi文件夹,将redis配置文件复制进去;
2)创建redis6380.conf文件,文件内容如下:
include redis.conf pidfile /var/run/redis_6380.pid port 6380 dbfilename dump6380.rdb # dir /root/myredis/redis_cluster -- 这行注释掉了 不影响启动服务的情况下可以添加上** # logfile /root/myredis/redis_cluster/redis_err_6380.log --这行暂时注释 日志文件路径放对即可** cluster-enabled yes #打开集群模式 cluster-config-file nodes-6380.conf #设置当前节点集群的配置文件名称 cluster-node-timeout 15000 #设置节点失联时间,超过该时间,集群自动进行主从切换
3)复制5份redis6380.conf,将端口号改为6381-6385;
4)启动6个redis服务;
../redis-6.2.0/src/redis-server ./redis6380.conf ../redis-6.2.0/src/redis-server ./redis6381.conf ../redis-6.2.0/src/redis-server ./redis6382.conf ../redis-6.2.0/src/redis-server ./redis6383.conf ../redis-6.2.0/src/redis-server ./redis6384.conf ../redis-6.2.0/src/redis-server ./redis6385.conf
5)创建集群,--cluster-replicas 1表示每个master节点都有一个slave;
../redis-6.2.0/src/redis-cli --cluster create --cluster-replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 -a 236300
6)连接集群中的某个节点,-c表示集群;
../redis-6.2.0/src/redis-cli -c -p 6380
7)使用命令cluster nodes查看集群信息;
4、在集群中读写值
- 在 redis-cli 每次录入、查询键值,redis 都会计算出该 key 应该送往的插槽,如果不是该客户端对应服务器的插槽,redis 会报错,并告知应前往的 redis 实例地址和端口。
- redis-cli 客户端提供了 –c 参数实现自动重定向。如 redis-cli -c –p 6379 登入后,再录入、查询键值对可以自动重定向。不在一个 slot 下的键值,是不能使用 mget,mset 等多键操作。
5、相关操作
参考:(29条消息) Redis Cluster集群操作_if 0 = -I can的博客-CSDN博客
6、故障恢复
- 如果主节点下线?从节点能否自动升为主节点?注意:15 秒超时
- 主节点恢复后,主从关系会如何?主节点回来变成从机。
- 如果所有某一段插槽的主从节点都宕掉,redis 服务是否还能继续?
- 如果某一段插槽的主从都挂掉,而 cluster-require-full-coverage 为 yes ,那么整个集群都挂掉。
- 如果某一段插槽的主从都挂掉,而 cluster-require-full-coverage 为 no ,那么,该插槽数据全都不能使用,也无法存储。
参考:Redis | ZC 的学习录 (zhangc233.github.io)
参考:Redis集群的原理和搭建,一文带你详解 - 知乎 (zhihu.com)
参考:(29条消息) Redis简单集群搭建及(error)NOAUTH Authentication required等问题的解决方法_aloneno的博客-CSDN博客