springboot-分布式实例开发 (八)-Redis(续)


上一节使用redis实现了缓存存放。那有一个问题。缓存的数据难道一直存在吗?若进程退出造成数据丢失怎么办?若redis服务器出现宕机,数据丢失怎么办呢?
首先了解一下。由于Redis是一种内存型数据库,即服务器在运行时,系统为其分配了一部分内存存储数据,一旦服务器挂了,或者突然宕机了,那么数据库里面的数据将会丢失,为了使服务器即使突然关机也能保存数据,那该如何实现呢?
持久化这个概念就因此出现了。

1 Redis持久化

1.1 持久化概念

持久化是将程序数据在持久状态和瞬时状态间转换的机制。对于程序来说,程序运行中数据是在内存的,若没有及时同步写入到磁盘,那么一旦服务器宕机或者程序突然奔溃,数据就会丢失,只有把数据及时同步到磁盘,数据才能永久保存,不会因为宕机影响数据的有效性。而持久化就是将数据从程序同步到磁盘的一个动作过程。
在这里插入图片描述

1.2 redis持久化方式

redis持久化有俩种方式。

1.2.1RDB模式

此方式是一种快照的方式。会根据某个时间点去保存当前时间下的全量数据的快照,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。
说明:

  1. RDB模式是redis默认的持久化策略
  2. RDB模式能够定期实现内存数据持久化(可能会丢失数据)
  3. RDB模式每次操作时记录内存数据的快照.持久化文件较小.
  4. RDB模式持久化效率高.
  5. RDB模式操作是同步的.
    此模式一共有save、bgsave、自动化三种触发机制。简单说一下三者的区别
    1.save
    此方式是需要手动触发。该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。当客户达到一定量的话,此方式对不可取。

2.bgsave
此方式是需要手动触发。执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。
3.自动
此方式是通过配置文件的方式实现redis自动完成数据的持久化。这也是目前用的最多的方式
开始配置
在这里插入图片描述

save 900 1      在900秒内用户执行1次set操作时持久化一次
save 300 10	   3000秒内执行10次set操作 持久化一次
save 60 10000   60秒内执行10000次set操作时 持久化一次
save 1 1         该配置虽然能够保证数据持久化但是效率低.因为该操作是阻塞的

修改持久化文件名称
在这里插入图片描述
持久化文件保存的路径 ,当redis启动时,在程序执行的当前目录中生成持久化文件
在这里插入图片描述

1.2.2 AOF模式

AOF(Append-Only-File)持久化:保存写状态。
通俗的讲就是,它记录了查询以外的所有变更数据库状态的指令。每一次的变更操作都会记录。这样的记录方式也会造成持久化文件变大。
为了压缩aof的持久化文件。因此redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。
重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
简单说明::

  1. AOF模式是对RDB模式的补充.可以实现数据的实时持久化.
  2. AOF模式默认是关闭的.需要手动开启.
  3. AOF模式记录的是用户的操作过程.会有大量的持久化文件生成.数据恢复时效率低. 需要定期维护持久化文件
  4. AOF的优先级高于RDB模式.2个文件同时开启时以AOF文件为准.
  5. AOF模式异步操作.

配置如下

  1. 开启AOF模式
    在这里插入图片描述
    我们看一下AOF持久化策略
    在这里插入图片描述
#appendfsync always   	实现实时持久化  性能低
appendfsync everysec 	每秒持久化		 性能略低于RDB模式
#appendfsync no			交给操作系统完成.15-20 持久化操作.

2.Redis过期策略

我们在存储缓存的时候是可以指定过期时间。redis会根据你设置的过期时间进行清除。那Redis是如何清除的呢?
共有三种过期策略:

  1. 定时过期:每个设置过期时间的key会创建一个定时器,到过期时间立即清除。该策略可以立即清除过期的数据;一旦过期数据很多时会占用大量的CPU资源去处理过期的数据,影响了缓存的响应时间和吞吐量。
  2. 惰性过期:只有客户端访问key时,redis才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。有个极端情况:大量的过期key没有再次被访问,就不会被清除,从而占用大量内存。
  3. 定期过期:每隔一定时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

Redis中同时使用了惰性过期和定期过期两种过期策略。
但又暴露了一个问题 如果定期删除漏掉了很多过期 key,若没及时去查,也就没走惰性删除,此时会造成大量过期 key 堆积在内存里,可能就会造成内存被无故占用,咋整?
那就走redis的缓存淘汰机制

3. Redis 缓存淘汰策略

LRU算法
LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
LFU算法
LFU(least frequently used (LFU) page-replacement algorithm)算法是redis5以后才提出的.算法是根据使用次数最少的优先删除
根据算法共包含了以下几种方式
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 不删除内存数据,如果内存溢出报错返回.

查看redis配置文件 默认是不删除内存。
在这里插入图片描述
将其改为第一种方式
在这里插入图片描述
既然这里涉及了根据超时时间进行删除。
上面是通过配置的方式让redis自动完成缓存的清除计划

4. 项目实战

在项目中其实很简单。只要连接好了,设置过期时间就可以。
再来看一下自定义注解
在这里插入图片描述我们可以看到里面有俩个变量。分别是key , seconds 。key是缓存的键值。seconds是过期时间。
我们看一下aop是如何使用的
在这里插入图片描述我们可以看到@Around注解中还有一个注解@annotation。此注解就是来获取自定义注解的。
里面的值需要和方法的参数名一样。才可以完成映射。
我们再看加注解的方法。
在这里插入图片描述在注解中直接给变量赋值即可。jedis设置的过期时间是以为单位。
我们这里设置了60秒。验证一下是否60秒后自动删除。
重启服务,并清除原有的缓存。这里还是使用RedisDesktopManager操作。方便啊
在这里插入图片描述点击新增商品,并选择类目。然后查看缓存。我截图的时候已经过了20秒了。不断双击这个键值。会看到时间在减少。
在这里插入图片描述等过完一分钟后,再点击此键值。会提示已经不存在了。
在这里插入图片描述
试验成功。我设置的默认时间是0.表示不过期。我们可以根据实际需求。去设置一下默认值。这样不用每次指定一个值了。

5.其他操作

上面我们可以看到我们只是在查询的时候调用缓存啥的。若我们在没过期期间对字典进行改变了呢。又如何实现数据同步呢?
其实很简单。我们也是可以通过aop的方式自定义注解。写一个aop方法 :保存数据时,拦截操作,进行缓存删除,重新将新数据放在缓存中。

github地址

https://github.com/lmy1965673628/jingtao.git

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值