【Redis】redis缓存击穿,缓存雪崩,缓存穿透

news2024/11/21 18:48:51

一、什么是缓存?

        缓存就是与数据交互中的缓冲区,它一般存储在内存中且读写效率高,提高响应时间提高并发性能,如果访问数据的话可以先访问缓存,避免数据查询直接操作数据库,造成后端压力过大。

        但是可能会面临数据不一致问题,比如访问数据时拿到的是缓存中的数据,但是实际上数据库此时已经改变了,那么拿到的缓存中拿到数据与数据库中数据会有不一致的问题。解决数据一致性问题会要进行代码操作,增加代码维护成本,如果使用redis还会有运维成本。

二、怎么用redis实现缓存?

        实际上就是把redis作用在客户端与数据库中间,充当缓冲区作为缓存。我们一般把一些经常访问,但是变化不大的数据放入缓存区,因为访问量大对磁盘IO次数多性能消耗大,如果作用与缓存区那么存储效率会快,第二是对于变化不大的数据,对于读写不一致问题问题出现概率较小。 

         大概流程就是我们要获取数据的时候先操作缓存,如果在缓存redis中查不到数据就访问数据库,如果查到了就将数据写入缓存中,并且返回给客户端。

        在Java中可以使用RedisTemplate类进行操作redis数据库,里面封装了很多方法可供使用,但是它默认使用的jdk 的序列号工具,将数据序列话后是2进制,为了方便操作数据,我们可以手动将它的序列号工具用第三方例如jackson的将数据序列化为json格式。

三、缓存更新策略

        缓存更新策略有三种,内存淘汰、超时剔除、主动更新。

        内存淘汰它是指redis内存不足后它会自动清理一些内存,在清理掉这些内存后,如果再查询对应的数据它在redis中查不到就会去数据库中查返回给客户端,并且把数据写入Redis中,完成缓存更新策略。它是默认开启,一致性较差。

        超时淘汰指的是给数据设置超时时间,如果对应超过了对应的时间则将缓存清理,这种一般作为主动剔除的保底策略。主动更新是主动将数据从redis中剔除,这种方式面对与要求数据一致性较强的操作。

        主动更新策略

                1.cache aside pattern

                        由缓存调用者在更新数据库时同时更新缓存

        操作缓存和数据库中,我们应该删除操作,还是更新缓存?

        答:应该选择删除缓存,如果使用更新缓存,每次更新数据库都更新缓存,如果几乎不查询数据库,那么根本没必要使用缓存更新策略,使用缓存就是优化查询的速度。所以使用删除缓存模式,等下次进行查询数据库的时候再把缓存写入redis中,避免无用的写操作。

        如何保证缓存与数据库操作同时成功或失败?

        答:单体系统放在一个事务里,分布式服务理由TCC等分布式事务解决。

        先删除缓存,再操作数据库 还是先操作数据库再删除缓存?

        答:正常线程1删除缓存,然后更新数据库信息。但是由于多线程情况下,线程1更新数据库的过程中比较慢,突然中间插入了一个线程操作,线程2进行查询值,由于此时线程1已经将数据删除,所以缓存未命中于是查询数据库,查到了然后将数据写入缓存中。但是此时更新 数据库操作完成了,就造成缓存中的数据是10,但是数据库的值为20,缓存与数据库。

        先操作数据库再删除缓存

        答:正常情况是更新数据库,然后更新缓存。但是线程2之前有一个线程1进来查数据,并且此时缓存失效了,就会线程1进行查数据库发现数据是10。然后线程2要进行更新数据删除缓存操作,此时将数据库数据为20。然后线程一会将之前查出的数据10写入缓存中。这个概率比先删除再更新概率要低很多,首先是在缓存失效后有一个线程要进行查数据,然后紧接着有个线程要进行修改数据,并且写入的速度是比更新的速度快的,写入有几微秒,但是更新要比写入要慢一些,也就是说在几微妙下,线程2更新删除操作必须立刻完成,所以这种概率比较小。

                 2.read/write through pattern

                        缓存与数据库作为一种整体,由服务器管理数据一致性,无需调用者关系一直性问题。最大的问题是维护它是比较复杂的。调用者不知道操作的数据库还是缓存。

                3.write behind caching pattern

                        调用者也是无需关系数据一致性,但是它只读取缓存,由一个线程异步将缓存和数据库进行操作,一定时间将缓存数据写入数据库中。一致性和可靠性可能存在问题。

        对于数据库和缓存直接的数据一致性问题,可以使用canal,让他伪装成一个数据库的从节点,在主节点配置信息后,再从节点使用canal配置主节点的端口,ip等,然后再Java中引入canal的包,之后配置canal配置名字,ip,通过注解CanalTable监听表,如果改变了就将数据同步到redis中。 

