Redis分片机制和集群搭建

需求数据

如果需要在redis中进行海量的数据存储,如果只有一台redis显然不能实现该功能.如果通过扩大内存的方式也不能达到要求.因为时间都浪费在寻址中. 如何有效的存储海量的数据呢???

Redis分片说明

说明:一般采用多台redis,分别保存用户的数据,从而实现内存数据的扩容.
对于用户而言:将redis分片当做一个整体,用户不在乎数据到底存储到哪里,只在乎能不能存.
分片主要的作用: 实现内存扩容.
在这里插入图片描述

Redis分片准备

创建目录

说明:在redis根目录中创建一个shards目录
在这里插入图片描述

分片搭建策略

说明:由于Redis启动是根据配置文件运行的,所以如果需要准备3台redis,则需要复制3份配置文件redis.conf. 端口号依次为6379/6380/6381

复制配置文件:
在这里插入图片描述
修改端口号:
根据配置文件名称,动态修改对应的端口即可.
在这里插入图片描述
在这里插入图片描述
启动redis:

 redis-server  6379.conf
 redis-server  6380.conf
 redis-server  6381.conf

在这里插入图片描述

Redis分片入门案例

 /**
     * 测试Redis分片机制
     * 业务思路:
     *      用户需要通过API来操作3台redis.用户无需关心数据如何存储,
     *      只需要了解数据能否存储即可.
     * 思考: 2005的数据存储到哪台redis中
     *      redis分片是如何实现数据存储的!
     */
    @Test
    public void testShards(){
        List<JedisShardInfo> list = new ArrayList<>();
        list.add(new JedisShardInfo("192.168.126.129", 6379));
        list.add(new JedisShardInfo("192.168.126.129", 6380));
        list.add(new JedisShardInfo("192.168.126.129", 6381));
        ShardedJedis shardedJedis = new ShardedJedis(list);
        shardedJedis.set("2005", "redis分片学习");
        System.out.println(shardedJedis.get("2005"));
    }

一致性hash算法

算法介绍

一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 [1] 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 [2] 。

常识介绍

1.常见hash多少位16进制数? 8位16进制数
2.16进制数取值有哪些 0-9 A-F 共16个数
3. hash的取值范围从 00000000 ~ FFFFFFFF (24)8
4. 上述取值的个数共有多少个??? 要求以2为底 2^32 幂
5. 对相同的数据进行hash值一致

一致性hash说明

步骤:
1.首先计算node节点
2.将用户的key进行hash计算,之后按照顺时针的方向找到最近的node节点之后链接,执行set操作.
在这里插入图片描述

特性一 平衡性

①平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题 [4] 。
说明: 如果发现节点中存储的数据负载不均,则采用虚拟节点的方式实现数据的平衡(相对平衡)
在这里插入图片描述

特性一 单调性

②单调性是指在新增或者删减节点时,不影响系统正常运行 [4] 因为可以实现自动的数据迁移.。
原则: 在进行数据迁移时 应该尽可能少的改变原有的数据.

特性一 分散性

③分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据 [4] 。
鸡蛋不要放在一个篮子里

关于Spring整合Redis分片

关于分片说明

Redis分片的主要的作用是实现内存数据的扩容,Redis分片如果宕机不能实现高可用!!!
Redis的分片的计算发生在业务服务器中 将需要保存的数据存储到redis中.
Redis分片的执行的效率是最高的.

Spring整合Redis分片

编辑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配置类

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);
    }*/
}


编辑 CacheAOP中的注入项

说明:将AOP缓存中的注入项 改为分片对象
在这里插入图片描述

Redis主从实现

Redis高可用实现前提

问题分析: 如果需要实现Redis服务器的高可用,前提条件应该实现主从的配置.

复制哨兵目录

前提:先关闭Redis服务器.
1).复制shards文件
在这里插入图片描述
2).删除持久化文件
在这里插入图片描述
3).运行3台Redis服务器

[root@localhost sentinel]# redis-server 6379.conf & redis             -server 6380.conf & redis-server 6381.conf &

在这里插入图片描述

实现主从挂载

搭建规则:

  1. 6379 当作主机
  2. 6380/6381 当作从机

检查主从的状态: info replication
在这里插入图片描述
3). 实现主从的挂载 slaveof 主机IP 主机端口
在这里插入图片描述
4).关于主从挂载的特点
检查从机中的状态
在这里插入图片描述
检查主机的状态:
在这里插入图片描述

关于挂载错误的说明

