19 redis缓存数据同步问题

1、缓存穿透

指缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存不命中,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,缓存就没有意义了。

在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

解决方案

  1. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒。
  2. 布隆过滤器。bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。
2、缓存击穿

主要针对的是热点key
缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
解决方案

  1. 设置热点数据永远不过期。
  2. 接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些 服务 不可用时候,进行熔断,失败快速返回机制。
  3. 加互斥锁。
3、缓存雪崩

缓存中数据大批量过期,而查询数据量巨大,引起数据库压力过大甚至down机。
缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。
  3. 设置热点数据永远不过期。
4、缓存污染

缓存污染问题说的是缓存中一些只会被访问一次或者几次的的数据,被访问完后,再也不会被访问到,但这部分数据依然留存在缓存中,消耗缓存空间。

缓存污染会随着数据的持续增加而逐渐显露,随着服务的不断运行,缓存中会存在大量的永远不会再次被访问的数据。缓存空间是有限的,如果缓存空间满了,再往缓存里写数据时就会有额外开销,影响Redis性能。

一般性建议缓存容量设置为总数据量的 15%30%,兼顾访问性能和内存空间开销。

5、缓存淘汰策略

主要分成三大类

  1. 不淘汰:noeviction (v4.0后默认的)
  2. 设置了过期时间的数据:
    随机:volatile-random
    ttl:volatile-ttl
    lru:volatile-lru
    lfu:volatile-lfu
  3. 全部淘汰:
    随机:allkeys-random
    lru:allkeys-lru
    lfu:allkeys-lfu
5.1、缓存淘汰策略详解
  1. noeviction: 该策略是Redis的默认策略,一旦缓存被写满了,再有写请求来时,Redis 不再提供服务,而是直接返回错误。这种策略不会淘汰数据,所以无法解决缓存污染问题。一般生产环境不建议使用。
  2. volatile-random: 在设置了过期时间的键值对中,进行随机删除。因为是随机删除,无法把不再访问的数据筛选出来,所以可能依然会存在缓存污染现象,无法解决缓存污染问题。
  3. volatile-ttl: 参考的指标比随机删除时多进行一步过期时间的排序。Redis在筛选需删除的数据时,越早过期的数据越优先被选择。
  4. volatile-lru: 按照最近最少使用的原则来筛选数据。这种模式下会使用 LRU 算法筛选设置了过期时间的键值对。
  5. volatile-lfu: 使用 LFU 算法选择设置了过期时间的键值对.
    LFU 算法:LFU 缓存策略是在 LRU 策略基础上,为每个数据增加了一个计数器,来统计这个数据的访问次数。当使用 LFU 策略筛选淘汰数据时,首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。如果两个数据的访问次数相同,LFU 策略再比较这两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出缓存。
6、数据库和缓存一致性问题

加入redis换粗后的一般的业务场景如下:
在这里插入图片描述
读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。

不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。

总结:

读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
更新的时候,先更新数据库,然后再删除缓存。

6.1、缓存一致性的解决方案

在更新数据库成功后,删除缓存key不一定生效的,解决方案是什么?

方案1:队列 + 重试机制
在这里插入图片描述
流程如下所示:

1.更新数据库数据;
2.缓存因为种种问题删除失败
3.将需要删除的key发送至消息队列
4.自己消费消息,获得需要删除的key
5.继续重试删除操作,直到成功

该方案有一个缺点,对业务线代码造成大量的侵入。于是有了方案2

方案2:异步更新缓存(基于订阅binlog的同步机制)
在这里插入图片描述
整体思路:MySQL binlog增量订阅消费+消息队列+增量数据更新到redis

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言精选——选择题Day42

第一题 1. 下面程序输出的结果是&#xff08;&#xff09; #include <stdio.h> int main () {int x;x printf("I See, Sea in C");printf("x%d" , x); } A&#xff1a;2 B&#xff1a;随机值 C&#xff1a;都不是 D&#xff1a;15 答案及解析 D p…

