Redis缓存!

news2024/12/23 18:11:32

一些基础芝士

将MySQL的热点数据存储在Redis中,通常业务都满足二八原则,80%的流量在20%的热点数据之上,所以缓存是可以很大程度提升系统的吞吐量。
一般而言, 缓存分为服务器端缓存,和客户端缓存

服务器端缓存即服务端将数据存入Redis,可以在访问DB之后,将数据缓存,或者在回包时将回包内容以请求参数为Key缓存.

(啊 那就每次查询数据之前 看看这个请求有没有加入过 如果有就直接取它的value 发过去)
客户端缓存就是对服务端远程调用之后,将结果存储在客户端,这样下次请求相同数据时就能直接拿到结果,不会再远程调用,提高性能节省网络带宽。


缓存的几种模式


缓存一般有如下几种模式:
●Cache-Aside Pattern:旁路缓存模式
Read Through Cache Pattern:读穿透模式
●Write Through Cache Pattern: 写穿透模式
●Write Behind Pattern:又叫Write Back,异步缓存写入模式
 

旁路缓存模式

Cache Aside,即旁路缓存模式,是最常见的模式,应用服务把缓存当作数据库的旁路,直接和缓存进行交互。
读操作的流程如下:
应用服务收到查询请求后,先查询数据是否在缓存上,如果在,就用缓存数据直接打包返回,如果不存在,就去访问数据库,从数据库查询,并放到缓存中,除了查库后加载这种模式,如果业务有需要,还可以预加载数据到缓存

 那它怎么写呢?

这里选择的方式是 直接删除 然后下次查询到该数据的时候 再把新的数据缓存了

为啥不直接更新呢

因为更新相比删除会更容易造成时序性问题举个例子:
thread1更新mysq|为5 -> thread2更 新mysql为3 -> thread2更新缓存为3 -> thread1更新缓存为5,最终正确的数据因为时序性被覆盖了。
Cache Aside适用于读多写少的场景,比如用户信息、新闻报道等,一旦写入缓存,几乎不会进行修改。该模式的缺点是可能会出现缓存和数据库不一致的情况。

Read Through
 

Read-Through,读穿透模式,和Cache Aside模式的区别主要在于应用服务不再和缓存直接交互,而是直接访问数据服务,这个数据服务可以理解为一个代理,即单独起这么一个服务,由它来访问数据库和缓存,作为使用者来看,不知道里面到底有没有缓存,数据服务会自己来根据情况查询缓存或者数据库。
查询的时候,和Cache Aside一样,也是缓存中有,就用从缓存中获得的数据,没有就查DB,只不过这些由数据服务托管保存,而对应用服务是透明的。
相比Cache Aside, Read Through的优势是缓存对业务透明,业务代码更简洁。缺点是缓存命中时性能不如CacheAside,相比直接访问缓存,还会多一次服务间调用。

 套了层壳子罢

Write Through
 

在Cache Aside中, 应用程序需要维护两个数据存储:一个缓存,一个数据库。这对于应用程序来说,更新操作比较麻烦,还要先更新数据库, 再去删除缓存。
WriteThrough模式相当于做了一层封装:
由这个存储服务先写入MySQL,再同步写入Redis,这样及时加载或更新了缓存数据。可以理解为,应用程序只有一个单独的访问源,而存储服务自己维护访问逻辑。

 这个不是之前的读穿透模式那样了 读穿透模式是旁路缓存纯套个壳子 这个写穿透就有改动了

Write Behind


Write-Behind和Write-Through相同点都是写入时候会更新数据库、也会更新缓存。
不同点在于Write-Through会把数据立即写入数据库中,然后写缓存,安全性很高。而Write-Behind是先写缓存,然后异步把数据一起写入数据库,这个异步写操作是Write-Behind的最大特点。
数据库写操作可以用不同的方式完成:
一种是时间上的灵活性,其中一个方式就是收集写操作并在某一时间点(比如数据库负载低的时候)慢慢写入。另一种方式就是合并几个写操作成为一个批量操作,一起批量写入。
两者是可以根据业务情况结合的。异步写操作极大地降低了请求延迟并减轻了数据库的负担,但是代价是安全性不够,比如先写入了Redis,更新操作先放在存储服务内存中,但是还没异步写入MySQL之前,存储服务崩溃了,那么数据也就丢失了。

就是一个同步一个异步的区别被

