Redis长久化策略

什么是长久化

阐明:Redis运行环境在内存中,如果redis服务器敞开,则内存数据将会失落.
需要: 如何保留内存数据呢?
解决方案: 能够定期将内存数据长久化到磁盘中.
长久化策略规定:
当redis失常运行时,定期的将数据保留到磁盘中,当redis服务器重启时,则依据配置文件中指定的长久化的形式,实现数据的复原.(读取数据,之后复原数据.)

RDB模式

RDB模式特点阐明

1).RDB模式是Redis默认的策略.
2).RDB模式可能定期(工夫距离)长久化. 弊病:可能导致数据的失落.
3).RDB模式记录的是内存数据的快照.长久化效率较高. 快照只保留最新的记录.

RDB模式命令

1.save命令: 将内存数据长久化到磁盘中 被动的操作 会造成线程阻塞
2.bgsave命令: 将内存数据采纳后盾运行的形式,长久化到文件中. 不会造成阻塞.
3.默认的长久化的机制
save 900 1 如果在900秒内,执行了1次更新操作,则长久化一次
save 300 10 如果在300秒内,执行了10次更新操作,则长久化一次
save 60 10000 如果在60秒内,执行了10000次更新操作,则长久化一次

长久化文件配置

1).指定长久化文件

2).指定长久化文件目录

AOF模式

AOF模式特点

1).AOF模式默认条件下是敞开的.须要手动开启
2).AOF模式记录的是用户的操作过程,所以能够实现实时长久化操作.
3).AOF模式因为记录的是实时的操作过程,所以长久化文件较大.须要定期维护.

启动AOF模式

阐明:如果一旦开启AOF模式,则以AOF模式为准.

对于长久化操作总结

1.当内存数据容许大量失落时,采纳RDB模式 (快)
2.当内存数据不容许失落时,采纳AOF模式(定期维护长久化文件)
3.个别在工作中采纳 RDB+AOF模式独特作用,保证数据的有效性.

面试题


问题: 如果小李(丑陋妹子)在公司服务器中执行了flushAll命令,问怎么办?
答: 须要找到aof文件之后,删除flushAll命令 之后重启redis,执行save命令即可.

内存优化策略

为什么须要内存优化

阐明: 因为redis在内存中保留数据.如果始终存储,则内存数据必然溢出.所以须要定期维护内存数据的大小.
保护策略: 删除旧的不必的数据,保留新的罕用的数据

LRU算法

(设置上次至今的范畴间隔时间t,筛选t最大的删除)

LRU是Least Recently Used的缩写,即最近起码应用,是一种罕用的页面置换算法,抉择最近最久未应用的页面予以淘汰。该算法赋予每个页面一个拜访字段,用来记录一个页面自上次被拜访以来所经验的工夫 t,当须淘汰一个页面时,抉择现有页面中其 t 值最大的,即最近起码应用的页面予以淘汰。
计算维度: 工夫T
注意事项: LRU算法是迄今为止内存中最好用的数据置换算法.

LFU算法

(设置应用次数num,为了将一些很久不实用但之前应用次数很多的数据筛选,所以,num数当很久不被援用时依照指数衰减即,定时右移一位。最初筛选num数最小的删除)

LFU(least frequently used (LFU) page-replacement algorithm)。即最不常常应用页置换算法,要求在页置换时置换援用计数最小的页,因为常常应用的页应该有一个较大的援用次数。然而有些页在开始时应用次数很多,但当前就不再应用,这类页将会长工夫留在内存中,因而能够将援用计数寄存器定时右移一位,造成指数衰减的均匀应用次数。
维度: 应用次数

随机算法(随机筛选删除)

随机算法.

TTL算法

(依据存活工夫筛选存活工夫最小的,提前删除)

依据残余的存活工夫,将马上要超时的数据提前删除.

配置内存优化策略

(redis.conf文件的570行~600行设置)

1.volatile-lru 在设定了超时工夫的数据中,采纳lru算法
2.allkeys-lru 在所有的数据中,采纳lru算法
3.volatile-lfu 在设定了超时工夫的数据中,采纳lfu算法
4.allkeys-lfu 所有数据采纳lfu算法
5.volatile-random 设置超时工夫数据的随机算法
6.allkeys-random 所有数据的随机
7.volatile-ttl 将设定了超时工夫的数据,提前删除.
8.noeviction 默认规定 如果设定noeviction 则不删除数据,间接报错返回.

