一、重要概念
1.1、redis-cluster架构图
描述:
- 所有节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
- 节点的fail是通过集群中超过半数节点检测有效时整个集群才生效。
- 客户端与redis节点直连,不需要通过poxy层;客户端不需要连接集群中所有节点,连接任意一个即可。
- redis-cluster把所有物理节点映射到[0-16383]slot上,cluster负责维护node<>slot<>value
Redis集群中内置了16384个哈希槽,当需要在redis集群中放置一个key-value时,redis使用crc16算法计算一个结果,然后结果对16384求余,这样每个key都会对应一个编号在0-16383之间的哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同节点。
1.2、redis-cluster投票:容错
心跳机制:
- 集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超时(cluster-node-timeout),认为该master节点失效。
- 整个集群不可以用状态:
(1)任意master失效且该master没有slave,则集群进入fail状态。也可以理解为集群的[0-16383]slot映 射不完全时进入fail状态。
(2)如果集群超过半数以上master失效,无论是否有slave,则集群进入fail状态。
二、搭建集群
2.1、创建集群目录
mkdir redis-cluster
搭建集群最少需要3台主机,每台主机再配置一台从机,就需要6台服务器(一般采用虚拟化)。6个redis实例端口7001-7006
2.2、复制redis目录
cp -r redis5/ redis-cluster/7001
删除持久化文件
rm -rf appendonly.aof dump.rdb
2.3、修改配置文件
支持集群
端口和IP
2.4、复制另外5台并修改端口
2.5、编写启动脚本
vi startall.sh
内容:
cd 7001
./bin/redis-server redis.conf
cd ..
cd 7002
./bin/redis-server redis.conf
cd ..
cd 7003
./bin/redis-server redis.conf
cd ..
cd 7004
./bin/redis-server redis.conf
cd ..
cd 7005
./bin/redis-server redis.conf
cd ..
cd 7006
./bin/redis-server redis.conf
cd ..
2.6、修改执行权限并执行
chmod u+x startall.sh
./startall.sh
2.7、创建集群
- 关闭防火墙
- redis版本5.0.5及以上
- 在集群中任意一台运行:
./redis-cli --cluster create ip:port ip:port --cluster-replicas 1
2.8、连接集群
./redis-cli -h 127.0.0.1 -p 7001 -c
其中 -c 是指定集群连接
查看集群
cluster info
查看集群节点
cluster nodes
三、Jedis连接集群
注意关闭服务器防火墙或者放行端口
3.1、pom依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.0.0</version>
</dependency>
3.2、连接集群
Set<HostAndPort> nodes=new HashSet<>();
nodes.add(new HostAndPort("192.168.223.128",7001));
nodes.add(new HostAndPort("192.168.223.128",7002));
nodes.add(new HostAndPort("192.168.223.128",7003));
nodes.add(new HostAndPort("192.168.223.128",7004));
nodes.add(new HostAndPort("192.168.223.128",7005));
nodes.add(new HostAndPort("192.168.223.128",7006));
JedisCluster jedisCluster=new JedisCluster(nodes);
jedisCluster.set("myKey1","王者");
String myKey1 = jedisCluster.get("myKey1");
System.out.println(myKey1);
jedisCluster.lpush("list1","小明","小张","小李");
List<String> list1 = jedisCluster.lrange("list1", 0, 3);
for (String s:list1){
System.out.println(s);
}
jedisCluster.close();
|