各有优势,但是Cache-Aside Pattern,旁路缓存模式是最常见,最易用的,在业务开发中,其他模式很少会用到
 

缓存异常场景

缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。
如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。谁正常人反复查这个数据 就是恶意让你穿透的
 

1.接口层增加校验,如用户鉴权校验,id做基础校验,id< =0的直接拦截;
2.从缓存取不到的数据, 在数据库中也没有取到,这时也可以将key-value对写为key-null, 缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用 如果后来这个真的key加入了 那么也无法使用即使旁路缓存也无法访问)。这样可以防止攻击用户反复用同一个id暴力攻击
3.布隆过滤器。bloomfilter就类似于一 个hash set, 用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小,
 

缓存击穿

问题背景
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
缓存击穿,一般指是指热键在过期失效的一瞬间,还没来得及重新产生,就有海量数据,直达数据库
●解决方案
1.热点数据支持续期,持续访问的数据可以不断续期,避免因为过期失效而被击穿
2.发现缓存失效,重建缓存加互斥锁,当线程查询缓存发现缓存不存在就会尝试加锁,线程争抢锁,拿到锁的线程就会进行查询数据库,然后重建缓存,争抢锁失败的线程,你可以加一个睡眠然后循环重试
 

缓存雪崩


●问题背景
缓存雪崩顾名思义,是指大量的应用请求因为异常无法在Redis缓存中进行处理,像雪崩一样,直接打到数据库。
这里异常的原因,也可以说雪崩的原因,主要是:缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机其实在一些资料里,会把Redis宕机算进来,原因是Redis宕机了也就无法处理缓存请求,但这里会觉得有些牵强,如果这里能算,缓存击穿不也可以算?所以这里建议是不把宕机考虑到雪崩里去。

●解决方案
1.缓存数据的过期时间设置随机,防止同- -时间大量数据过期现象发生。
2.重建缓存加互斥锁,当线程拿到缓存发现缓存不存在就会尝试加锁,线程争抢锁,拿到锁的线程就会进行查询
数据库,然后重建缓存,争拾锁失败的线程,你可以加一个睡眠然后循环重试
 

区分一下 这个击穿是 一条热点数据过期 然后大量请求去查询这个热点数据 然后雪崩是大量的数据过期 这个大量的请求去请求这些数据

缓存一致性问题

缓存,都知道是持久化数据的冗余存储,但如果缓存加载了数据源的数据,但对应数据要发生变化,怎么办呢?
我们以数据源为MySQL,缓存用Redis,前面也说过了,在数据库场景下,更廉价、高效但可靠性稍低的redis可以给更昂贵、较慢、可靠性强的mysq|做缓存。
前面介绍了几种缓存模式,这里我们以常见、最实用的旁路缓存模式为基础,来进行分析。
大的方向有三:
1.更新MySQL即可,不管Redis,以过期时间兜底
2.更新MySQL之后,操作Redis
3.异步将MySQL的更新同步到Redis

方向一


使用redis的过期时间,mysqI更新时,redis不做处理,等待缓存过期失效,再从mysq|拉取缓存。
这种方式实现简单,但不一致的时间会比较明显,具体由你的业务来配置。如果读请求非常频繁,且过期时间设置较长,则会产生很多脏数据。
优点:
redis原生接口,开发成本低,易于实现;
管理成本低,出问题的概率会比较小。
不足:
完全依赖过期时间,时间太短容易造成缓存频繁失效,太长容易有较长时间不一 致

方向二

不光通过key的过期时间兜底,还需要在更新mysql时,同时尝试操作redis,这里的操作分两种方式,1是更新,直接将结果写入Redis,但实际上很少用更新,而是用删除,等待下次访问再加载回来,为什么呢?因为更新容易带来时序性问题。
举个例子:假设a的初始值为2,两台业务服务器在同一时间发出两条请 求:
第一条,给a的值加1
第二条,设置a的值为5
若mysqI中先执行第一条, 再执行第二条,则mysq|中a的值先变成3,最终为5;
但由于网络传输本身有延迟,所以无法保证两条Redis更新操作谁先执行,如果第二条对应的更新先执行,Redis的数据就先变成了5,然后在加1变成了6。
这就出现数据对不上的问题,相比于数据延迟而言,这更让人疑惑和不能接受。所以一般都选择 删除。
上面有提到,这里是尝试删除,这样说是这一步操作是可能失败了,失败就我们可以忽略,也就是不能让删除成为一个关键路径,影响核心流程。
因为我们有key本身的过期时间作为保障,所以最终一致性是一 定达成的, 主动删除redis数据只是为了减少不一致的时间。
优点:
相对方案一,达成最终一致性的延迟更 小;
实现成本较低, 只是在方案-的基础上, 增加了删除逻辑。
不足:
如果更新mysql成功,删除redis却失败,就退化到了方案- - ;
在更新时候需要额外操作Redis,带来了损耗。
 

