078:RedisCluster扩容与缩容&Jedis支持集群原理
- 1 快速回顾搭建RedisCluster集群
- 2 RedisCluster快速实现扩容原理
- 3 搭建RedisCluster集群
- 4 RedisCluster快速的实现卡槽扩容
- 5 master节点宕机之后重新实现选举
- 6 RedisCluster快速的实现缩容
- 7 JedisCluster支持集群原理
1 快速回顾搭建RedisCluster集群
课程内容:
- RedisCluster高可用实现原理
- RedisCluster如何实现卡槽扩容
- RedisCluster如何实现卡槽缩容
- Jedis如何连接RedisCluster
分配hash命令
/usr/redis/bin/redis-cli --cluster create 192.168.206.103:7000 192.168.206.103:7001 192.168.206.103:7002 192.168.206.103:7003 192.168.206.103:7004 192.168.206.103:7005 --cluster-replicas 1
表示主和从为1:1的关系,前3台为主节点,后3台为从节点,16384/3每个节点卡槽均摊(建议最好使用服务器的ip地址搭建,否则重定向也是定向到127.0.0.1)
集群连接redisCluster:
/usr/redis/bin/redis-cli -h 127.0.0.1 -p 7000 -c
2 RedisCluster快速实现扩容原理
新增主的节点,可能需要重新分配卡槽
如果有3台主节点,每台节点16384/3=5461个卡槽;
新增一台主节点,有4台主节点,每台节点16384/4=4096个(手动计算)卡槽。
原3台节点每个节点分配4096/3个卡槽(带数据)到新节点。做卡槽迁移,如果卡槽有数据的情况下,会带着数据一起迁移到新的节点。
3 搭建RedisCluster集群
RedisCluster集群模式扩容节点
新增一个主节点 为7006 (7006连7000自动加入集群)
/usr/redis/bin/redis-cli --cluster add-node 新增集群地址:端口 集群中已经存在的任意一台连接地址:端口
/usr/redis/bin/redis-server /usr/rediscluster/redis7006/redis.conf
/usr/redis/bin/redis-cli --cluster add-node 192.168.206.103:7006 192.168.206.103:7000 (默认加入成为master节点)
新增一个从节点 为7007
/usr/redis/bin/redis-server /usr/rediscluster/redis7007/redis.conf
/usr/redis/bin/redis-cli --cluster add-node 192.168.206.103:7007 192.168.206.103:7000 --cluster-salve --cluster-master-id 2e70b808eb8c1bb2a440c46cc79a30e081c5e98b
以上文档代码运行报错(可能是redis版本不一致)
采用另一种方式新增从节点7007
/usr/redis/bin/redis-server /usr/rediscluster/redis7007/redis.conf
/usr/redis/bin/redis-cli --cluster add-node 192.168.206.103:7007 192.168.206.103:7000
/usr/redis/bin/redis-cli -h 192.168.206.103 -p 7007 (登录7007节点)
##使用cluster replicate <master_id>命令为主节点添加从节点,集群模式下不支持slaveof命令。
cluster replicate 2e70b808eb8c1bb2a440c46cc79a30e081c5e98b (主节点的ID,这里是7006)
ps:如果报错可以尝试修改redis.conf中配置dbfilename dump.rdb->dbfilename 7001dump.rdb,伪集群环境rdb文件重复可能造成冲突;或者清除rdb文件
4 RedisCluster快速的实现卡槽扩容
如何分配卡槽节点
/usr/redis/bin/redis-cli --cluster reshard 192.168.206.103:7000
你需要分配多少卡槽?4096
接收的id为多少?7006的id
两种形式分配:all 全部均摊分配;done 按照能力分
卡槽重新分配以后
5 master节点宕机之后重新实现选举
7006节点宕机,7007节点变为主节点;7006节点重新启动,自动变为7007的从节点
6 RedisCluster快速的实现缩容
Redis槽位缩容
假设7006节点和7007节点不要了,还原卡槽到当前正在运行的节点。
/usr/redis/bin/redis-cli –cluster reshard 192.168.206.103:7000 --cluster-from 需要缩容的卡槽节点 --cluster-to 接收卡槽的节点 --cluster-slots 卡槽容量
/usr/redis/bin/redis-cli --cluster reshard 192.168.206.103:7000 --cluster-from 5061a25001b5ffc12f1cd66e6023706672f1a8e7 --cluster-to 585e3e8fe06c58f5531614a5ebc9c606d8b547a4 --cluster-slots 4096
7 JedisCluster支持集群原理
引入maven依赖
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
Jedis单机版本
public class Test001 {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.206.103", 7002);
String value = jedis.get("mm");
System.out.println("value:" + value);
jedis.close();
}
}
运行结果:
Jedis支持集群版本
public class RedisCluster {
private static JedisCluster jedis;
static {
// 添加集群的服务节点set集合
HashSet<HostAndPort> hostAndPorts = new HashSet<>();
// 添加节点 只要添加一个节点,客户端就会自动重定向
hostAndPorts.add(new HostAndPort("192.168.206.103", 7005));
// Jedis连接池配置
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲连接数,默认8个
jedisPoolConfig.setMaxIdle(100);
// 最大连接数,默认8个
jedisPoolConfig.setMaxTotal(500);
// 最小空闲连接数,默认0个
jedisPoolConfig.setMinIdle(0);
// 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时抛出异常
jedisPoolConfig.setMaxWaitMillis(2000);
// 对拿到的connection进行validateObject校验
jedisPoolConfig.setTestOnBorrow(true);
jedis = new JedisCluster(hostAndPorts, jedisPoolConfig);
}
public String getKey(String key) {
return jedis.get(key);
}
public static void main(String[] args) {
String value = new RedisCluster().getKey("mm");
System.out.println("value:" + value); //value:mm
}
}
JedisCluster底层支持集群原理:
首先连接集群节点,先crc16计算key对应的卡槽(cluster KEYSLOT),再cluster nodes查找节点卡槽分配,找到对应的节点重定向后查询。