手动批改redis内存优化策略:

对于缓存面试问题

问题出发点:
因为缓存生效,导致大量的用户的申请,间接拜访数据库服务器.导致负载过高,从而引发整体宕机的危险!!!

缓存穿透

(拜访数据库中没有的数据,所以每次redis中都无奈命中,间接拜访数据库,可能威逼到数据库)

阐明: 用户频繁拜访数据库中不存在的数据,可能呈现缓存穿透的景象.如果该操作是高并发操作,则可能间接威逼数据库服务器.
解决方案:
1.采纳IP限流的形式 升高用户拜访服务器次数. IP动静代理(1分钟变一次)
2.微服务的解决形式: 利用断路器返回执行的业务数据即可不执行数据库操作 从而爱护了数据库.
3.微服务解决形式: API网关设计. 不容许做非法操作

缓存击穿

(高并发的查问同一数据时,redis中没有该数据,但数据库中有,全副都拜访了数据库时,可能威逼到数据库)

阐明: 因为redis中某个热点数据因为超时/删除等操作造成数据生效.同时用户高并发拜访该数据,则可能导致数据库宕机.该操作称之为 缓存击穿.
解决方案: 能够采纳多级缓存的设计. 同时数据的超时工夫采纳随机数的形式.

缓存雪崩

(redis中大量数据同时生效或失落,此时压力一下都到了数据库这边,间接威逼到数据库)

阐明: 因为redis内存数据大量生效.导致用户的拜访命中率太低.大量的用户间接拜访数据库,可能导致数据库服务器宕机. 这种景象称之为缓存雪崩.
解决:
1.采纳多级缓存.
2.设定不同的超时工夫
3.禁止执行 flushAll等敏感操作.

Redis分片机制

(reids进行扩容,如果一台呈现问题,数据扩散存储,拜访到有问题的就会报错)

Redis分片阐明

阐明: 如果须要Redis存储海量的内存数据,应用单台redis不能满足用户的需要,所以能够采纳Redis分片机制实现数据存储.
注意事项:
如果有多台redis,则其中的数据都是不一样的…

Redis部署

搭建端口:6379/6380/6381

筹备配置文件:

6379.conf 6380.conf 6381.conf

批改端口号

只批改80/81的端口即可

Redis分片测试

@Test    public void testShards(){        List<JedisShardInfo> shards = new ArrayList<>();        shards.add(new JedisShardInfo("192.168.126.129", 6379));        shards.add(new JedisShardInfo("192.168.126.129", 6380));        shards.add(new JedisShardInfo("192.168.126.129", 6381));        ShardedJedis shardedJedis = new ShardedJedis(shards);        shardedJedis.set("shards", "redis分片操作!!!");        System.out.println(shardedJedis.get("shards"));    }

一致性HASH算法

(数据计算hash后,在hash环中查看交给哪一个node治理,一致性hash只计算治理归属问题,三大个性:平衡性:虚节点;枯燥性:增删节点时只对繁多节点有影响;分散性:数据扩散在各个节点)

概念

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

原理阐明

常识温习:

  1. 惯例hash由多少位16进制数组成??? 8位16进制数组成 2^32次方
  2. 如果对雷同的数据进行hash计算问后果是否雷同??? 后果必然雷同.

个性一平衡性

①平衡性是指hash的后果应该平均分配到各个节点,这样从算法上解决了负载平衡问题.
实现平衡性的计划: 引入虚构节点

个性二枯燥性

②枯燥性是指在新增或者删减节点时,不影响零碎失常运行 [4] 。
特点:在进行数据迁徙时,要求尽可能小的扭转数据.

个性三分散性

③分散性是指数据应该扩散地寄存在分布式集群中的各个节点(节点本人能够有备份),不用每个节点都存储所有的数据 [4] 。
俗语: 鸡蛋不要到放到一个篮子里

SpringBoot整合Redis分片

编辑properties配置文件

# 配置单台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