四、缓存穿透

        缓存穿透指的是在数据库中和缓存中都没有的情况下进行查询操作。

                        1.缓存空对象解决缓存穿透,查询缓存如果为空查询数据库也为空,如果不断查询数据库会对数据库造成巨大的查询压力,所以可以设置一个缓存,key对应查询的对象,值为null。但是如果有可能此时数据库添加了该值,但是缓存还是之前的null值,此时可以设置个过期时间,或者插入数据库的时候查有没有缓存有的话删除就可以了,可能会造成短期数据不一致问题。

                        2.使用布隆过滤器解决缓存穿透

                 将数据库的数据根据hash算法,然后转换存2进制位存入布隆过滤器,然后如果有数据进来后,通过相同的算法进行与 布隆过滤器里的值进行比对,如果对应位有该数据说明该值有一定可能存在,如果布隆过滤器不存在说明值真不存在。内存占用特别小,实现复杂,存在误判的可能。

五、缓存雪崩

        缓存雪崩指的是同一时间大量数据同时失效或者redis宕机, 大量数据雪崩打入数据库中。

        解决方案:

                给缓存设置ttl设置随机值,防止缓存同时失效。

                确保redis高可用性,主从机制,当主宕机了从服务器可以挑选从节点作为主。

                限流降级sentinel,或者设置多级缓存

六、缓存击穿

         大量数据打进来,然后缓存数据失效需要重建的过程,再次过程中时间比较长,后面的数据继续访问需要先查缓存,此时缓存为建立,然后会查询数据库,不断的访问对数据库有巨大的冲击。

        结局方案 :1.互斥锁,2.逻辑过期

                1.互斥锁是如果缓存查询不到就操作数据库,在操作数据库操作重建缓存的过程完成后释放锁,其他线程在查不到缓存后会操作数据库前也需要获取锁。所以并发性能差,实现简单。

                2.逻辑过期指的是在查询缓存后发现逻辑过期也就是失效了,然后加互斥锁,此时开辟一个新的线程查询数据库更新缓存逻辑过期时间,然后返回旧缓存值。如果新的线程真的更新完毕了那么才会释放锁,在这期间如果其他线程进来查缓存失效了那么就会访问数据库发现互斥锁没释释放,说明此时新线程没有重建缓存完毕,那么会直接返回过期的旧缓存值。这样可以增加并发性,但是数据一致性较差,实现复杂,性能消耗大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux复习5:C prog

编辑 缩排 为了使C源代码更加整洁易读,可以使用一些工具来自动格式化代码,例如cb(C程序美化器)、bcpp(C美化器)和indent等。 编译 编译并链接C文件 gcc hello.c -o hello 将 hello.c 编译并链接成可执行文…

uni-app快速入门(十)--常用内置组件(下)

本文介绍uni-app的textarea多行文本框组件、web-view组件、image图片组件、switch开关组件、audio音频组件、video视频组件。 一、textarea多行文本框组件 textarea组件在HTML 中相信大家非常熟悉,组件的官方介绍见: textarea | uni-app官网uni-app,un…

世界坐标系、相机坐标系、图像物理坐标系、像素平面坐标系

坐标系及其转换在计算机视觉领域占据核心地位。理解如何从一个坐标系转换到另一个坐标系,不仅是理论上的需要,也是实际应用中不可或缺的技能。 一、世界坐标系的定义 世界坐标系是一个全局的坐标系统,用于定义场景中物体的位置。在这个坐标…

机器学习笔记——聚类算法(Kmeans、GMM-使用EM优化)

