一、Redis集群实现
1.1 为什么要用集群?
Redis分片:
功能特点:实现了redis内存数据的扩容.
缺点:如果某台redis节点宕机,则整个redis分片将不能运行.没有实现高可用的效果
Redis哨兵机制:
功能:实现了redis高可用机制
缺点:无法实现数据的扩容并且哨兵本身没有实现高可用
Redis集群:
Redis集群设计时主机实现分片的功能,每台主机之后都有对应的从机.并且在内部实现高可用(不需要依赖第三方监控)
1.2 Redis集群
采用redis集群:
可以保证数据分散存储,同时保证数据存储的一致性
并且在内部实现高可用的机制,
实现了服务故障的自动迁移
1.3 集群搭建
1.3.1 集群搭建计划
3主3从 , 集群(哨兵)正常工作的条件: 存活的服务器数量 > 总数N/2
1.3.2 准备集群文件夹
mkdir cluster
1.3.3 复制配置文件
将redis根目录中的redis.conf文件复制到cluster/7000/ 并以原名保存
cp redis.conf cluster/7000/
1.3.4 编辑配置文件
vim redis.conf
- 注释本地绑定IP地址 :
#bind 127.0.0.1
69行
- 关闭保护模式 :
protected-mode no
88行
- 修改端口号 :
port 7000
92行
- 后台启动 :
daemonize yes
136行
- 修改pid文件 :
pidfile /usr/local/src/redis/cluster/7000/redis.pid
158行
- 修改持久化文件路径 :
dir /usr/local/src/redis/cluster/7000
263行
- 设定内存优化策略 :
maxmemory-policy volatile-lru
597行
- 关闭AOF模式 :
appendonly no
699行
- 开启集群配置 :
cluster-enabled yes
838行
- 开启集群配置文件 :
cluster-config-file nodes.conf
846行
- 修改集群超时时间 :
cluster-node-timeout 15000
852行
1.3.5 复制修改后的配置文件
将7000文件夹下的redis.conf文件分别复制到7001-7005中
1.3.6 批量修改
分别将7001-7005文件中的7000改为对应的端口号的名称
:%s/7000/7001/g
1.3.7 通过脚本编辑启动/关闭指令
1.创建启动脚本 :
vim start.sh
#!/bin/sh
redis-server 7000/redis.conf &
redis-server 7001/redis.conf &
redis-server 7002/redis.conf &
redis-server 7003/redis.conf &
redis-server 7004/redis.conf &
redis-server 7005/redis.conf &
2.编辑关闭的脚本 :
vim shutdown.sh
#!/bin/sh
redis-cli -p 7000 shutdown &
redis-cli -p 7001 shutdown &
redis-cli -p 7002 shutdown &
redis-cli -p 7003 shutdown &
redis-cli -p 7004 shutdown &
redis-cli -p 7005 shutdown &
3.启动redis节点 :
sh start.sh
4.关闭redis节点 :
sh shutdow.sh
1.3.8 创建redis集群
#5.0版本执行 使用C语言内部管理集群
redis-cli --cluster create --cluster-replicas 1 192.168.56.129:7000 192.168.56.129:7001 192.168.56.129:7002 192.168.56.129:7003 192.168.56.129:7004 192.168.56.129:7005
执行后 :
yes
1.3.9 Redis集群高可用测试
- 关闭redis主机.检查是否自动实现故障迁移.
- 再次启动关闭的主机.检查是否能够实现自动的挂载.
一般情况下 能够实现主从挂载
个别情况: 宕机后的节点重启,可能挂载到其他主节点中(7001-7002) 正确的
二、Spring整合redis集群
2.1 入门案例
@Test
public void test01(){
Set<HostAndPort> nodes =new HashSet<>();
nodes.add(new HostAndPort("192.168.56.129",7000));
nodes.add(new HostAndPort("192.168.56.129",7001));
nodes.add(new HostAndPort("192.168.56.129",7002));
nodes.add(new HostAndPort("192.168.56.129",7003));
nodes.add(new HostAndPort("192.168.56.129",7004));
nodes.add(new HostAndPort("192.168.56.129",7005));
JedisCluster jediscluster = new JedisCluster(nodes);
}
2.2 编辑pro文件
#redis集群配置
redis.nodes=192.168.56.129:7000,192.168.56.129:7001,192.168.56.129:7002,192.168.56.129:7003,192.168.56.129:7004,192.168.56.129:7005
2.3 编辑配置类
@Configuration //标识配置类
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
@Value("${redis.nodes}")
private String nodes;
/**将set集合交给容器管理*/
@Bean("redisSet")
public Set<HostAndPort> redisSet() {
Set<HostAndPort> redisSet = new HashSet<>();
String[] arrayNodes = nodes.split(",");
for (String node : arrayNodes) {
String host = node.split(":")[0];
int port = Integer.parseInt(node.split(":")[1]);
HostAndPort hostAndPort = new HostAndPort(host, port);
redisSet.add(hostAndPort);
}
return redisSet;
}
@Bean
@Scope("prototype")
public JedisCluster jedisCluster(@Qualifier("redisSet") Set<HostAndPort> redisSet) {
return new JedisCluster(redisSet);
}
}
三、修改项目,使用JedisCluster
将使用
Jedis
的改为JedisCluster
集群
随手笔记
1.Rides集群(哨兵)一般是奇数,最小单位3台
一般是3主3从
2.linux命令
在Vi/Vim编辑器下,取消高亮显示 : :nohl
防火墙关闭 : server iptables stop
批量修改配置文件 :将7001替换全部的7000 :%s/7000/7001/g
3.redis操作命令
主/从复制信息 :
info replication
查询redis中全部的key :
keys *
4.关于Redis集群搭建报错问题
1.关闭redis集群节点
sh stop.sh
2.删除全部文件 除redis.conf文件之外
rm -rf 700*/dump.rdb
rm -rf 700*/nodes.conf
3.之后重启redis节点sh start.sh
4.重新运行集群搭建命令
5.Redis集群原理(分区)
5.1 Redis集群高可用推选原理
Redis的所有节点都会保存当前redis集群中的全部主从状态信息.并且每个节点都能够相互通信.当一个节点发生宕机现象.则集群中的其他节点通过PING-PONG检测机制检查Redis节点是否宕机.当有半数以上的节点认为宕机.则认为主节点宕机.同时由Redis剩余的主节点进入选举机制.投票选举链接宕机的主节点的从机.实现故障迁移
5.2 Redis集群宕机条件
特点 : 集群中如果主机宕机,那么从机可以继续提供服务,
当主机中没有从机时,则向其它主机借用多余的从机.继续提供服务.如果主机宕机时没有从机可用,则集群崩溃.
例如 : 9个redis节点,节点宕机5-7次时集群才崩溃.
5.3 Redis hash槽存储数据原理
RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16384槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据.根据主节点的个数,均衡划分区间
算法:哈希函数: Hash()=CRC16[key]&16383按位与,如图:
当向redis集群中插入数据时,首先将key进行计算.之后将计算结果匹配到具体的某一个槽的区间内,之后再将数据set到管理该槽的节点中
效率 :
1.分片效率高: 发生在服务器中 redis只负责存取
2.Redis集群: 发生在redis内部 效率低