编辑配置类

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.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 RedisConfig {    /**     * SpringBoot整合Redis分片,本质:ShardedJedis对象,交给容器治理     */    @Value("${redis.nodes}")    private String nodes;       //node,node,node    @Bean    public ShardedJedis shardedJedis(){        List<JedisShardInfo> shards = new ArrayList<>();        String[] nodeArray = nodes.split(",");        for (String node : nodeArray){ //node=ip:port            String host = node.split(":")[0];            int port = Integer.parseInt(node.split(":")[1]);            //筹备分片节点信息            JedisShardInfo info  = new JedisShardInfo(host, port);            shards.add(info);        }        return new ShardedJedis(shards);    }   /* @Value("${redis.host}")    private String  host;    @Value("${redis.port}")    private Integer port;    @Bean    public Jedis jedis(){        return new Jedis(host, port);    }*/}

批改AOP缓存注入

无需批改其余代码,只须要批改接管依赖注入对象类型即可)

阐明:将AOP中的注入对象切换为分片对象

Redis哨兵机制

(redis的高可用,当主机挂掉,通过哨兵选举,将一个从机百年未主机并从新搭建主从关系)

分片机制存在的问题

阐明: redis分片次要的作用是实现内存数据的扩容.然而如果redis分片中有一个节点宕机,则间接影响所有节点的运行. 是否优化?
实现策略: 采纳Redis哨兵机制实现Redis节点高可用.

Redis节点主从配置

筹备主从节点

1).敞开redis分片的节点,之后复制配置文件筹备哨兵的配置.

2).复制分片的目录 改名为sentinel

3).删除多余的长久化文件,保留redis配置文件

4).启动3台Redis服务器

实现redis主从

命令: info replication 查看redis节点的状态信息

节点划分: 6379 当主机 6380/81 当从机

命令2: 实现主从挂载 slaveof host port


3).查看6379主机的状态

论断: redis所有节点都能够雷同通信.并且门路以后的主从的状态.

数据主从同步的状态

哨兵机制工作原理

心跳检测ping-pong三次决定主机是否存活,选举制度通过配置文件设定)

1).当哨兵启动时,会链接redis主节点,同时获取所有节点的状态信息
2).当哨兵间断3次通过心跳检测机制(PING-PONG),如果发现主机宕机,则开始选举.
3).哨兵外部通过随机算法筛选一台从机入选新的主机.其余的节点应该当新主机的从.

哨兵机制配置

敞开保护模式

开启后盾运行

配置投票机制

依据哨兵数量决定投票失效数 个别哨兵为奇数个(三局两胜,五局三胜...);咱们测试只有一台哨兵,所以一票定主机)

批改投票工夫

(哨兵选定从机后,给定上任工夫,否则从新选举,避免死锁产生,即选好后,被选中的从机宕机了)

主机宕机3秒之后开始选举

哨兵高可用测试(哨兵端口:26379)

1.启动哨兵 redis-sentinel sentinel.conf

2).查看哨兵配置

3)将主机宕机,之后查看从机是否入选主机

4).启动之前的主机,查看是否入选新主机的从

5).如果搭建异样 则删除重做
敞开所有redis服务器.

哨兵入门案例