本笔记介绍机器学习中常见的聚类算法(Kmeans、GMM-使用EM优化)。 文章目录 聚类K-Means工作原理特点 K-Medoids工作原理特点 Mini-Batch K-Means工作原理特点 K-Means(重要)工作原理特点 总结K的选值1. 肘部法则(Elbow…

浅议Flink中的通讯工具: Akka

在Flink中,各个组件之间需要频繁交换数据和控制信息。Flink选择了基于Actor模型的Akka框架作为通信基础。 Akka是什么 Actor模型 Actor模型是用于单个进程中并发的场景。 在Actor模型中: ActorSystem负责管理actor生命周期 将每个实体视为独立的 Ac…

如何在react中使用react-monaco-editor渲染出一个编辑器

一、效果展示 二、基于vite配置 1.首先安装react-monaco-editor和monaco-editor包 npm add react-monaco-editor npm i monaco-editor 2.其次创建一个单独的文件(此处是tsx、直接用app或者jsx也行) import { useState, useEffect } from react impo…

孙玲:从流水线工人到谷歌程序员

这是《开发者说》的第24期,本期我们邀请的开发者是孙玲,她出生于湖南娄底一个贫穷的农村家庭,2009年高考落榜,她去了深圳一家电子厂,在流水线上给电池喷码,每天12个小时轮班,月薪2300&#xff0…

kali搭建pikachu靶场

前言: 总所周知搭个网站需要有apachemysqlphp,Apache是一个开源的Web服务器软件, MySQL是一种关系型数据库管理系统(数据库),PHP是一种在服务器上执行的脚本语言 文章内容来自:【黑帽编程与攻…

android 使用MediaPlayer实现音乐播放--获取音乐数据

前面已经添加了权限&#xff0c;有权限后可以去数据库读取音乐文件&#xff0c;一般可以获取全部音乐、专辑、歌手、流派等。 1. 获取全部音乐数据 class MusicHelper {companion object {SuppressLint("Range")fun getMusic(context: Context): MutableList<Mu…

VMware Workstation 17.6.1

概述 目前 VMware Workstation Pro 发布了最新版 v17.6.1&#xff1a; 本月11号官宣&#xff1a;针对所有人免费提供&#xff0c;包括商业、教育和个人用户。 使用说明 软件安装 获取安装包后&#xff0c;双击默认安装即可&#xff1a; 一路单击下一步按钮&#xff1a; 等待…

Methode Electronics EDI 需求分析

Methode Electronics 是一家总部位于美国的全球性技术公司&#xff0c;专注于设计和制造用于多个行业的电子和电气组件&#xff0c;产品涵盖汽车、工业、电信、医疗设备以及消费电子等多个领域&#xff0c;提供创新的解决方案。 填写Methode_EDI_Parameters_Template Methode_…

uniapp自动注册机制:easycom

传统 Vue 项目中&#xff0c;我们需要注册、导入组件之后才能使用组件。 uniapp 框架提供了一种组件自动注册机制&#xff0c;只要你在 components 文件夹下新建的组件满足 /components/组件名/组件名.vue 的命名规范&#xff0c;就能直接使用。 注意&#xff1a;组件的文件夹…

【Vue】Vue3.0(二十六)Vue3.0中的作用域插槽

上篇文章 【Vue】Vue3.0&#xff08;二十五&#xff09;Vue3.0中的具名插槽 的概念和使用场景 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Vue专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月20日17点30分 文章目录 概念使用场景示…

C语言第14节:字符函数和字符串函数

1. 字符分类函数 C语言中有一系列的函数是专门做字符分类的&#xff0c;也就是一个字符是属于什么类型的字符的。这些函数的使用都需要包含一个头文件是<ctype.h> <ctype.h>头文件中的字符分类函数提供了一组用于检查单个字符特性的函数。这些函数接收一个字符&a…

IDEA怎么定位java类所用maven依赖版本及引用位置

在实际开发中&#xff0c;我们可能会遇到需要搞清楚代码所用依赖版本号及引用位置的场景&#xff0c;便于排查问题&#xff0c;怎么通过IDEA实现呢&#xff1f; 可以在IDEA中打开项目&#xff0c;右键点击maven的pom.xml文件&#xff0c;或者在maven窗口下选中项目&#xff0c;…

使用vscode+expo+Android夜神模拟器运行react-native项目

1.进入夜神模拟器安装路径下的bin目录 2.输入命令&#xff0c;连接Android Studio 启动夜神模拟器后&#xff0c; 打开安装目录的bin文件夹执行下面的命令&#xff0c;只需执行一次&#xff09; nox_adb.exe connect 127.0.0.1:62001adb connect 127.0.0.1:62001 3.运行项目…

IPv6 NDP 记录

NDP&#xff08;Neighbor Discovery Protocol&#xff0c;邻居发现协议&#xff09; 是 IPv6 的一个关键协议&#xff0c;它组合了 IPv4 中的 ARP、ICMP 路由器发现和 ICMP 重定向等协议&#xff0c;并对它们作出了改进。该协议使用 ICMPv6 协议实现&#xff0c;作为 IPv6 的基…

个人全栈开发微信小程序上线了(记日记)

个人开发的全栈项目&#xff0c;《每日记鸭》微信小程序上线了&#xff01; 主要是技术栈&#xff1a;uniapp,koa2,mongodb,langchian&#xff1b; 感兴趣的小伙伴可以来捧捧场&#xff01;

用源码编译虚幻引擎,并打包到安卓平台

用源码编译虚幻引擎&#xff0c;并打包到安卓平台 前往我的博客,获取更优的阅读体验 作业内容: 源码编译UE5.4构建C项目&#xff0c;简单设置打包到安卓平台 编译虚幻 5 前置内容 这里需要将 Epic 账号和 Github 账号绑定&#xff0c;然后加入 Epic 邀请的组织&#xff0c…

如何更改手机GPS定位

你是否曾想过更改手机GPS位置以保护隐私、玩游戏或访问受地理限制的内容&#xff1f;接下来我将向你展示如何使用 MagFone Location Changer 更改手机GPS 位置&#xff01;无论是在玩Pokmon GO游戏、发布社媒贴子&#xff0c;这种方法都快速、简单且有效。 第一步&#xff1a;下…