redis缓存

redis是一个高性能的key-value数据库,支持内存高速缓存

我们可以用其来存储键值对数据,当然因为redis的高性能的键值对存储特性,我们也常常用其来实现应用的缓存功能

为什么Redis缓存速度这么快

首先介绍一下硬盘数据库和Redis的工作模式

硬盘数据库的工作模式:

在这里插入图片描述

需要先从数据读取数据到内存,内存中的数据保存到硬盘,我们更改硬盘的数据后在保存到数据库。这里的步骤较多,而且还占用我们的硬盘容量。

内存数据库的工作模式:

在这里插入图片描述

这种方式相比硬盘数据库的方式少了内存到硬盘这一步,速度回快很多,而且不占用我们的硬盘容量,Redis就是基于这种方式的

Redis为什么这么快

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4、使用多路I/O复用模型,非阻塞IO;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

注意:这里我们一直在强调的单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的,这里需要大家明确的注意一下!例如Redis进行持久化的时候会以子进程或者子线程的方式执行

为什么需要缓存

当我们调用一个方法的时候如果数据没有发生实质变化,我们应该避免直接连接数据库,而是应该去内存中读取数据,这样就打打降低了数据库的读写次数,而且从内存中读数据的速度要比从数据库查询要快很多

如何使用Redis实现缓存

1.需要加上springboot的redis jar包

2.创建一个redis连接工厂(Redis连接工厂会生成到Redis数据库服务器的连接)

3.使用工厂获取一个redis连接,向redis中读取存入数据

Redis操作模板类

上面我们发现每次添加的key和value都是byte数组类型(使用很麻烦),于是spring为我们带来了redis template(模版)

//创建一个模板类 RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); 
//将刚才的redis连接工厂设置到模板类中 template.setConnectionFactory(factory);

数据

spring data redis提供多个序列化器,当保存一条数据的时候,会序列化成json数据,取出来的时候被序列化成对象

Jackson2JsonRedisSerializer:使用Jackson 2,将对象序列化为JSON;
JdkSerializationRedisSerializer:使用Java序列化;

springboot缓存某个方法

在某些时候,我们可能有这样的需求,用户登录的时候,我们会从数据库中读取用户所有的权限,部门等信息。而且每次刷新页面都需要判断该用户有没有这个权限,如果不停的从数据库中读并且计算,是非常耗性能的,所以我们这个时候就要用到了springboot为我们带来的缓存管理器

缓存管理器

要使用缓存首先我们需要加上@EnableCaching这个注解,这个注解会被spring发现,spring会创建一个切面并触发Spring缓存, 根据所使用的注解以及缓存的状态, 这个切面会从缓存中获取数据, 将数据添加到缓存之中或者从缓存中移除某个值

接下来我们需要申明一个缓存管理器RedisCacheManager ,这个bean的作用是在新增缓存或者删除缓存的时候会调用这个缓存管理器的方法

添加缓存:

@RequestMapping("/getPrud")
@Caheable("prudCache")
public Pruduct getPrud(@RequestParam(required=true)String id){

System.out.println("如果第二次没有走到这里说明缓存被添加了");
return pruductDao.getPrud(Integer.parseInt(id));

}

打开redis的客户端发现redis对应的key就是我们的参数1,这个时候就会出问题,比如说我在其他要缓存的方法的参数也是1,就会重复。因此我们常常会自定义这个key的值

除了@Cacheable添加缓存外,springboot还为我们带了了其他几个注解

删除缓存

在delete的时候用@CacheEvict清除这条缓存

@RequestMapping("/deletePrud") @CacheEvict("pruddeleteCache") public String deletePrud(@RequestParam(required=true)String id){ return "SUCCESS"; }

自定义key

@Cacheable和@CachePut都有一个名为key属性,这个属性能够替换默认的key,它是通过一个表达式(Spel表达式)计算得到的

例如下面的就是将返回对象的id当作key来存储(但是Pruduct的id是int类型,所以需要将数字转化成String类型)

@RequestMapping("/savePrud")
@CachePut(value="prudsaveCache",key="#result.id +''")
public Pruduct savePrud(Pruduct prud){ return prud;

}

#result是代表函数的返回值,当然还会有其他的一些元数据

条件化缓存

通过为方法添加Spring的缓存注解,Spring就会围绕着这个方法创建一个缓存切面。但是,在有些场景下我们可能希望将缓存功能关闭

@Cacheable和@CachePut提供了两个属性用以实现条件化缓存:unless和condition,这两个属性都接受一个SpEL表达式。

如果unless属性的SpEL表达式计算结果为true,那么缓存方法返回的数据就不会放到缓存中。与之类似,如果condition属性的SpEL表达式计算结果为false,那么对于这个方法缓存就会被禁用掉

这两个属性的区别是如果condition的表达式计算结果为false,那么在这个方法调用的过程中,缓存是被禁用的。就是说,不会去缓存进行查找,同时返回值也不会放进缓存中。但是unless依然会去缓存中进行查找,如果找到了匹配的值,就会返回找到的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值