Redis缓存在Springboot中的使用

目录

一、缓存基础概念

1. 什么是缓存

2. 缓存的优缺点

3. 使用缓存的必要性

二、Redis知识概述

1. Redis是什么?

2. Redis的优缺点,为什么用作缓存

3. Redis 支持的数据类型

4. Redis持久化机制有哪些?

RDB(Redis DataBase):

AOF(Append-only file):

5. 常见问题

1. 缓存穿透

2. 缓存击穿

3. 缓存雪崩

4. 缓存一致性问题

三、SpringBoot整合Redis

1. 使用 Spring data redis

1. 引入redis依赖

2. 项目启动类添加注解

3. 配置Redis数据库

4. 创建配置类

5. 操作Redis

2. 使用 SpringCache 的注解

1. 常用注解

2. 注解参数

3. 自动缓存

四、Redis的高可用方案

1. 主从模式

2. 哨兵模式(sentinel)

3. 集群模式(cluster)


一、缓存基础概念

了解Redis缓存之前,先来了解一下缓存的相关内容

1. 什么是缓存

缓存就是数据交换的缓冲区(称作Cache),是临时存贮数据(使用频繁的数据)的地方。当用户查询数据,首先在缓存中寻找,如果找到了则直接执行;如果找不到则去数据库中查找。

缓存的本质就是用空间换时间,牺牲数据的实时性,以服务器内存中的数据暂时代替从数据库读取最新的数据,减少数据库IO,减轻服务器压力,减少网络延迟,加快页面打开速度。

2. 缓存的优缺点

优点:加快响应速度,减少对数据库的读操作,降低数据库访问压力

缺点:内存的存储容量小。可能出现缓存数据与数据库数据不一致的情况。内存在断电后数据会丢失。

3. 使用缓存的必要性

远端服务器上,客户端请求量大,尤其是大量的读取操作,都需要访问到数据库,给数据库造成较大的压力,自然响应速度会变慢。那么如果把一些热点数据存到内存中,内存的速度很快,可以达到及时响应的目的,同时缓解数据库压力。

缓存本质就是将数据存储在内存中,当数据没有发生本质变化的时候,应尽量避免直接连接数据库进行查询,因为并发高时很可能会将数据库压塌,而是应去缓存中读取数据,只有缓存中未查找到时再去数据库中查询,这样就大大降低了数据库的读写次数,增加系统的性能和能提供的并发量。

二、Redis知识概述

1. Redis是什么?

Redis 是一个高性能的 Key-Value 开源数据库, 是一个非关系型(NoSQL)的数据库,是为了解决高并发、高扩展,大数据存储等一系列的问题而产生的数据库解决方案。但它不能替代关系型数据库,只能作为特定环境下的扩充。常用作缓存使用 (cache)

2. Redis的优缺点,为什么用作缓存

优点:

  • 性能极高:10w次/s的读写速度。
  • 数据持久化:可以将内存中的数据持久化在磁盘中,当宕机或者故障重启时,可以再次加载进如 Redis,从而不会或减少数据的丢失。
  • 丰富的数据类型:Redis 不仅支持简单的 Key/Value 类型的数据,Value数据支持多种类型,String(字符串)、List(列表)、Hash(字典)、Set(集合)、Sorted Set(有序集合)。
  • 支持高可用:Redis 支持 master\slave 主\从机制、sentinel 哨兵模式、cluster 集群模式,保证了 Redis 运行的稳定和高可用性。

缺点:

  • 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写。

  • 适合的场景主要局限在较小数据量的高性能操作和运算上。

3. Redis 支持的数据类型

  • 字符串(string)
  • 哈希表(hash)
  • 列表(list)
  • 集合(set)
  • 有序集合(zset)

应用:

1. 排行榜,利用zset可以方便的实现排序功能;
2. 计数器,利用redis中原子性的自增操作,可以统计到阅读量,点赞量等功能;
3. 简单消息队列,list存储结构,满足先进先出的原则,可以使用lpush/rpop或rpush/lpop;
4. session共享,分布式系统中,可以利用redis实现session共享。spring官方提供的分布式解决方案Spring Session就是利用redis 实现的。

4. Redis持久化机制有哪些?

Redis 提供两种持久化机制: RDB 和 AOF

RDB(Redis DataBase)

在指定的时间间隔内将内存中的数据集快照写入磁盘,恢复时是键快照文件直接读到内存里。

