1.关于Spring整合Redis分片
1.1 关于分片说明
Redis分片的主要的作用是实现内存数据的扩容,Redis分片如果宕机不能实现高可用!!!
Redis的分片的计算发生在业务服务器中 将需要保存的数据存储到redis中.
Redis分片的执行的效率是最高的.
1.2 Spring整合Redis分片
1.2.1 编辑pro配置文件
#添加redis的配置
#添加单台配置
#redis.host=192.168.126.129
#redis.port=6379
#配置多台的redis信息
redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381
1.2.2 编辑Redis配置类
package com.jt.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import java.util.ArrayList;
import java.util.List;
@Configuration //标识我是一个配置类
@PropertySource("classpath:/properties/redis.properties")
public class JedisConfig {
@Value("${redis.nodes}")
private String nodes; //node,node,node
/**
* 添加Redis分片的配置
* 需求1: 动态的获取IP地址/PORT端口
* 动态的获取多个的节点信息. 方便以后扩展
*/
@Bean
public ShardedJedis shardedJedis(){
List<JedisShardInfo> list = new ArrayList<>();
String[] strArray = nodes.split(","); //[node,node,node]
for (String node : strArray){
//ip:port
String host = node.split(":")[0];
int port = Integer.parseInt(node.split(":")[1]);
list.add(new JedisShardInfo(host,port ));
}
return new ShardedJedis(list);
}
/* @Value("${redis.host}") //spel表达式 yml为准
private String host;
@Value("${redis.port}")
private Integer port;
*//**
* 将jedis对象交给spring容器管理
*//*
@Bean //默认条件下是单例对象
//@Scope("prototype") //设置为多利对象
public Jedis jedis(){
//由于将代码写死不利于扩展,所以将固定的配置添加到配置文件中
return new Jedis(host,port);
}*/
}
1.2.3 编辑 CacheAOP中的注入项
说明:将AOP缓存中的注入项 改为分片对象
1.3 Redis主从实现
1.3.1 Redis高可用实现前提
问题分析: 如果需要实现Redis服务器的高可用,前提条件应该实现主从的配置.
1.3.2 复制哨兵目录
前提:先关闭Redis服务器.
1).复制shards文件
2).删除持久化文件
3).运行3台Redis服务器
[root@localhost sentinel]# redis-server 6379.conf & redis -server 6380.conf & redis-server 6381.conf &
1.3.3 实现主从挂载
搭建规则:
1. 6379 当作主机
2. 6380/6381 当作从机
检查主从的状态: info replication
3). 实现主从的挂载 slaveof 主机IP 主机端口
4).关于主从挂载的特点
检查从机中的状态
检查主机的状态:
1.3.4 关于挂载错误的说明
说明:由于误操作可能导致主从的结构挂载异常.如何重新挂载呢?
操作说明:可以将redis服务器全部关闭,之后重启 默认条件下的主从的挂载则会失效. 重新挂载即可.
补充说明:由于slaveof指令在内存中生效.如果内存资源释放,则主从的关系将失效.为了实现永久有效,应该将主从的关系写在配置文件中即可.
新问题的产生: 如果主机意外宕机,则由谁来完成配置文件的修改呢?
1.4 哨兵的工作原理
哨兵工作原理说明
1.当哨兵启动时,会监控当前的主机信息.同时获取链接当前主机的从机信息.
2.当哨兵利用心跳检测机制(PING-PONG),检验主机是否正常.如果连续3次发现主机没有响应信息.则开始进行选举.
3.当哨兵选举完成之后.其他的节点都会当做新主机的从.
1.5 哨兵机制实现
1.5.1 复制哨兵配置文件
1.5.2 修改配置文件
1).修改保护模式
2).开启后台运行
3).修改哨兵的监控 其中的1表示投票生效的数量.
4).哨兵宕机之后的选举时间
如果主机宕机10秒之后开始进行推选.
5.修改哨兵选举的超时时间
1.5.3 哨兵高可用测试
1).启动哨兵
[root@localhost sentinel]# redis-sentinel sentinel.conf
2).先关闭主机,之后等待10秒之后,检查从机是否当选主机.之后再次启动主机(宕机的),检查是否为新主机的从
1.6 关于哨兵选举平票的说明
如果有多个哨兵进行选举,如果连续3次投票失败,可能引发脑裂现象的发生.
问题: 脑裂现象发生的概率是多大?? 1/8 = 12.5%
解决策略: 只要增加选举的节点的数量,可以有效的降低脑裂现象的发生. 概率论
1.7 链接哨兵的入门案例
/**
* 哨兵的测试
* 参数说明: masterName: 主机的变量名称
* sentinels: 链接哨兵的集合.
* 理解: 哨兵虽然链接3台redis. 但是3台redis中存储的数据都是一样的.对于用户而言
* 就是一台.
*/
@Test
public void testSentinel(){
Set<String> sets = new HashSet<>();
sets.add("192.168.126.129:26379");
JedisSentinelPool sentinelPool =
new JedisSentinelPool("mymaster",sets);
Jedis jedis = sentinelPool.getResource();
jedis.set("aaa", "wt");
System.out.println(jedis.get("aaa"));
jedis.close();
}
1.8 关于分片哨兵的总结说明
分片:
1.主要的作用实现内存数据的扩容.
2.由于运算发生在业务服务器中,所以执行的效率更高.
3.Redis的分片没有高可用的效果. 如果其中一个节点出现了问题则导致程序运行出错.
哨兵机制:
1.实现Redis高可用,当redis服务器发生宕机的现象时,哨兵可以灵活的监控.实现自动的选举实现 故障的迁移.
2.哨兵中所监控的redis节点中的数据都是相同的. 无法实现海量的数据存储.
3.哨兵虽然可以实现redis的高可用,但是由于哨兵的本身没有实现高可用.所以存在风险.
如果想要最大程度上减少损耗,则建议不要引入第三方的监控
2.Redis集群搭建
2.1 搭建步骤
说明:Redis集群搭建步骤 参见课前资料的文档.
2.2 关于Redis集群搭建错误的说明
前提条件: redis.conf的配置文件首先应该配置正确 码云中有redis配置.
搭建步骤:
1. 关闭所有的Redis服务项
2.删除nodes.conf配置文件
由于搭建集群之后,所有的集群的信息都会写入nodes.conf文件中,如果下次重启会读取其中的配置信息实现redis集群的主从的搭建. 所以如果需要重新搭建集群,则必须删除该文件重新生成.
3.重启Redis服务器之后重新搭建集群
redis-cli --cluster create --cluster-replicas 1 192.168.126.129:7000 192.168.126.129:7001 192.168.126.129:7002 192.168.126.129:7003 192.168.126.129:7004 192.168.126.129:7005
2.3 关于集群工作原理的说明
2.3.1 redis集群高可用测试
1).检查redis主机的状态
2).将主机关闭
redis-cli -p 7000 shutdown
3).检查主机是否切换
4).重启7000服务器.检查是否为7003的从
2.4 关于Redis集群的面试题
原则: Redis的内存缺失则集群崩溃
2.4.1 如果3主3从(1主1从) 最少/宕机几台集群崩溃? B
A. 1台 B.2台 C.3台 D.4台
2.4.2 如果3主6从(1主2从) 最少宕机几台集群崩溃? C
A. 3台 B.4台 C.5台 D.6台
**说明: 如果没有子节点 则会借用其他主机的多余的从.**
2.5 SpringBoot整合Redis集群
2.5.1入门案例测试
/**
* redis集群的入门案例
* jedisCluster 操作整个redis集群,链接redis的所有的节点
*/
@Test
public void testCluster(){
Set<HostAndPort> sets = new HashSet<>();
sets.add(new HostAndPort("192.168.126.129", 7000));
sets.add(new HostAndPort("192.168.126.129", 7001));
sets.add(new HostAndPort("192.168.126.129", 7002));
sets.add(new HostAndPort("192.168.126.129", 7003));
sets.add(new HostAndPort("192.168.126.129", 7004));
sets.add(new HostAndPort("192.168.126.129", 7005));
JedisCluster jedisCluster = new JedisCluster(sets);
jedisCluster.set("cluster", "集群测试");
System.out.println(jedisCluster.get("cluster"));
}