1.Redis集群算法
1. Redis集群工作原理
原理说明:
Redis的所有节点都会保存当前redis集群中的全部主从状态信息(node.conf).并且每个节点都能够相互通信.当一个节点发生宕机现象.则集群中的其他节点通过PING-PONG检测机制检查Redis节点是否宕机.当有半数以上的节点认为宕机.则认为主节点宕机.同时由Redis剩余的主节点进入选举机制.投票选举链接宕机的主节点的从机.实现故障迁移.
2. Redis集群宕机的条件
说明:当redis主节点宕机之后.没有从节点进行替补,则整个redis集群崩溃!!!
特点:集群中如果主机宕机,那么从机可以继续提供服务,
当主机中没有从机时,则向其它主机借用多余的从机.继续提供服务.如果主机宕机时没有从机可用,则集群崩溃.
答案:9个redis节点,三台主机,节点宕机5-7次时集群才崩溃.
3. Redis存储的原理(分区)
知识准备:
- 当用户操作redis主机时,从机会自动的实现数据的同步!!! (主从复制)
- Redis集群搭建的主要的目的2个 1.实现内存扩容 2.可以实现Redis的高可用.
- redis中的主机所保存的数据都是不相同的!!!.
- redis集群中的数据存储,不是随机存储,内部有算法的支持. hash槽算法(分区算法)
Redis集群搭建的划分:
Redis hash存储的原理:
说明: RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]%16384)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据.根据主节点的个数,均衡划分区间.
算法:哈希函数: Hash()=CRC16[key]%16384 CRC16是哈希算法的一种
当向redis集群中插入数据时,首先将key进行计算.之后将计算结果匹配到具体的某一个槽的区间内,之后再将数据set到管理该槽的节点中.
如图所示
4. Redis分区说明
Redis分区只负责 数据应该存储到哪里的问题.至于是否能存储的下 完全由Redis内存决定.
特点:
1.hash(key1)%16384 = 3000
2.hash(key2)%16384 = 3000 key1和key2 都归第一个节点进行管理.
5.Redis hash槽与一致性 hash算法的区别
1.运算位置不同.
1.redis分片机制在业务服务器中完成的运算.
2.redis分区算法在连接Redis之后,由redis进行计算.
2.算法不同
一致性hash算法/hash槽算法.
3.redis分片可以随意的进行数据的保存. redis分区不能随机存储.分区中只能保存属于我的key.
6.Redis面试题
1.Redis集群中的主机最多 多少台? 16384个.
=Redis集群内存多少最多可以扩展到原有redis多少倍.
2.Redis中存储的数据最多16384个??? 不对的. 16384只是分区的大小.至于能存储多少数据,完全由内存决定.
7.Redis集群宕机条件说明
说明: redis集群中 只要有一台Redis 主机宕机. 则整个Redis集群崩溃(可以进行高可用)
问题分析:
- 如果有6台Redis搭建集群,问: 最少宕机多少台Redis集群崩溃???
宕机2台集群崩溃
- 如果搭建9台Redis.3台主机, 问 :最少宕机Redis台 集群奔溃???
宕机5台集群崩溃
补充说明:如果想让集群尽可能不宕机,则适当增加从节点的数量. 2-3个从即可.
8.什么是脑裂现象
说明:在集群的机制中,由主机进行选举,当主机在进行选举时如果连续3次出现平票的结果时,则可能引发脑裂现象.
问题:出现脑裂现象的概率是多少? 答: 1/8=12.5%
如何有效降低脑裂现象: 可以通过增加主机的数量来有效降低脑裂的发生
2.Spring整合Redis集群
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
#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
2.2编辑配置类
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 redis.clients.jedis.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
//表明该类是一个配置类
@Configuration
@PropertySource("classpath:properties/redis.properties")
public class RedisConfig {
@Value("${redis.nodes}")
private String nodes;
/**
* spring 整合redis集群
*/
@Bean //一定要交给spring容器管理
public JedisCluster jedisCluster(){
Set<HostAndPort> nodeSet = new HashSet<>();
String[] clusters = nodes.split(",");//形成node结点的数组
for (String cluster : clusters) {//遍历结点
String host = cluster.split(":")[0];//获取ip
int port = Integer.parseInt(cluster.split(":")[1]);//获取端口
HostAndPort hostAndPort = new HostAndPort(host,port);
nodeSet.add(hostAndPort);
}
return new JedisCluster(nodeSet);
}
}
2.3 修改CacheAOP注入项
如果配置了AOP, 修改AOP中的依赖注入即可, 改为注入JedisCluster
对象