Redis会单独创建(fork)一个子进程进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束后,再用这个临时文件替换上次持久化好的文件。

优点:

  • 只有一个文件 dump.rdb,恢复操作简单

  • 性能较高,fork 子进程进行写操作,主进程继续处理命令

  • 大数据集比 AOF 的恢复效率高

缺点:

  • 数据安全性低,RDB 是每间隔一段时间进行持久化,若期间 redis 发生故障,可能会发生数据丢失

AOF(Append-only file):

指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储,保存为 aof 文件。

这个方法是每执行一条写操作命令,就将该命令以追加的方式写入到 AOF 文件,然后在恢复时,以逐一执行命令的方式来进行数据恢复。

优点:

  • 数据安全,aof 持久化可以配置 appendfsync 属性为 always,记录每个命令操作到 aof 文件中一次;通过 append 模式写文件,即使中途服务器宕机,也可以通过 redis-check-aof 工具解决数据一致性问题

  • AOF 机制的 rewrite 模式,AOF 文件没被 rewrite 之前可以进行处理,如删除文件中的 flushall 命令

缺点:

  • AOF 的持久化文件比 RDB 大,恢复速度慢

如果数据比较重要,使用 AOF 方式备份数据,设置合理的备份频率。

5. 常见问题

1. 缓存穿透

缓存穿透:缓存和数据库中都没有的数据,而用户不断发起请求。 由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决方法:

  • 空值缓存:一种比较简单的解决办法,在第一次查询完不存在的数据后,将该key与对应的空值也放入缓存中,只不过设定为较短的失效时间,例如几分钟,这样则可以应对短时间的大量的该key攻击
  • bloom过滤器(bloom filter):可以用来告诉你 “某样东西一定不存在或者可能存在”。类似于哈希表的一种算法,用所有可能的查询条件生成一个bitarray,在进行数据库查询之前会使用这个bitmap进行过滤,如果不在其中则直接过滤,从而减轻数据库层面的压力。

2. 缓存击穿

缓存击穿: 热点数据缓存失效,流量瞬间直达数据库。缓存击穿实际上是缓存雪崩的一个特例,缓存击穿是指缓存中没有但数据库中有的数据。

解决方法:

  • 设置二级缓存,或者设置热点缓存永不过期,需要根据实际情况进行配置。
  • 通过对应用层加锁,避免所有流量同时访问数据库。使用互斥锁,在执行过程中,如果缓存过期,那么先获取分布式锁,在执行从数据库中加载数据,如果找到数据就存入缓存,没有就继续该有的动作,在这个过程中能保证只有一个线程操作数据库,避免了对数据库的大量请求。

3. 缓存雪崩

缓存雪崩:大量缓存数据在同一时间段失效,缓存服务挂掉或者热点缓存失效,所有请求都去查数据库。

解决方法:

  • 缓存组件设计高可用:缓存高可用是指存储缓存的组件的高可用,能够防止单点故障、机器故障、机房宕机等一系列问题。例如 Redis sentinel 和 Redis Cluster,都实现了高可用。
  • 交错失效时间:设置缓存过期时间一定的随机分布,避免集中在同一时间缓存失效。
  • 请求限流与服务熔断降级机制,限制服务请求次数,当服务不可用时快速熔断降级。

4. 缓存一致性问题

  • 更熟数据库成功 -> 更新缓存失败 -> 数据不一致
  • 更新缓存成功 -> 更新数据库失败 -> 数据不一致
  • 更新数据库成功 -> 淘汰缓存失败 -> 数据不一致

三、SpringBoot整合Redis

1. 使用 Spring data redis

1. 引入redis依赖

在pom.xml文件中引入Redis依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2. 项目启动类添加注解

增加注解@EnableCaching,开启缓存功能

3. 配置Redis数据库

4. 创建配置类

5. 操作Redis

SpringBoot提供了两个bean来操作redis,分别是RedisTemplate 和 StringRedisTemplate,这两者的主要区别如下:

RedisTemplate使用的是JdkSerializationRedisSerializer ,存入数据会将数据先序列化成字节数组然后在存入Redis数据库;

StringRedisTemplate使用的是StringRedisSerializer。

2. 使用 SpringCache 的注解

1. 常用注解

  • @Cacheable: 用于对方法返回结果进行缓存,如果已经存在该缓存,则直接从缓存中获取,缓存的key可以从入参中指定,缓存的 value 为方法返回值。
  • @CachePut: 无论是否存在该缓存,每次都会重新添加缓存,缓存的key可以从入参中指定,缓存的value为方法返回值,常用作于更新。
  • @CacheEvict: 用于清除缓存
     