7.题目:编号1531 快递分拣

题目: ### 这道题主要考察map,vector,string的综合运用单号和城市都可以用string类型存储 #include <bits/stdc.h> using namespace std;map<string,vector<string>> mp;vector<string> citys;int main(){ios::sync_with_stdio(0),cin.tie(0),cout.t…

猿人学第三题 罗生门

思路 使用开发者工具进行抓包&#xff0c;验证数据请求的方式是什么&#xff0c;这里推荐大家使用浏览器自带的工具。 我们发现每次的翻页请求都会有一个jssm请求&#xff0c;这里我们先记录一下这个情况&#xff0c;现在观察一下cookie是否有变化。 这个实际上没有发生变化。…

最长连续序列(leetcode 128)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路方法一&#xff1a;排序方法二&#xff1a;哈希表 5.实现示例参考文献 1.问题描述 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你…

见微知著-从底层代码一撇Qt的控件绘图

Qt 是目前C语言首选的框架库。之所以称为框架库而不单单是GUI库&#xff0c;是因为Qt提供了远远超过GUI的功能封装&#xff0c;即使不使用GUI的后台服务&#xff0c;也可以用Qt大大提高跨平台的能力。 仅就界面来说&#xff0c;Qt 保持各个平台绘图等效果的统一&#xff0c;并…

不想写大量 if 判断?试试用规则执行器优化,就很丝滑!

近日在公司领到一个小需求&#xff0c;需要对之前已有的试用用户申请规则进行拓展。我们的场景大概如下所示: if (是否海外用户) {return false; }if (刷单用户) {return false; }if (未付费用户 && 不再服务时段) {return false }if (转介绍用户 || 付费用户 || 内推…

Terminator的layout设置(一个新的一键启动思路)

首先你得有terminator&#xff1a; sudo apt install terminator然后就能使用了&#xff0c;我一般喜欢修改它原本的水平和垂直分割&#xff1a;用ctrlshifta和ctrlshifts 把屏幕先分成多块&#xff1a; 比如是这样的&#xff0c;接下来 右键->点击Preference 弹框中上方标…

LVGL | Demo实例使用说明

LVGL | Demo实例使用说明 时间&#xff1a;2023年12月10日21:51:17 文章目录 LVGL | Demo实例使用说明Demos for LVGLAdd the examples to your projectsDemosWidgetsMusic playerKeypad and encoderBenchmarkStress Contributing Demos for LVGL Add the examples to your p…

[山东大学操作系统课程设计]实验四+实验五

0.写在前面&#xff1a; 为什么这次把两个实验放在一起写了&#xff0c;因为实验五的要求就是在实验四的基础上完成实现的。但是我得实现说明&#xff0c;我的实验四虽然完成了要求&#xff0c;但是无法在我自己的实验四的基础上完成实验五&#xff0c;这是一个很大的问题&…

盘点251个Python源码Python爱好者不容错过

盘点251个Python源码Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 项目名称 链接&#xff1a;https://pan.baidu.com/s/1PikCn61NfHXmEzQiny8kfw?pwd6666 提取码&#xff1a;6666 dailyfreshpython-Dj…

P1317 低洼地题解

题目 一组数&#xff0c;分别表示地平线的高度变化。高度值为整数&#xff0c;相邻高度用直线连接。找出并统计有多少个可能积水的低洼地&#xff1f; 如图&#xff1a;地高变化为 [0,1,0,2,1,2,0,0,2,0]。 输入输出格式 输入格式 两行&#xff0c;第一行n, 表示有n个数。第…

在Spring Cloud使用Hystrix核心组件,并注册到Eureka注册中心去

其实吧&#xff0c;写Spring Cloud系列&#xff0c;我有时候觉得也挺难受的&#xff0c;因为Spring Cloud的微服务启动都需要一个一个来&#xff0c;并且在IDea中也需要占用比较大的内存&#xff0c;并且我本来可以一篇写完5大核心组件的&#xff0c;但是我却分了三篇&#xff…