/*** 测试Redis哨兵*/@Testpublic void testSentinel(){    Set<String> set = new HashSet<>();    //1.传递哨兵的配置信息    set.add("192.168.126.129:26379");    JedisSentinelPool sentinelPool =    new JedisSentinelPool("mymaster",set);    Jedis jedis = sentinelPool.getResource();    jedis.set("aa","哨兵测试");    System.out.println(jedis.get("aa"));}

Redis集群阐明

分片/哨兵有哪些毛病

1.分片毛病: 分片的次要的性能是实现内存的扩容的. 然而没有高可用的成果. 如果宕机将间接影响用户的应用.
2.哨兵毛病: 数据没有扩容,哨兵自身没有高可用机制
需要: 既能够实现内存数据的扩容,同时实现高可用机制(不必第三方). 应该应用Redis集群.

Redis集群搭建

1.为什么要搭建集群

通常,为了进步网站响应速度,总是把热点数据保留在内存中而不是间接从后端数据库中读取。

Redis是一个很好的Cache工具。大型网站利用,热点数据量往往微小,几十G上百G是很失常的事儿。
因为内存大小的限度,应用一台 Redis 实例显然无奈满足需要,这时就须要应用多台 Redis作为缓存数据库。然而如何保证数据存储的一致性呢,这时就须要搭建redis集群.采纳正当的机制,保障用户的失常的拜访需要.
采纳redis集群,能够保证数据扩散存储,同时保证数据存储的一致性.并且在外部实现高可用的机制.实现了服务故障的主动迁徙.

2.集群搭建打算

主从划分:
3台主机 3台从机共6台 端口划分7000-7005

集群搭建步骤

3.筹备集群文件夹

Mkdir cluste
在cluster文件夹中别离创立7000-7005文件夹

4.复制配置文件

阐明:
将redis根目录中的redis.conf文件复制到cluster/7000/ 并以原名保留

cp redis.conf cluster/7000/

5.编辑配置文件

1.正文本地绑定IP地址
![Image \[2\].png](/img/bVcKVkq)
2.敞开保护模式
![Image \[12\].png](/img/bVcKVlg)
3.批改端口号
![Image \[3\].png](/img/bVcKVku)
4.启动后盾启动
![Image \[4\].png](/img/bVcKVkv)
5.批改pid文件
![Image \[5\].png](/img/bVcKVkw)
6.批改长久化文件门路
![Image \[6\].png](/img/bVcKVkx)
7.设定内存优化策略
![Image \[7\].png](/img/bVcKVky)
8.敞开AOF模式
![Image \[8\].png](/img/bVcKVkA)
9.开启集群配置
![Image \[9\].png](/img/bVcKVkE)
10.开启集群配置文件
![Image \[10\].png](/img/bVcKVkG)
11.批改集群超时工夫
![Image \[11\].png](/img/bVcKVkH)

6.复制批改后的配置文件
阐明:将7000文件夹下的redis.conf文件别离复制到7001-7005中

[root@localhost cluster]# cp 7000/redis.conf  7001/[root@localhost cluster]# cp 7000/redis.conf  7002/[root@localhost cluster]# cp 7000/redis.conf  7003/[root@localhost cluster]# cp 7000/redis.conf  7004/[root@localhost cluster]# cp 7000/redis.conf  7005/

7.批量批改
阐明:别离将7001-7005文件中的7000改为对应的端口号的名称,
批改时留神方向键的应用

8.通过脚本编辑启动/敞开指令

1.创立启动脚本 vim start.sh

2.编辑敞开的脚本 vim shutdown.sh
![Image \[2\].png](/img/bVcKVlt)
3.启动redis节点
sh start.sh
4.查看redis节点启动是否失常
![Image \[3\].png](/img/bVcKVlu)

9.创立redis集群
1示意一主一从,此处六台redis,示意三组,三主三从 ; 如果是2示意一主两从

#5.0版本执行 应用C语言外部治理集群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


![Image \[2\].png](/img/bVcKVlG)

10.Redis集群高可用测试

1.敞开redis主机.查看是否主动实现故障迁徙.
2.再次启动敞开的主机.查看是否可能实现主动的挂载.

个别状况下 可能实现主从挂载
个别情况: 宕机后的节点重启,可能挂载到其余主节点中(7001-7002) 正确的
![Image \[3\].png](/img/bVcKVlH)

Redis集群原理

11.Redis集群高可用推选原理
如图所示

原理阐明:
Redis的所有节点都会保留以后redis集群中的全副主从状态信息.并且每个节点都可能互相通信.当一个节点产生宕机景象.则集群中的其余节点通过PING-PONG检测机制查看Redis节点是否宕机.当有半数以上的节点认为宕机.则认为主节点宕机.同时由Redis残余的主节点进入选举机制.投票选举链接宕机的主节点的从机.实现故障迁徙.
12.Redis集群宕机条件
特点:集群中如果主机宕机,那么从机能够持续提供服务,
当主机中没有从机时,则向其它主机借用多余的从机.持续提供服务.如果主机宕机时没有从机可用,则集群解体.
答案:9个redis节点,节点宕机5-7次时集群才解体.
如图所示:
![Image \[2\].png](/img/bVcKVlN)
13.Redis hash槽存储数据原理
阐明: RedisCluster采纳此分区,所有的键依据哈希函数(CRC16[key]%16384)映射到0-16383槽内,共16384个槽位,每个节点保护局部槽及槽所映射的键值数据.依据主节点的个数,平衡划分区间.
算法:哈希函数: Hash()=CRC16[key]%16384
如图所示
![Image \[3\].png](/img/bVbnUhA)
当向redis集群中插入数据时,首先将key进行计算.之后将计算结果匹配到具体的某一个槽的区间内,之后再将数据set到治理该槽的节点中.
如图所示
![Image \[4\].png](/img/bVcKVlO)

Redis集群搭建问题阐明

1.首先敞开所有的Redis服务器

2.查看配置文件编辑是否正确.
3.删除多余的配置文件

4.重启redis服务器

5.搭建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

集群入门案例

@Testpublic 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("jedis", "集群赋值");    System.out.println(jedisCluster.get("jedis"));}

