当前位置: 首页 > news >正文

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

一、什么是缓存?

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

        但是可能会面临数据不一致问题,比如访问数据时拿到的是缓存中的数据,但是实际上数据库此时已经改变了,那么拿到的缓存中拿到数据与数据库中数据会有不一致的问题。解决数据一致性问题会要进行代码操作,增加代码维护成本,如果使用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.逻辑过期指的是在查询缓存后发现逻辑过期也就是失效了,然后加互斥锁,此时开辟一个新的线程查询数据库更新缓存逻辑过期时间,然后返回旧缓存值。如果新的线程真的更新完毕了那么才会释放锁,在这期间如果其他线程进来查缓存失效了那么就会访问数据库发现互斥锁没释释放,说明此时新线程没有重建缓存完毕,那么会直接返回过期的旧缓存值。这样可以增加并发性,但是数据一致性较差,实现复杂,性能消耗大。

相关文章:

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

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

HBase Flink操作

Apache Flink 是一个开源的分布式流处理框架,能够高效地处理和分析实时数据流以及批数据。HBase 是一个分布式、面向列的开源数据库,是 Hadoop 项目的子项目,适合非结构化数据结构的存储,并提供实时读写能力。以下是关于 Flink 对…...

C# .Net Core通过StreamLoad向Doris写入CSV数据

以下代码可以只关注StreamLoad具体实现。 1.创建StreamLoad返回值Model public class StreamLoadResponse {public long TxnId { get; set; }public string Label { get; set; }public string Comment { get; set; }public string TwoPhaseCommit { get; set; }public string…...

React-自定义Hook与逻辑共享

#题引:我认为跟着官方文档学习不会走歪路 在 React 中,自定义 Hook 是一种复用逻辑的方式。自定义 Hook 是一个 JavaScript 函数,名称以 use 开头,可以调用其他的 Hook, 可以返回任意值。 创建自定义Hook 假设你正在开发一款重…...

蓝桥杯每日真题 - 第17天

题目:(最大数字) 题目描述(13届 C&C B组D题) 题目分析: 操作规则: 1号操作:将数字加1(如果该数字为9,变为0)。 2号操作:将数字…...

游戏开发实现简易实用的ui框架

游戏开发实现简易实用的ui框架 本文使用cocos引擎实现,框架代码本质上不依赖某一个引擎,稍作修改也能作为其他引擎的实现 1.1 UI管理框架的核心需求剖析 分层与类型管理 对不同类型UI需要进行分层管理。不同层级的UI需要有不同的父节点,保证渲…...

vue3的attr透传属性详解和使用法方式。以及在css样式的伪元素中实现

在 Vue 3 和 TypeScript 中,属性透传(attr pass-through)是指将组件的属性传递到其根元素或某个子元素中。这个概念在开发可复用的组件时非常有用,尤其是当你希望将父组件的属性动态地传递给子组件的某个 DOM 元素时。 在 Vue 3 …...

【仿真建模-MESA】框架简介

1. 简介 Mesa是一个基于Python3的开源项目,旨在提供一个现代、易用的多智能体仿真环境。它借鉴了NetLogo、Repast和MASON等多智能体仿真框架的优点,并结合Python语言的强大功能,为用户提供了丰富的建模和仿真工具。 《官方文档》 2. 核心组件…...

Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)

目录 Linux软件包管理器 - yum Linux下安装软件包的方式 认识yum 查找软件包 安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件 Linux编辑器 - vim vim的基本概念 vim下各模式的切换 批量化注释 vim的简单配置 Linux编译器 - gcc/g gcc/g的作用 gcc/g语…...

VSCode 间距太小

setting->font family 使用:Consolas, Courier New, monospace 字体...

【K8S系列】imagePullSecrets配置正确,但docker pull仍然失败,进一步排查详细步骤

如果 imagePullSecrets 配置正确,但在执行 docker pull 命令时仍然失败,可能存在以下几种原因。以下是详细的排查步骤和解决方案。 1. 检查 Docker 登录凭证 确保你使用的是与 imagePullSecrets 中相同的凭证进行 Docker 登录: 1.1 直接登录 在命令行中,执行以下命令: …...