方向三 

把我们搭建的消费服务作为mysqI的一个slave,订阅mysqI的binlog日志,解析日志内容,再更新到redis.此方案和业务完全解耦,redis的更新对业务方透明,可以减少心智成本。

优点:
和业务完全解耦,在更新mysq|时,不需要做额外操作;
无时序性问题,可靠性强。
缺点:
引入了消息队列这种算比较重的组件,还要单独搭建一个同步服务.维护他们是非常大的额外成本
同步服务如果压力比较大,或者崩溃了,那么在较长时间内,redis中都是老旧数据
 

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

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

相关文章

git权限问题解决方法Access denied fatal: Authentication failed

文章目录 遇到Access denied 的权限问题解决方法1、git的密码修改过&#xff0c;但是本地没更新。2、确定问题&#xff0c;然后增加配置① 查询用户信息②如果名称和email不对&#xff0c;设置名称&#xff1a;③ 检查ssh-add是否链接正常④ 设置不要每次都输入用户名密码 3、配…

算法通关村第3关【青铜】| 不简单的数组增删改查

1. 创建数组 //第一种创建和初始化的方法int[] arr new int[10];//第二种创建和初始化的方法int[] arr2 new int[]{0, 1, 2, 3, 5, 6, 8};System.out.println("arr2:" Arrays.toString(arr2));//第二种方式的简化版本:int[] arr3 {2, 5, 0, 4, 6, -10};System.ou…

leetcode292. Nim 游戏(博弈论 - java)

Nim 游戏 Nim 游戏题目描述博弈论 上期经典算法 Nim 游戏 难度 - 简单 原题链接 - Nim游戏 题目描述 你和你的朋友&#xff0c;两个人一起玩 Nim 游戏&#xff1a; 桌子上有一堆石头。 你们轮流进行自己的回合&#xff0c; 你作为先手 。 每一回合&#xff0c;轮到的人拿掉 1 -…

蓝牙资讯|中国智能家居前景广阔,蓝牙Mesh照明持续火爆

据俄罗斯卫星通讯社报道&#xff0c;中国已成为全球最大的智能家居消费国&#xff0c;占全球50%—60%的市场份额。未来&#xff0c;随着人工智能技术的发展以及智能家居生态的不断进步&#xff0c;智能家居在中国的渗透率将加速提升。德国斯塔蒂斯塔调查公司数据显示&#xff0…

已知四个坐标点,怎样求出四边形的四个内角

1&#xff0c;理论 最简单的方式利用向量进行求解 如图可得&#xff1a; cosθa*b/&#xff08;|a|*|b|&#xff09; 已知三点坐标&#xff0c;很容易可以得到两向量之积a*b&#xff0c;以及每个的模值 2&#xff0c;四个角度求解过程 首先&#xff0c;我们定义了四个坐标点…

Kubernetes+EFK构建日志分析平台

目录 Fluentd 工作原理 1.1、主机初始化配置 1.2、部署docker环境 二、部署kubernetes集群 2.1、组件介绍 2.2、配置阿里云yum源 2.3、安装kubelet kubeadm kubectl 2.4、配置init-config.yaml 2.5、安装master节点 2.6、安装node节点 2.7、安装flannel 3、部署企业…

5G之CSI报告的内容

[TOC]5G之CSI报告的内容 一、CSI包括的内容 1. UE上报的信道状态信息&#xff08;Channel State Information&#xff0c;CSI&#xff09;包括 信道质量指示&#xff08;Channel Quality Indicator, CQI)&#xff1b;预编码矩阵指示&#xff08;Precoding Matrix Indicator&…

QT:定时器事件

定时器第一种办法&#xff1a; 1.利用事件timerEvent&#xff0c;在帮助文档中找到该字段&#xff1a;[override virtual protected] void QTimer::timerEvent(QTimerEvent *e) 重写该虚函数 //重写定时器事件void timerEvent(QTimerEvent *e);2.启动定时器startTimer(1000); …

C++线程库

