1. 简介
上一篇文章我们介绍了集群的基本概念,以及如何搭建一个简单的Redis集群。Redis(二十九)- Redis集群的介绍以及搭建,这篇文章我们接着来学习Redis集群。
2. 基本的原理概念
1. redis cluster 如何分配这六个节点
一个集群至少要有三个主节点。
选项 --cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。
这是为了尽量减少发生故障的风险,想象一下,如果主库和从库在同一个IP地址上,当这个服务器宕机之后,岂不是主库和从库都宕机了。
2. 什么是slots
在集群的启动日志中,我们可以看到All 16384 slots convered 这句日志。
一个Redis集群包含16384个插槽(hash slots),数据库中的每个键都属于这16384个插槽的其中一个。插槽可以理解为是每个内存区域,数据库将内存区域分为16384块。
集群使用公司 CRC16(key)%16384 来计算键key属于哪个槽,其中CRC16(key) 语句用于计算键key的CRC16校验和。
集群中每个主节点负责处理其中一部分插槽,在上图中我们可以看出,
节点6379 负责处理 0号至5460号插槽
节点6380 负责处理 5461号至10922号插槽
节点6381负责处理 10923号至16383号插槽。
简单来说,Redis集群在存储键值对时,首先会计算key的插槽值,然后,就将值有该插槽值的节点中。
3. 集群操作
向集群中插入单键值对,如果计算的插槽值不在当前的主节点上时,集群会切换到有该插槽值的主节点上。
不在一个slot下的键值对,是不能使用 mget,mset等多键操作。可以通过{} 来定义组的概念,从而使key中{}内相同内容的键值对放在一个slot中。
查询某个键所在的插槽值
获取某个插槽值上的键值
统计某个插槽上的键值数量,这里之所以统计不到是由于4847插槽值在6379主节点上。
4. 故障恢复
如果主节点下线,从节点可以自动升为主节点,超时的时间是15秒,这里将主节点6379下线之后,查看集群状态可以发现从节点6391自动升为了主节点。
原来的主节点恢复后,原主节点会变成从节点。这里重新启动节点6379可以发现,其变成了6391的从节点。
如果所有某一段插槽的主从节点都宕掉了,redis服务是否还能继续?
如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为yes,那么,整个集群都挂掉。
如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为no, 那么,该插槽的数据全部不能使用,也无法存储。
在redis.conf中的参数 cluster-require-full-coverage
5. 集群的Jedis开发
即使连接的不是主机,集群也会自动切换主机存储,主机写,从机读。
无中心化主从集群。无论从哪台主机写的数据,其他主机都能读到数据。
public class RedisClusterDemo { public static void main(String[] args) { // 创建对象 HostAndPort hostAndPort = new HostAndPort("192.168.122.1", 6379); JedisCluster jedisCluster = new JedisCluster(hostAndPort); // 进行操作 jedisCluster.set("name", "张三"); String nameValue = jedisCluster.get("name"); System.out.println(nameValue); jedisCluster.close(); } }
6. redis集群的优缺点
6.1. 优点
实现扩容,可以水平添加主机,实现扩容
分摊压力,将单主机的压力分摊到多主机上
无中心配置相对简单。
6.2. 缺点
不支持多键操作
多键的Redis事务是不被支持的,lua脚本也不支持
总结
本文详细介绍Redis集群操作和故障恢复&集群的Jedis开发