【ARM Coresight OpenOCD 系列 5.1 -- OpenOCD 无法识别CPUID 问题: xxx is unrecognized】

请阅读【嵌入式开发学习必备专栏】 文章目录 OpenOCD 无法识别CPUID 问题ARM CPUIDCPUID 特性CPUID 寄存器字段OpenOCD 无法识别CPUID 问题 在使用OpenOCD 进行CPU debug的过程中有时会报出 无法识别CPUID的问题,本文将会介绍如何解决这个问题。首先我们来学习下什么是CPUID,…...

如何实现点击目录跳转到指定位置?【vue】

需求&#xff1a;实现目录点击跳转到指定位置&#xff0c;点击后直接定位到指定模块 效果&#xff1a; 实现方法&#xff1a; &#xff08;1&#xff09;a标签跳转 普通使用&#xff1a; <!DOCTYPE html> <html><head><title>a-Demo</title>&l…...

SQL 通配符

SQL 通配符 在SQL中&#xff0c;通配符是一种特殊字符&#xff0c;用于在LIKE子句中搜索数据。它们主要用于模式匹配&#xff0c;允许你搜索符合特定模式的值。SQL中的通配符通常用于SELECT、UPDATE和DELETE语句中&#xff0c;以增加查询的灵活性。本文将详细介绍SQL中常用的通…...

ubuntu显示管理器_显示导航栏

ubuntu文件管理器_显示导航栏 一、原始状态&#xff1a; 二、显示导航栏状态&#xff1a; 三、原始状态--->导航栏状态: 1、打开dconf编辑器&#xff0c;直接在搜索栏搜索 dconf-editor ------如果没有安装&#xff0c;直接按流程安装即可。 2、进入目录&#xff1a;org …...

黑芝麻嵌入式面试题及参考答案

请详细描述二叉树的深度优先搜索(dfs)流程。 深度优先搜索是一种用于遍历二叉树的重要算法,主要有先序遍历、中序遍历和后序遍历三种方式。 先序遍历的流程是,首先访问根节点,然后递归地遍历左子树,最后递归地遍历右子树。这就好比是在探索一个家族树,先拜访家族中的长辈…...

使用 PyTorch-BigGraph 构建和部署大规模图嵌入的完整教程

当涉及到图数据时&#xff0c;复杂性是不可避免的。无论是社交网络中的庞大互联关系、像 Freebase 这样的知识图谱&#xff0c;还是推荐引擎中海量的数据量&#xff0c;处理如此规模的图数据都充满挑战。 尤其是当目标是生成能够准确捕捉这些关系本质的嵌入表示时&#xff0c;…...

系统性能优化方法论详解:从理解系统到验证迭代

在当今的企业级和云计算环境中&#xff0c;系统性能优化已成为提升竞争力的关键因素。本文将对系统优化的步骤进行深入解析&#xff0c;帮助读者系统化地进行性能优化&#xff0c;从而显著提升系统的整体表现。 流程概述: 系统性能优化的流程可以分为以下几个关键步骤&#x…...

使用Tengine 对负载均衡进行状态检查(day028)

本篇文章对于在服务器已经安装了nginx,但却希望使用Tengine 的状态检查或其他功能时使用&#xff0c;不需要卸载服务器上的nginx,思路是使用干净服务器&#xff08;未安装过nginx&#xff09;通过编译安装Tengine&#xff0c;通过对./configure的配置&#xff0c;保证安装Tengi…...

网站推广实战案例:杭州翔胜科技有限公司如何为中小企业打开市场大门

以下是以杭州翔胜科技有限公司为例&#xff0c;解析其如何通过网站推广为中小企业打开市场大门的实战案例&#xff1a; 一、一站式网站推广方案 杭州翔胜科技有限公司提供一站式网站推广方案&#xff0c;该方案整合了多种推广手段&#xff0c;如搜索引擎优化&#xff08;SEO&a…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...