说明:由于误操作可能导致主从的结构挂载异常.如何重新挂载呢?
操作说明:可以将redis服务器全部关闭,之后重启 默认条件下的主从的挂载则会失效. 重新挂载即可.
在这里插入图片描述
补充说明:由于slaveof指令在内存中生效.如果内存资源释放,则主从的关系将失效.为了实现永久有效,应该将主从的关系写在配置文件中即可.
新问题的产生: 如果主机意外宕机,则由谁来完成配置文件的修改呢?

哨兵的工作原理

在这里插入图片描述
哨兵工作原理说明
1.当哨兵启动时,会监控当前的主机信息.同时获取链接当前主机的从机信息.
2.当哨兵利用心跳检测机制(PING-PONG),检验主机是否正常.如果连续3次发现主机没有响应信息.则开始进行选举.
3.当哨兵选举完成之后.其他的节点都会当做新主机的从.

哨兵机制实现

复制哨兵配置文件

在这里插入图片描述

修改配置文件

1).修改保护模式
在这里插入图片描述
2).开启后台运行
在这里插入图片描述
3).修改哨兵的监控 其中的1表示投票生效的数量.
在这里插入图片描述
4).哨兵宕机之后的选举时间
如果主机宕机10秒之后开始进行推选.
在这里插入图片描述
5.修改哨兵选举的超时时间
在这里插入图片描述

哨兵高可用测试

1).启动哨兵

[root@localhost sentinel]# redis-sentinel sentinel.conf

2).先关闭主机,之后等待10秒之后,检查从机是否当选主机.之后再次启动主机(宕机的),检查是否为新主机的从
在这里插入图片描述

关于哨兵选举平票的说明

如果有多个哨兵进行选举,如果连续3次投票失败,可能引发脑裂现象的发生.
问题: 脑裂现象发生的概率是多大?? 1/8 = 12.5%
解决策略: 只要增加选举的节点的数量,可以有效的降低脑裂现象的发生. 概率论

链接哨兵的入门案例

   /**
     * 哨兵的测试
     * 参数说明:  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.主要的作用实现内存数据的扩容.
2.由于运算发生在业务服务器中,所以执行的效率更高.
3.Redis的分片没有高可用的效果. 如果其中一个节点出现了问题则导致程序运行出错.
哨兵机制:
1.实现Redis高可用,当redis服务器发生宕机的现象时,哨兵可以灵活的监控.实现自动的选举实现 故障的迁移.
2.哨兵中所监控的redis节点中的数据都是相同的. 无法实现海量的数据存储.
3.哨兵虽然可以实现redis的高可用,但是由于哨兵的本身没有实现高可用.所以存在风险.
如果想要最大程度上减少损耗,则建议不要引入第三方的监控

Redis集群说明

Redis集群数据存储的原理

Hash槽算法 分区算法.
说明: RedisCluster采用此分区,所有的键根据哈希函数**(CRC16[key]%16384)**映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据.根据主节点的个数,均衡划分区间.
算法:哈希函数: Hash()=CRC16[key]%16384
在这里插入图片描述
当向redis集群中插入数据时,首先将key进行计算.之后将计算结果匹配到具体的某一个槽的区间内,之后再将数据set到管理该槽的节点中.

在这里插入图片描述

Redis集群搭建

搭建步骤

说明:Redis集群搭建步骤 参见资料的文档.

链接:https://pan.baidu.com/s/1v6q9FF6tzhYqdfMkPUeu5A 
提取码:deuo 

关于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

关于集群工作原理的说明

redis集群高可用测试

1).检查redis主机的状态
在这里插入图片描述
2).将主机关闭
redis-cli -p 7000 shutdown

3).检查主机是否切换
在这里插入图片描述
4).重启7000服务器.检查是否为7003的从
在这里插入图片描述

关于Redis集群的面试题

原则: Redis的内存缺失则集群崩溃

如果3主3从(1主1从) 最少/宕机几台集群崩溃? B

	A. 1台      B.2台  C.3台  D.4台

如果3主6从(1主2从) 最少宕机几台集群崩溃? C

A. 3台      B.4台  C.5台  D.6台
**说明: 如果没有子节点 则会借用其他主机的多余的从.**

问: Redis集群中最多存储16384个key 错
CRC16(KEY1)%16384 = 2000
CRC16(KEY2)%16384 = 2000
表示key1和key2都归节点1进行管理. 至于节点到底是否能够存储 由内存决定.

问: Redis集群中最多有多少个主机?? 16384台

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值