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

redis 缓存预热_Redis中缓存预热、击穿、雪崩等问题解决方案

1、缓存雪崩

缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案

缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。

给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。

2、缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案

接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;

从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力

附加

对于空间的利用到达了一种极致,那就是Bitmap和布隆过滤器(Bloom Filter)。

Bitmap: 典型的就是哈希表

缺点是,Bitmap对于每个元素只能记录1bit信息,如果还想完成额外的功能,恐怕只能靠牺牲更多的空间、时间来完成了。

布隆过滤器(推荐)

就是引入了k(k>1)k(k>1)个相互独立的哈希函数,保证在给定的空间、误判率下,完成元素判重的过程。

它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

Bloom-Filter算法的核心思想就是利用多个不同的Hash函数来解决“冲突”。

Hash存在一个冲突(碰撞)的问题,用同一个Hash得到的两个URL的值有可能相同。为了减少冲突,我们可以多引入几个Hash,如果通过其中的一个Hash值我们得出某元素不在集合中,那么该元素肯定不在集合中。只有在所有的Hash函数告诉我们该元素在集合中时,才能确定该元素存在于集合中。这便是Bloom-Filter的基本思想。

Bloom-Filter一般用于在大数据量的集合中判定某元素是否存在。

3、缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案

设置热点数据永远不过期。

加互斥锁,互斥锁

4、缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

解决方案

直接写个缓存刷新页面,上线时手工操作一下;

数据量不大,可以在项目启动的时候自动进行加载;

定时刷新缓存;

5、缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。

缓存降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。

在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:

一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;

警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;

错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;

严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。

服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。

6、热点数据和冷数据

热点数据,缓存才有价值

对于冷数据而言,大部分数据可能还没有再次访问到就已经被挤出内存,不仅占用内存,而且价值不大。频繁修改的数据,看情况考虑使用缓存

对于热点数据,比如我们的某IM产品,生日祝福模块,当天的寿星列表,缓存以后可能读取数十万次。再举个例子,某导航产品,我们将导航信息,缓存以后可能读取数百万次。

数据更新前至少读取两次,缓存才有意义。这个是最基本的策略,如果缓存还没有起作用就失效了,那就没有太大价值了。

那存不存在,修改频率很高,但是又不得不考虑缓存的场景呢?有!比如,这个读取接口对数据库的压力很大,但是又是热点数据,这个时候就需要考虑通过缓存手段,减少数据库的压力,比如我们的某助手产品的,点赞数,收藏数,分享数等是非常典型的热点数据,但是又不断变化,此时就需要将数据同步保存到Redis缓存,减少数据库压力。

7、缓存热点key

缓存中的一个Key(比如一个促销商品),在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

解决方案

对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询

原文链接:https://thinkwon.blog.csdn.net/article/details/103402008

更多信息请关注公众号:「软件老王」,关注不迷路,软件老王和他的IT朋友们,分享一些他们的技术见解和生活故事。

相关文章:

  • Ubuntu环境下IPython的搭建和使用
  • 或是独体字吗_什么是独体字?
  • 【7005】二叉树的遍历问题2
  • eslint 无法格式化ts_vscode-eslint的踩坑实践--typescript没法格式化
  • 【2030】排队打水问题
  • vue入门到启动_Vue入门:Vue项目创建及启动
  • 【2012】建立二维矩阵
  • idle显示出错信息 python_python小课堂05 - 基本数据类型字符串篇(重要)
  • POJ3468(线段树 区间修改 lazy-tag)
  • html radio 默认图片替换_怎么修改单选框radio默认样式
  • ubuntu 16.04 主题美化及终端美化
  • android怎么监听多点触摸_android 多点触控
  • c#webservice接口調用_用.net发布一个简单的webservice
  • 51nod1967 路径定向(欧拉回路+结论题)
  • python管道函数_python--管道, 事件, 信号量, 进程池
  • 网络传输文件的问题
  • 【面试系列】之二:关于js原型
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • ES6简单总结(搭配简单的讲解和小案例)
  • gitlab-ci配置详解(一)
  • JavaScript创建对象的四种方式
  • JS 面试题总结
  • PHP CLI应用的调试原理
  • SQLServer之创建数据库快照
  • v-if和v-for连用出现的问题
  • vue-router 实现分析
  • vue学习系列(二)vue-cli
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 七牛云假注销小指南
  • 前端学习笔记之观察者模式
  • 悄悄地说一个bug
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 小试R空间处理新库sf
  • ​什么是bug?bug的源头在哪里?
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • (02)vite环境变量配置
  • (2020)Java后端开发----(面试题和笔试题)
  • (C++20) consteval立即函数
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • ***监测系统的构建(chkrootkit )
  • .describe() python_Python-Win32com-Excel
  • .Net core 6.0 升8.0
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .net实现客户区延伸至至非客户区
  • [2023-年度总结]凡是过往,皆为序章
  • [22]. 括号生成
  • [2669]2-2 Time类的定义