日志

Redis 三大缓存

 来源    2020-09-16    0  

Redis 三大缓存

     过去的有些事情不一定要忘记,但一定要放下。

背景:Redis 三大缓存:缓存穿透、缓存击穿、缓存雪崩,是Redis 面试必须要掌握的东西。

一、缓存穿透

1.概念简述

缓存穿透是指当用户在查询一条数据时,而此时数据库缓存却没有关于这条数据的任何记录;而该数据若在缓存中没找到则会向数据库请求获取数据,Redis 拿不到数据时,就会一直查询数据库,这样会对数据库的访问造成很大的压力。

2.案例

用户查询一个 id = -1 的商品信息,但是数据库 id 自增是从 1 开始的,很明显这条信息是不在数据库中,当没有信息返回时,Redis 会一直向数据库查询,给当前数据库访问造成很大的压力。

3.解决方案

A、从缓存出发,给缓存设置一个 如果当前数据库不存在 的信息,把它缓存为一个空对象,返回给用户;

B、缓存空对象的解决方案代码简单,但效果不是很好;可以考虑使用Redis 提供的布隆过滤器。

Redis 布隆过滤器代码:


package com.ausclouds.bdbsec.tjt;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

import java.nio.charset.Charset;

/**
 * Redis 布隆过滤器
 * 引入依赖:
 * <dependency>
 *     <groupId>com.google.guava</groupId>
 *     <artifactId>guava</artifactId>
 *     <version>22.0</version>
 * </dependency>
 */
public class BloomFilterDemon {

    // initial_size: 表示预计放入的元素数量,当实际数量超出这个数值时,误判率会上升
    private static long initial_size = 1000000;

    // error_rate: 错误率
    private static double error_rate = 0.0001;

    public static void main(String[] args) {
        BloomFilter<String> bloomFilter =
                BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), initial_size, error_rate);
        bloomFilter.put("what");
        boolean isContain = bloomFilter.mightContain("what");

    }


}

View Code~拍一拍小轮胎

 缓存空对象流程图

二、缓存击穿

1.概念简述

缓存击穿是指有某个key 经常被查询,或者某个key 不经常被访问,而这个时候,若该key 在缓存的过期时间失效或者是个冷门key 的时候,突然有大量关于这个key 的访问请求,这样就会导致大并发请求直接穿透缓存,请求数据库,瞬间增大了数据库的访问压力。

2.案例

(1)一个“冷门”key,突然被大量用户请求访问;

(2)一个“热门”key,在缓存中时间恰好过期,这时有大量用户来进行访问。

缓存击穿案例图

3.解决方案

对于缓存击穿问题,常用的解决方案是加锁;对于key 过期问题,当key 要查询数据库的时候加上锁,保证只能让第一个请求进行查询数据库操作,然后把从数据库中查询到的值存储到缓存中,对于剩下的相同的key,则可直接从缓存中获取。

缓存击穿解决方案图

三、缓存雪崩

1.概念简述

缓存雪崩是指在某一个时间段内,缓存集中过期失效,若这个时间段内有大量请求,并且查询数据量巨大,所有的请求都会查询数据库,使数据库的调用瞬间量剧增,引起数据库压力过大甚至宕机。(Redis 突然宕机或大部分数据失效)

2.案例

某宝双十一购物节,在 23:00-24:00 举行商品促销活动。开发人员是这么设计的:在 23:00 把商家促销的商品放到缓存中,并通过redis 的expire 设置了过期时间为1小时;这个时间段许多用户在访问这些商品信息,但是刚好到了24:00点的时候,恰好还有许多用户在访问这些商品,此时对这些商品的访问都会转到数据库上,导致数据库压力突然剧增,甚至直接宕机。

3.解决方案

A、限流降级

在缓存失效后,通过加锁或者队列来控制读数据库写缓存和写缓存的线程数量,对某个key 同一时刻只允许一个线程执行查询设计和写缓存操作。

B、Redis 高可用

可能会出现Redis 挂掉的情况,多增加几台Redis 实例(一主多从),即使一台挂掉之后其他的还可以继续工作。

C、不同过期时间

设置不同的过期时间,让缓存失效的时间尽量均匀,避免同一时间大量缓存失效。

D、数据预加热

数据加热的含义就是在正式部署之前,先把可能用到的数据预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中;一般可以在即将发生大并发访问前手动触发加载缓存不同的key。

过去的有些事情不一定要忘记

但一定要放下

