Redis分片前提:Redis可以通过修改内存的大小实现数据的保存,但是不能设置的过大
解决方案:可以采用Redis分片机制来实现内存数据的扩容,使用Redis分片的主要目的就是为了内存扩容,解决海量数据的存储问题
Redis每个分片内的数据都是不相同的
1.分离三个分片节点即准备多个配置文件(复制三份Redis.conf)
2.修改端口号(vim XXX.conf)
3.关闭AOF模式
AOF模式特点:
AOF模式默认是关闭状态如果需要则手动开启AOF模式可以记录程序的执行过程,可以实现数据的实时持久化,但是AOF文件占用空间大,回复数据熟读慢AOF模式开启之后RDB模式不再生效4.修改RDB模式名称
RDB模式特点:
RDB模式采用定期持久化的方式,会有丢失数据的风险RDB模式记录的是当前Redis的内存记录快照,只记录当前状态,持久化效率最高RDB持久化命令:
save 同步操作,要求记录马上持久化,可能对现有的操作造成阻塞bgsave 异步操作,开启单独的线程实现持久化任务持久化周期
save 900 1 在900秒内,如果执行一次更新操作,则持久化一次.save 300 10 在300秒内,如果执行10次更新操作,则持久化一次.save 60 10000 在60秒内,如果执行10000次更新操作,则持久化一次.save 1 1 ???不可以 容易阻塞 性能太低.不建议使用.用户操作越频繁,则持久化周期越短. 启动三台Redis Redis入门案例
ShardedJedis 是通过一致性哈希来实现分布式缓存的,通过一定的策略把不同的key分配到不同的redis server上,达到横向扩展的目的
JedisShardInfo 存储Ip地址加端口号
一致性哈希算法1997年麻省理工学院提出,解决分布式缓存问题,在移除或者添加一个服务器时,可以尽可能小的改变已存在的服务请求与处理请求服务器之间的映射关系
一致性Hash原理 一般的hash由8位16进制数组成的. 共有2^32种可能性!!!hash算法对相同的数据进行hash运算时 结果必然相同.进制
二进制 取值 : 0-1 规则满2进1(01010101)从左往右运算第一位数时1* 2 ^ 0 /1*2^1/以此类推八进制 取值 : 0-7 规则满8进1 2^3=8 每三位二进制数就是一个8进制数十六进制 取值 : 0-9 A-F 规则满16进一 2^4=16 每四位二进制数就是一个16进制数在2^32的范围内会有多个储存节点,每个节点就好比是一个Redis缓存节点,节点是经过hash运算后的值,我们存入的key-Value是按顺时针去寻找最近的节点 一致性Hash特性 1.平衡性
平衡性是指Hash的结果应该平均分配到各个节点.这样从算法上解决了负载均衡问题,通过引入虚拟节点实现数据的平衡,但是平衡不是绝对的
图解: node1到node2,node1的顺时针存储空间过小容易引发负载不均现象,hash算法会添加一个node2虚拟节点
单调性是指在新增或者删除节点的时候不影响系统的正常运行
图解: 在引入新的节点的时候可以实现数据的迁移
分散性是指数据应该分散的存放在分布式集群的哥哥节点,节点可以有自己的备份,不必每个节点都存储所有的数据(鸡蛋不要放在一个篮子里)
Spring整合redis分片机制1.准备Redis.properties文件配置多台Redis
# 配置多台redisredis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381# 配置单台redis#redis.host=192.168.126.129#redis.port=63792.编辑配置类
@Configuration 标识我是一个配置类@PropertySource(“classpath:配置文件路径”)@Value 动态赋值1.动态赋值过来的是字符串类型数组内存的多条信息,并且是以逗号分割的所以需要分割字符串split() 方法用于把一个字符串分割成字符串数组2.新建LIst类型集合,JedisShardInfo 存储IP+端口的泛型3.遍历所有的截取完成的String类型数组为List赋值,遍历出来的值格式为(node=ip:port)4.String类型的host为node的:后面的值分割后的下标为0的值5.Integer下的parseInt方法Integer类型转换为Int类型6.建一个存储分片的类型JedisShardInfo 将遍历到的host和port传入得到端口7.将遍历到的IP和端口传入存储端口的List集合8.new一个Redis分片对象传入List集合9 . 返回对象 @Configuration //标识我是配置类@PropertySource("classpath:/properties/redis.properties")public class RedisConfig { @Value("${redis.nodes}") private String nodes; //node,node,node /** * spring整合redis分片机制 */ @Bean public ShardedJedis shardedJedis(){ //1.获取每个节点的信息 String[] strNodes = nodes.split(","); List<JedisShardInfo> shards = new ArrayList<>(); //2.遍历所有node.为list集合赋值 for(String node :strNodes){ //node=ip:port String host = node.split(":")[0]; int port = Integer.parseInt(node.split(":")[1]); JedisShardInfo info = new JedisShardInfo(host,port); shards.add(info); } ShardedJedis shardedJedis = new ShardedJedis(shards); return shardedJedis; } Redis哨兵机制前提: Redis分片机制虽然可以实现内存数据的扩容,但是如果Redis服务器繁盛了宕机的现在,会影响整个分片使用
问题: Redis分片机制只是实现了内存数据的扩容并没有实现高可用.没有实现当主机宕机之后.由从机自动的实现故障迁移.用户访问不受任何影响.
注:分片机制没实现主机宕机会报错
如果要实现Redis高可用机制,必须要闲时间主从搭建
主从关系6379主机-M,其他都是从机-S
准备Redis的配置拷贝shards目录(存放的.conf)(cp -r shards sentinel)删除拷贝过来的持久化文件(.rdb文件)(rm -rf *.rdb)准备3台Redis服务器(重启Redis即可)查看Redis默认下的主从关系(进入Redis主机redis-cli -p 文件.conf)(info replication 查看主从关系)实现主从配置(slave of 主机IP 主机端口) slave of 主机IP 主机端口 检查数据是否同步 Redis主从配置问题
问题说明: Redis服务器配置了主从结构之后,如果服务器宕机,然后再次重起,服务器又会变为主机
解决思路: 执行了主从挂载命令该命令一直保存在内存中.当redis服务器重启之后,该命令失效.如果想要一直保持主从的关系.则必须将主从的结构写入Redis.conf的配置文件中.
(1) 启动Redis哨兵,由哨兵来监控整个Redis主从状态,主要监控M(主)主机,同时获取从机的信息
(2) 哨兵利用心跳检测机制(PING-阳光的短靴)的方式监控主机是否宕机. 如果连续3次主机没有响应.则哨兵判断主机宕机.
(3) 根据从主机中获取的从机信息.之后利用 选举机制算法.挑选新的主机.
(4) 之后将剩余的redis修改为当前主机的的从.并且修改配置文件.
修改哨兵的监控配置(参数为IP+端口+选举生效的票数)修改哨兵的选举时间,当Redis主机宕机之后,哨兵多久开始选举选举超时时间设定
说明:如果当选主机的服务器在规定的时间之内,没有完成切换.则哨兵重新选举. 启动哨兵
命令redis-sentinel sentinel.conf
测试步骤
1.将其中一台主机宕机
redis-cli
info replication
redis-cli shutdown
2.十秒后检查从机是否当选主机
masterName:主机名称 哨兵配置文件中 mymaster,sentinele : 哨兵节点信息Set集合存放哨兵节点信息sentinelPool.getResource(); 获取资源set/get测试