C线程库是C11新增的重要的技术之一&#xff0c;接下来来简单学习一下吧&#xff01; thread类常用接口 函数名功能thread()构造一个线程对象&#xff0c;没有关联任何线程函数&#xff0c;即没有启动任何线程。thread(fn, args1, args2, ...)构造一个线程对象&#xff0c;并…

Python进阶系列(一)——异常处理

异常处理 在程序中&#xff0c;如果出现异常&#xff0c;我们需要捕捉异常&#xff0c;终止程序&#xff08;可能的话&#xff09;&#xff0c;并且提示错误信息。 写好异常处理&#xff0c;对于debug有很大的好处&#xff0c;可以帮助我们捕捉到错误所在的位置&#xff0c;以…

centos 7.9 部署django项目

1、部署框架 主要组件&#xff1a;nginx、uwsgi、django项目 访问页面流程&#xff1a;nginx---》uwsgi---》django---》uwsgi---》nginx 2、部署过程 操作系统&#xff1a;centos 7.9 配置信息&#xff1a;4核4G 50G 内网 eip &#xff1a;10.241.103.216 部署过程&…

【STM32】 工程

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星TO…

Maven自定义脚手架(多module模块)+自定义参数

脚手架 视频教程&#xff1a; Maven保姆级教程 脚手架是一个项目模板&#xff0c;包含常用的工程结构、代码。 1 自定义脚手架 脚手架创建的步骤如下&#xff0c;先创建一个工程&#xff0c;把常用的代码写好&#xff0c;进入工程根目录&#xff0c;进行如下操作&#xff1a; …

webSocket 笔记

1 认识webSocket WebSocket_ohana&#xff01;的博客-CSDN博客 一&#xff0c;什么是websocket WebSocket是HTML5下一种新的协议&#xff08;websocket协议本质上是一个基于tcp的协议&#xff09;它实现了浏览器与服务器全双工通信&#xff0c;能更好的节省服务器资源和带宽…

全网首发 | 科学计算与系统建模仿真系列课程上线啦!

当前&#xff0c;信息物理融合系统&#xff08;CPS&#xff09;、基于模型的系统工程&#xff08;MBSE&#xff09;、数字孪生、数字化工程等新型技术快速发展&#xff0c;推动装备研制从信息化时代步入到数字化时代&#xff0c;并且呈现数字化与智能化相融合的新时代特点。MWO…

Flink的常用算子以及实例

1.map 特性&#xff1a;接收一个数据&#xff0c;经过处理之后&#xff0c;就返回一个数据 1.1. 源码分析 我们来看看map的源码 map需要接收一个MapFunction<T,R>的对象&#xff0c;其中泛型T表示传入的数据类型&#xff0c;R表示经过处理之后输出的数据类型我们继续往…

vue2+Spring Boot2.7 大文件分片上传

之前我们文章 手把手带大家实现 vue2Spring Boot2.7 文件上传功能 将了上传文件 但如果文件很大 就不太好处理了 按正常情况甚至因为超量而报错 这里 我弄了个足够大的文件 我们先搭建 Spring Boot2.7 环境 首先 application.yml 代码编写如下 server:port: 80 upload:path:…

机器学习、cv、nlp的一些前置知识

为节省篇幅&#xff0c;不标注文章来源和文章的问题场景。大部分是我的通俗理解。 文章目录 向量关于向量的偏导数&#xff1a;雅可比矩阵二阶导数矩阵&#xff1a;海森矩阵随机变量随机场伽马函数beta分布数学术语坐标上升法协方差训练集&#xff0c;验证集&#xff0c;测试集…

2023年7月京东冰箱行业品牌销售排行榜(京东运营数据分析)

作为日常使用的大家电之一&#xff0c;如今我国冰箱产业已渐趋饱满&#xff0c;市场增长有限。今年上半年&#xff0c;冰箱市场整体销额同比去年来看勉强保持小幅增长。不过&#xff0c;7月份&#xff0c;冰箱大盘的销售表现就略显萧条了。 根据鲸参谋电商数据分析平台的相关数…

css3-grid:grid 布局 / 基础使用

一、理解 grid 二、理解 css grid 布局 CSS Grid布局是一个二维的布局系统&#xff0c;它允许我们通过定义网格和网格中每个元素的位置和尺寸来进行页面布局。CSS Grid是一个非常强大的布局系统&#xff0c;它不仅可以用于构建网格布局&#xff0c;还可以用于定位元素&#xf…