相关文章
node.js – MongoDB和Redis作为缓存层架构
问答假设我们有一个社交网络应用程序(使用NodeJS,Express)和MongoDB作为主数据库引擎. 在大多数来自客户端的API调用(移动应用程序,Web应用程序等)中,我不想为每个请求进行复杂的查询 ...
1
Symfony 3:使用Redis配置缓存组件池
问答我想使用新的Cache Component在Redis中存储数据. 我想配置具有不同生命周期数据的池. 现在,我配置: framework: cache: app: cache.adapter.red ...
1
缓存 – Redis只是缓存吗?
问答我一直在读一些Redis文档,并尝试在http://try.redis-db.com/的教程.到目前为止,我看不到Redis和缓存技术,如Velocity或企业库缓存框架之间的任何区别 你实际上只是使 ...
排序 – 在Redis中缓存可排序/可过滤的数据
问答我有一些我已经在标准Redis hashmap中缓存的数据,而且我遇到了需要响应客户端订购和过滤请求的情况.名称,平均评分和评论数量的订单排名可以定期更改(可能每分钟多次).任何人都可以建议我采取适当 ...
java – Web服务体系结构:Redis(作为缓存)和PostgreSQL用于持久化
问答我正在开发一个使用postgreSQL数据库中的客户端数据的Java REST API. 数字: .一开始大约有600个客户 .他们中的一些人每隔几秒就做一次请求 由于客户按要求付费,我们需要控制成功 ...
1
缓存 – ArangoDb作为redis的缓存服务器替代方案
问答我计划使用arangodb作为我的后端存储.我想知道arango db作为缓存服务与aerospike和redis相比有多高效.有没有人在功能和性能方面尝试比较作为缓存系统.它将帮助我减少从后端堆栈使 ...
2
MongoDB应该使用Memcache还是Redis进行缓存?
问答我使用MongoLab作为托管的MongoDB, 使用Memcache或Redis缓存响应是否有意义? 我读到了使用Redis作为缓存的常见问题,但另一方面,我读到如果没有分页MongoDB,Mong ...
1
Redis的缓存策略和主键失效机制
日志作为缓存系统都要定期清理无效数据,就需要一个主键失效和淘汰策略. 1.EXPIRE主键失效机制 在Redis当中,有生存期的key被称为volatile,在创建缓存时,要为给定的key设置生存期,当k ...
3
SpringBoot之Mybatis操作中使用Redis做缓存
日志上一博客学习了SpringBoot集成Redis,今天这篇博客学习下Mybatis操作中使用Redis做缓存.这里其实主要学习几个注解:@CachePut.@Cacheable.@CacheEvict ...
1
Java系统高并发之Redis后端缓存优化
日志一:前端优化 暴露接口,按钮防重复(点击一次按钮后就变成禁用,禁止重复提交) 采用CDN存储静态化的页面和一些静态资源(css,js等) 二:Redis后端缓存优化 Redis 是完全开源免费的,遵守 ...
1
原 Spring AOP实现对Redis的缓存同步
日志    前言:刚开始采用spring cache作为缓存数据,到后面发现扩展性不灵活,于是基于sprig cache原理自定义一套规则用于缓存数据. 请求过程: 根据请求参数生成Key,后面我们会对生 ...
1
Java中如何使用Redis做缓存
日志基本功能测试 1.程序基本结构 2.主要类 1)功能类 package com.redis; import java.util.ArrayList; import java.util.Iterator ...
组件-------(一)redis系列--安装部署redis+实现redis分布式缓存 java+Spring+redis
日志目的:解决单机session不能共享问题,插入查询数据库时间效率问题,实现分布式缓存. 准备材料:Redis 下载链接 http://pan.baidu.com/s/1dEGTxvV 相关jar包如果 ...
mybatis-自定义缓存-redis二级缓存
日志在mybatis一级缓存二级缓存中已经介绍过了二级缓存的大致原理.下面我们用redis来实现一下二级缓存.环境是springmvc+mybatis+redis 步骤一.引入redis相关的maven依 ...
1
springboot+redis实现缓存数据
日志在当前互联网环境下,缓存随处可见,利用缓存可以很好的提升系统性能,特别是对于查询操作,可以有效的减少数据库压力,Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存 ...
2
spring配置redis注解缓存
日志前几天在spring整合Redis的时候使用了手动的方式,也就是可以手动的向redis添加缓存与清除缓存,参考:https://www.cnblogs.com/qlqwjy/p/8562703.htm ...
1
spring+redis的集成,redis做缓存
日志1.前言        Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.我们都知道,在日常的应用中,数据库瓶颈 ...
1
SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache实现二级缓存、利用SpringCache和Redis作为缓存
日志1 环境说明 JDK: 1.8 MAVEN: 3. SpringBoot: 2.0.4 2 SpringBoot集成Mybatis-Plus 2.1 创建SpringBoot 利用IDEA创建Spri ...
2
Spring Boot 整合 Redis 实现缓存操作
日志本文提纲 一.缓存的应用场景 二.更新缓存的策略 三.运行 springboot-mybatis-redis 工程案例 四.springboot-mybatis-redis 工程代码配置详解 运行环境 ...
1
Springboot2.x使用redis作为缓存
日志一.Springboot2.x关于配置redis作为缓存. 基本配置如下: (1)在application.properties文件中 spring.redis.database=2 //第几个数据库 ...