2. 注解参数

  • value用来指定缓存组件的名字,缓存文件的名称。

  • key缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用Spring表达式语言( spEL 表达式)来编写)。

  • cacheManager可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。

  • condition可以用来指定符合条件的情况下才缓存。

  • unless否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。

  • sync是否使用异步模式。默认是方法执行完,以同步的方式将方法返回的结果存在缓存中。

3. 自动缓存

@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。

如果添加了@Cacheable注解,那么方法被调用后,值会被存入redis,下次再调用的时候会直接从redis中取值返回。

四、Redis的高可用方案

所谓的高可用,也叫HA(High Availability),是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。

如果在实际生产中,如果redis只部署一个节点,当机器故障时,整改服务都不能提供服务了。这就是我们常说的单点故障。如果redis部署了多台,当一台或几台故障时,整个系统依然可以对外提供服务,这样就提高了服务的可用性。

redis高可用有三种模式:主从模式哨兵模式集群模式

1. 主从模式

主要是基于Redis的主从复制特性架构的。通常我们会设置一个主节点,N个从节点;默认情况下,主节点负责处理使用者的IO操作,而从节点则会对主节点的数据进行备份,并且也会对外提供读操作的处理。

特点:

  • 主从模式下,当某一节点损坏时,因为其会将数据备份到其它Redis实例上,这样做在很大程度上可以恢复丢失的数据;
  • 主从模式下,可以保证负载均衡;
  • 主从模式下,主节点和从节点是读写分离的。使用者不仅可以从主节点上读取数据,还可以很方便的从从节点上读取到数据,这在一定程度上缓解了主机的压力;
  • 从节点也是能够支持写入数据的,只不过从从节点写入的数据不会同步到主节点以及其它的从节点下。

优点:​​​​​​​

  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离;
  • 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务依然必须由Master来完成;
  • Master和Slave都是以非阻塞的方式提供服务。

缺点:​​​​​​​​​​​​​​

  • 主从模式下的Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复;
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性;
  • Redis的主节点和从节点中的数据是一样的,降低的内存的可用性。

2. 哨兵模式(sentinel)

是基于主从模式做的一定变化,它能够为Redis提供高可用性。

哨兵模式的核心还是主从复制。只不过相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制——从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个sentinel进程。

sentinel特点:

  • 监控:它会监听主服务器和从服务器之间是否在正常工作。

  • 通知:它能够通过API告诉系统管理员或者程序,集群中某个实例出了问题。

  • 故障转移:它在主节点出了问题的情况下,会在所有的从节点中竞选出一个节点,并将其作为新的主节点。

  • 提供主服务器地址:它还能够向使用者提供当前主节点的地址。这在故障转移后,使用者不用做任何修改就可以知道当前主节点地址。

优点:​​​​​​​

  • 哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
  • 主从可以自动切换,系统更健壮,可用性更高。

缺点:​​​​​​​

  • 具有主从模式的缺点,每台机器上的数据是一样的,内存的可用性较低。
  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

3. 集群模式(cluster)

集群模式,实现了 Redis 的分布式存储,对数据进行分片,也就是说每台主机Redis 节点上存储不同的内容,节点间数据共享,可动态调整数据分布。

Redis Cluster是Redis 3.0以后才正式推出,时间较晚。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot项目使用Redis缓存可以通过以下几个步骤: 1. 添加Redis依赖 在pom.xml添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 配置Redis连接信息 在application.properties添加Redis连接信息: ``` # Redis连接信息 spring.redis.host=localhost spring.redis.port=6379 spring.redis.password= ``` 3. 定义RedisTemplate 在Java代码定义一个RedisTemplate,用于操作Redis缓存: ``` @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } } ``` 4. 使用RedisTemplate操作缓存 使用RedisTemplate可以进行常见的缓存操作,如添加缓存、获取缓存、删除缓存等。例如: ``` @Autowired private RedisTemplate<String, Object> redisTemplate; public void setCache(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public Object getCache(String key) { return redisTemplate.opsForValue().get(key); } public void deleteCache(String key) { redisTemplate.delete(key); } ``` 以上是在Spring Boot项目使用Redis缓存的基本步骤,可以根据实际需求进行扩展和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值