知识问答:
传统的哨兵集群方式存在哪些缺陷?
1.redis的哨兵集群方式,每个节点都保存相同的同步数据,可能会存在冗余的数据;其次只能允许有一个主的节点;属于中心化集群;
Redis Cluster 从3.0开始是Redis官方推出一种去中心化的集群方式.
采用hash槽分片的将数据存放到多个不同的Redis中,从而可以去减少冗余的数据.
核心原理:采用hash槽,预先分配16384个卡槽,并且将卡槽分配到具体Redis的节点,通过key进行crc16(key)%16384=卡槽,可以根据卡槽存到具体Redis节点,注意一个卡槽可以存放多个不同的key.只有主的节点才会分配卡槽,从节点没有卡槽.
卡槽作用: 决定key存放具体的服务器位置,从而实现均摊存放数据.类似我们的数据库中具体的分表, 优点:动态实现扩容和缩容;
搭建RedisCluster集群
1.liunx下安装好redis
2.在usr文件下创建rediscluster文件夹,并配置6个redis.conf文件
3.修改配置redis.conf文件下面几点,分别是7000 7001 7002 7003 7004 7005
4.配置好配置文件后,依次启动6台redis
5.使用命令搭建rediscluster集群,分配卡槽命令: /usr/redis/bin/redis-cli --cluster create 192.168.0.106:7000 192.168.0.106:7001 192.168.0.106:7002 192.168.0.106:7003 192.168.0.106:7004 192.168.0.106:7005 --cluster-replicas 1
6.确认完成卡槽分配,集群搭建
7.连接到redis 7000端口 /usr/redis/bin/redis-cli -h 192.168.0.106 -p 7000
8.使用-c集群连接模式
9.帮助命令
扩容
1.添加7006 . 7007两个redis
2.启动7006 .7007两个节点
3.连接7000节点 ,查看节点信息
4.使用命令将7006节点加入到rediscluster集群
/usr/redis/bin/redis-cli --cluster add-node 192.168.0.106:7006 192.168.0.106:7000
5.查看节点信息,发现7006已经加入到集群,且为主节点.但是没有分配卡槽
6.使用命令将7007节点加入rediscluster集群 ,并从于7006主节点
/usr/redis/bin/redis-cli --cluster add-node 192.168.0.106:7007 192.168.0.106:7000 --cluster-slave --cluster-master-id 447889fb4caaeec881eca8331a4c3caf4220ae49
7.加入成功后开始分配卡槽
/usr/redis/bin/redis-cli --cluster reshard 192.168.0.107:7000
8.继续分配卡槽操作
9.分配成功后查询节点信息 ,分配成功
缩容
1.先查看节点信息,使用命令将7006节点卡槽分配给7000节点
/usr/redis/bin/redis-cli --cluster reshard 192.168.0.107:7000 --cluster-from d91287701e9b0103f9f561a19f2d1d62fcc1b9c0 --cluster-to b6075e00fa0f7cefe0a9ec4d0abbbc2391050221 --cluster-slots 4096
2.查看缩容后的节点信息
jedis连接RedisCluster集群
原理:根据cluster help命令查询key所在卡槽的位置值 . 再根据命令 cluster nodes查询节点信息, key在哪个节点,然后连接节点,查询返回数据
@Component
public class RedisCluster {
private static JedisCluster jedis;
static {
Set<HostAndPort> hostAndPortSet=new HashSet<>();
hostAndPortSet.add(new HostAndPort("192.168.0.107",7000));
hostAndPortSet.add(new HostAndPort("192.168.0.107",7001));
hostAndPortSet.add(new HostAndPort("192.168.0.107",7002));
hostAndPortSet.add(new HostAndPort("192.168.0.107",7003));
hostAndPortSet.add(new HostAndPort("192.168.0.107",7004));
hostAndPortSet.add(new HostAndPort("192.168.0.107",7005));
//jedis连接池配置
JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
//最大空闲连接数 ,默认8个
jedisPoolConfig.setMaxIdle(100);
//最大连接数 ,默认8个
jedisPoolConfig.setMaxTotal(500);
//最小空闲连接数
jedisPoolConfig.setMinIdle(0);
//获取连接最大等待毫秒数
jedisPoolConfig.setMaxWaitMillis(2000);
//对拿到的connection进行validateObject效验
jedisPoolConfig.setTestOnBorrow(true);
jedis=new JedisCluster(hostAndPortSet,jedisPoolConfig);
}
//根据key获取value
public static String getKey(String key){
return jedis.get(key);
}
}