Redis 集群
问题
1、容量不够,redis如何进行扩容 ?
2、并发写操作, redis如何分摊 ?
3、另外,主从模式,薪火相传模式,主机宕机,导致ip地址发生变化,应用程序中配置需要修改对应的主机地址、端口等信息。
4、之前通过代理主机来解决,但是在 redis3.0 中提供了解决方案。就是无中心化集群配置。
什么是集群 ?
Redis 集群(包括很多小集群)实现了对 Redis 的水平扩容,即启动 N 个 redis 节点,将整个数据库分布存储在这 N 个节点中,每个节点存储总数据的 1/N,即一个小集群存储 1/N 的数据,每个小集群里面维护好自己的 1/N 的数据。
Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
该模式的 redis 集群特点是:分治、分片。
集群的搭建
搭建结果:制作6个实例,6379,6380,6381,6389,6390,6391 上下对应主从
- 删除文件夹中的全部持久化文件rdb或者aof
- 新建六个配置文件,内容如下:(除了端口号不一样,其他都一样)
include /myredis/redis.conf
pidfile "/var/run/redis_6379.pid"
port 6379
dbfilename "dump6379.rdb"
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
cluster-enabled yes
打开集群模式cluster-config-file nodes-6379.conf
设定节点配置文件名cluster-node-timeout 15000
设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。
启动6个服务
- 首先进入redis安装目录的环境,然后进入里面的src目录下
- 在src目录下执行
redis-cli --cluster create --cluster-replicas 1 10.0.8.14:6379 10.0.8.14:6380 10.0.8.14:6381 10.0.8.14:6389 43.138.131.175:6390 10.0.8.14:6391
- 从中可以看出,79是主机,81是其对应的从机;90是主机,89是其对应的从机;80是主机,91是其对应的从机。
查看是否集成成功
# 连接Redis
redis-cli -c -p 6379
# 查看集群信息
cluster nodes
集群操作
- 查看集群信息
cluster nodes
redis cluster 如何分配这六个节点呢 ?
- 一个集群至少要有**
三个主节点
**。 - 选项 --cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
- 分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。
什么是 slots ?
在运行集成集群命令后,会出现 “[OK] All 16384 slots covered
”
说明:一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个, 集群使用公式 CRC16(key) % 16384
来计算键 key 属于哪个槽,其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
集群中的每个节点负责处理一部分插槽。 举个例子, 如果一个集群可以有主节点, 其中:
节点 A 负责处理 0 号至 5460 号插槽。
节点 B 负责处理 5461 号至 10922 号插槽。
节点 C 负责处理 10923 号至 16383 号插槽。
插槽的作用 ?
- 在集群中录入值
- 注意:在用mset 同时设置多个值的时候,需要把这些key放到同一个组中,不然会报错。可以通过{ }来定义组的概念,从而使key中{ }内相同内容的键值对放到一个 slot 中去
查询集群中的值
cluster keyslot k1 # 查询k1的插槽值
# 查看指定插槽中的key数量,注意只能在插槽值所在的主机上能成功
# 例如:12706插槽在6381端口的主机上,但是在其他端口则查询失败
cluster countkeysinslot 12706
# 返回指定插槽的指定数量的key
cluster getkeysinslot 5474 2
故障恢复
如果主节点下线?从节点能否自动升为主节点?注意:15秒超时
- 6390宕机后,其从机6389自动升为主机
主节点恢复后,主从关系会如何?主节点回来变成从机。
- 原主机6390恢复后,自动变成从机
如果所有某一段插槽的主从节点都宕掉,redis服务是否还能继续 ?
- 如果某一段插槽的主从都挂掉,而
cluster-require-full-coverage
为 yes ,那么 ,整个集群都挂掉。 - 如果某一段插槽的主从都挂掉,而
cluster-require-full-coverage
为no ,那么,该插槽数据全都不能使用,也无法存储;而其他插槽是可以使用的。 - redis.conf 中的参数
cluster-require-full-coverage
集群的 Jedis 开发
- 即使连接的不是主机,集群会自动切换主机存储。主机写,从机读。
- 无中心化主从集群。无论从哪台主机写的数据,其他主机上都能读到数据。
/**
* 演示redis集群操作
*/
public class RedisClusterDemo {
public static void main(String[] args) {
// 创建对象
HostAndPort hostAndPort = new HostAndPort("10.0.8.14", 6379);
JedisCluster jedisCluster = new JedisCluster(hostAndPort);
// 进行操作
jedisCluster.set("k5", "v5");
String k5 = jedisCluster.get("k5");
System.out.println("k5 = " + k5);
jedisCluster.close();
}
}
Redis 集群的好处与不足
优点
- 实现扩容
- 分摊压力
- 无中心配置相对简单
缺点
- 多键操作是不被支持的。
- 多键的 Redis 事务是不被支持的,lua 脚本不被支持。
- 由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至 redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。