对于选举机制-脑裂景象

阐明: 当集群进行选举时,如果间断3次都呈现了平票的后果的则可能呈现脑裂的景象.
问题: 呈现脑裂景象的概率是多少??? 1/8

数学建模:
抛银币间断3次呈现平票的概念是多少? 1/8=12.5%
第一次: 正正 正反 反正 反反 1/2
第二次: 正正 正反 反正 反反 1/2
第三次: 正正 正反 反正 反反 1/2
预防: 减少主节点的数量能够无效的升高脑裂景象的产生.

面试题

1.redis集群中一共能够存储16384个KEY? 不对的
答: 16384只是槽位的数量 只负责布局这个数据归谁治理的问题.至于数据如何存储,是由redis内存决定的.
hash(key1) = 3000,
hash(key2) = 3000;

2.Redis集群中最多能够有多少台主机? 16384台主机.

3.Redis中如果遇到多线程操作,是否有线程安全性问题 ? 没有
因为:redis服务器是单过程单线程操作. 每次操作都是由一个线程执行,所以不会有线程安全性问题.

4.Redis如何实现内存数据的优化? LRU/LFU/随机算法/TTL

SpringBoot整合Redis集群

编辑properties文件

阐明:将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集群配置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

编辑配置类

@Configuration //标识我是配置类@PropertySource("classpath:/properties/redis.properties")public class RedisConfig {    /*redis集群*/    @Value("${redis.nodes}")    private String nodes; //node,node,node    @Bean    public JedisCluster jedisCluster(){        Set<HostAndPort> cluster=new HashSet<>();        String[] nodeArray = nodes.split(",");        for (String node :nodeArray){//host port            String host=node.split(":")[0];            int port=Integer.parseInt(node.split(":")[1]);            cluster.add(new HostAndPort(host,port));        }        return new JedisCluster(cluster);    }}

编辑AOP配置

在AOP中注入Redis缓存对象

@Aspect //标识我是一个切面@Component //交给spring容器治理public class CacheAOP {    @Autowired    private JedisCluster jedis; //实现集群对象的注入    //private JedisSentinelPool jedisSentinelPool;//单台哨兵    //private ShardedJedis jedis;//切换成分片redis    //private Jedis jedis;

对于京淘我的项目后盾阐明

知识点概括:

1.框架增强阶段
1.1SpringBoot 各个配置文件的阐明 pom.xml配置 罕用注解 springboot启动执行的流程
1.2 对于SpringBoot常见用法 属性赋值 @Value , 开发环境优化 ,配置文件引入 ,整合Mybatis , 整合MybatisPlus ,整合web资源(JSP)
1.3京淘后盾我的项目搭建
1.3.1分布式思维 依照模块/ 依照层级拆分
1.3.2 聚合工程创立的思路 父级我的项目 对立治理jar包 ,工具API我的项目, 业务性能零碎
1.4 UI工具 前端与后端进行数据交互时 如果想要展示特定的格局构造,则必须依照要求返回VO对象.
1.5 JSON构造模式 1.Object类型 2.Array类型 3. 简单类型(能够进行有限层级的嵌套)
1.6 后盾商品/商品分类的CURD操作.
1.7 引入富文本编辑器 /实现文件上传业务.
1.8 反向代理/正向代理
1.9 NGINX 实现图片回显, NGINX装置/命令/过程项阐明/域名的代理/负载平衡机制/相干属性阐明
1.10 windows tomcat服务器集群部署.

2.Linux学习
2.1 什么是VM虚拟机. 网络配置阐明 桥接/NAT模式
2.2 介绍Linux倒退, 介绍Linux根本命令 装置Linux JDK tomcatLinux部署. Linux装置Mysql数据
2.3 Linux装置Nginx服务器. 整个我的项目Linux部署.

3.我的项目实在部署
3.1 实现数据的读写拆散/负载平衡/数据库高可用 mycat
3.2 Redis 命令/redis单台操作/redis分片/redis哨兵/redis集群/
3.3 AOP相干常识.