1. Redis分片机制说明
1.1一致性hash算法
1.1.1 一致性Hash算法介绍
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 [1] 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 [2] 。
1.1.2 一致性Hash原理说明
常识:
1).对相同的数据hash得到的结果相同
2).常见hash值 8位16进制数 2^32种可能性
1.1.3 平衡性说明
说明: 平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题 .
如果发现数据分布不均匀,则采用虚拟节点的方式,实现数据的平衡. 如果一次平衡不能达到目标则多次生成虚拟节点.但是数据平衡没有办法做到绝对的平均.
1.1.4 单调性说明
单调性是指在新增或者删减节点时,不影响系统正常运行
如果新增或者删除节点,则尽可能不要改变原有的数据结构.
1.1.5 分散性
分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据
鸡蛋不要放到一个篮子里.
2. Redis哨兵机制
2.1 Redis分片机制问题
说明: 如果redis分片中有一个节点宕机,则可能会影响整个服务的运行. redis分片没有实现高可用.
2.2 Redis主从结构搭建
2.2.1 复制配置文件
2.2.2 准备3台redis
2.2.3 主从搭建
命令1: info replication
命令2: slaveof IP PORT 主从挂载命令
检查主从结构状态
关于主从结构说明:
主和从都知道 当前的主从的状态, 并且只有主机可以写操作.从机只能读操作.
2.2 Redis哨兵机制工作原理
1).当哨兵启动时,首先会监控主机,从主机中获取当前所有的节点的状态,同时哨兵开启心跳检测机制.
2).当主机发生宕机的现象时,由于哨兵有PING-PONG机制 发现主机宕机,则哨兵开始进行选举.
3).当选举成功之后,新的主机当选之后,其他的节点当新主机的从.
2.3 编辑哨兵配置文件
1)关闭保护模式
2).开启后台运行
3).编辑监控配置
4).修改选举时间
2.4 启动哨兵服务
命令: redis-sentinel sentinel.conf
高可用检查:
1).先关闭主机 等待10秒检查是否进行选举.
2).启动6379. 检查是否当选新主机的从.
2.5 哨兵测试API
/**
* 测试哨兵
*/
@Test
public void testSentinel(){
Set<String> set = new HashSet<>();
set.add("192.168.126.129:26379");
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(1000);
poolConfig.setMaxIdle(40);
poolConfig.setMinIdle(10);
JedisSentinelPool sentinelPool =
new JedisSentinelPool("mymaster",set,poolConfig);
Jedis jedis = sentinelPool.getResource();
jedis.set("sentinel", "哨兵机制测试");
System.out.println(jedis.get("sentinel"));
jedis.close();
}
2.6 SpringBoot整合哨兵机制
2.6.1 编辑pro配置文件
2.6.2 编辑配置类
2.6.3 编辑CacheAOP
2.6.4 关于分片/哨兵总结
1.Redis分片主要的作用实现内存的扩容,缺点:没有实现高可用的效果.
2.Redis哨兵主要的作用实现了redis节点高可用. 缺点:没有实现内存扩容
Redis哨兵机制实质就是引入第三方的监控,但是需要保证第三方的高可用.就必须引入更多的资源.
3.Redis集群
参见搭建文档.
3.1 集群搭建错误解决方案
注意事项: redis集群搭建要求节点的数据必须为null.
1).将所有的redis节点全部关闭 sh stop.sh
2).删除多余的文件
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
3.2 Redis集群入门案例
@Test
public void testCluster(){
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.126.129", 7000));
nodes.add(new HostAndPort("192.168.126.129", 7001));
nodes.add(new HostAndPort("192.168.126.129", 7002));
nodes.add(new HostAndPort("192.168.126.129", 7003));
nodes.add(new HostAndPort("192.168.126.129", 7004));
nodes.add(new HostAndPort("192.168.126.129", 7005));
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(1000);
poolConfig.setMaxIdle(40);
poolConfig.setMinIdle(20);
JedisCluster jedisCluster = new JedisCluster(nodes,poolConfig);
jedisCluster.set("jedisCluster", "redis集群搭建");
System.out.println(jedisCluster.get("jedisCluster"));
}
3.3 面试问题
1).redis集群中一共可以存储16384个数据?
不对: redis中存储多少数据完全由内存决定
hash(key1)=3000
hash(key2)=3000
2).redis集群中最多可以有多少个redis主机? 16384台主机 一台主机管理一个槽位.
3.4 SpringBoot整合Redis集群
3.4.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
#配置redis哨兵机制
#redis.node=192.168.126.129:26379
#配置redis集群
redis.nodes=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
3.4.2 编辑配置类
@Configuration //标识我是一个配置类 一般与@Bean注解联用
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
@Value("${redis.nodes}")
private String nodes; //node,node,node
@Bean
public JedisCluster jedisCluster(){
Set<HostAndPort> nodesSet = new HashSet<>();
String[] nodeArray = nodes.split(",");
for (String node : nodeArray){ //host:port
String host = node.split(":")[0];
int port = Integer.parseInt(node.split(":")[1]);
HostAndPort hostAndPort = new HostAndPort(host, port);
nodesSet.add(hostAndPort);
}
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(1000);
config.setMaxIdle(60);
config.setMinIdle(20);
return new JedisCluster(nodesSet,config);
}
}