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

缓存大杀器-redis

缓存模型

redis是我们最常使用的缓存组件,使用缓存能够大大降低用户访问并发量带来的服务器读写压力。

常见的缓存模型如下:

在这里插入图片描述

在客户端请求数据库之前先查询缓存,如果缓存数据存在,则直接返回;如果缓存数据不存在,再查询数据库,然后将数据写入redis缓存中,最后返回数据给客户端。

通过缓存中间件可以有效缓解数据库并发访问下产生的压力

缓存更新

缓存更新是redis为了节约内存而设计出来的一个东西,主要是因为内存数据宝贵,当我们向redis插入太多数据,此时就可能会导致缓存中的数据过多,所以redis会对部分数据进行更新,或者把他叫为淘汰更合适。

  • 内存淘汰:redis自动进行,当redis内存达到咱们设定的max-memery的时候,会自动触发淘汰机制,淘汰掉一些不重要的数据(可以自己设置策略方式)

  • 超时剔除:当我们给redis设置了过期时间ttl之后,redis会将超时的数据进行删除,方便咱们继续使用缓存

  • 主动更新:我们可以手动调用方法把缓存删掉,通常用于解决缓存和数据库不一致问题

双写一致问题

由于我们的缓存的数据源来自于数据库,而数据库的数据是会发生变化的,因此,如果当数据库中数据发生变化,而缓存却没有同步,此时就会有一致性问题存在。

缓存数据与数据库数据不一致,使得用户使用的是缓存中的过时数据,而不是数据库中的实时数据,这就会给我们的程序带来灾难性的业务问题。

为了确保数据库和缓存数据的一致性,我们每次操作数据库后都需要操作缓存,那么这就带来了一系列问题?

  1. 操作缓存时是删除缓存还是更新缓存

    • 更新缓存:每次更新数据库都更新缓存,无效写操作较多

    • 删除缓存:更新数据库时让缓存失效,查询时再更新缓存

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

    • 单体系统,将缓存与数据库操作放在一个事务

    • 分布式系统,利用TCC等分布式事务方案

  3. 先操作缓存还是先操作数据库

    1. 先删除缓存,再操作数据库

    2. 先操作数据库,再删除缓存

在多线程并发执行的环境下,当你使用a方案先删除缓存,再来操作数据库可能会出现如下情况:

在这里插入图片描述

  1. 线程1想要更新数据,会先删除缓存中存在的数据,此时发生线程调度,切换到线程2。

  2. 线程2想要获取数据,先查询缓存中的数据,当缓存为命中时(缓存中数据被线程1删除),线程2会接着去查询数据库,并将数据库中还未发生修改的旧数据写入缓存(缓存中依然是数据库中的旧数据),并返回给线程2。

  3. 此时又发生线程调度,将cpu交由线程1,线程1会接着执行上次未完成的任务,进行数据库更新操作,使得数据库中存储新的数据。

经过我们上面的分析,我们发现缓存与数据库中的出现了不一致的情况。

当前b方案先操作数据库,再来删除缓存在多线程并发访问的条件下也有可能出现问题:

在这里插入图片描述

  1. 线程1查询缓存时,缓存正好失效(缓存未命中),此时线程1会去查询数据库数据,当准备将查询的数据库数据写入缓存时恰好发生线程调度,切换到线程2。

  2. 线程2正好更新数据库数据,并执行了删除缓存操作。

  3. 此时又发生线程调度,将cpu交由线程1,线程1会接着执行上次未完成的任务,将上次线程1查询到的数据库数据写入缓存。

也就是说,无论是a方案,还是b方案都有可能存在数据库数据和缓存数据的不一致性,这时候我们可以通过给缓存数据添加过期时间来确保数据库数据和缓存数据的最终一致性(双写最终一致)。

尽管上述两种方案都可能存在短暂的数据不一致情况,但是我们还是推荐使用b方案,先操作数据库再来操作缓存

这是因为相比于方案a而言,方案b是在极端场景下才会出现一致性问题;方案b需要同时满足缓存恰好失效,线程切换,和写入缓存前被打断这三个条件才会出现一致性问题。(更新数据库的耗时(如MySQL事务提交)远长于删除缓存的耗时(如Redis的DEL命令,约1-10微秒),这也就是说删除缓存的操作几乎不会被其他线程打断)

缓存穿透问题

缓存穿透 :缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库,给数据库造成大量压力。

常见的解决方案有两种:

在这里插入图片描述

缓存雪崩问题

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

解决方案:

在这里插入图片描述

缓存击穿问题

缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。

在这里插入图片描述

常见的解决方案有两种:

  1. 通过互斥锁限制访问实现缓存重建,从而避免数据库的访问压力过大,但是这种互斥会导致查询其他线程的阻塞,从而影响性能。

在这里插入图片描述

  • 热点key问题是由过期时间导致的,那么我们可以不真正设置过期时间,而是通过逻辑过期来判断key的有效与否的手段来解决问题。

在这里插入图片描述

采用逻辑过期方案时,当我们获取互斥锁成功后,后续缓存重建的逻辑是在新的线程中进行,然后在原线程中直接返回过期数据;当获取互斥锁失败后,直接返回过期数据。通过这种异步的构建提高程序的效率,缺点在于缓存重建完成前,返回的都是脏数据。

http://www.dtcms.com/a/462262.html

相关文章:

  • 网站建设管理方案网站开发与app开发的区别
  • 装修公司网站制作大数据营销成功案例
  • 【STM32】I2C通信—硬件外设
  • 脚手架学习
  • 做网站好还是做淘宝好现在手机网站用什么做的
  • 建设行业网站平台的瓶颈网站网页
  • 【Linux】线程概念与控制(2)
  • vue项目发布后图标乱码解决方案
  • 成都手机网站重庆本地建站
  • UI设计(二)赛博科技修仙通讯录——东方仙盟筑基期
  • 实时数仓历史数据优化
  • 网站建设在哪能看企业网站建立流程的第一步是什么
  • 告别手动配置:用 Terraform 定义你的 RustFS 存储帝国
  • 36.Linux Shell编程
  • AI智能体赋能社会科学研究领域之仿真:心智疆域的重塑与伦理韧性机制的建立
  • daily notes[81]
  • 常用命令和tricks
  • 【AI编程前沿】人类编写代码 vs AI生成代码:质量、漏洞与复杂度的大规模比较研究
  • 黑龙江建设人力资源网站网站建设及安全制度
  • 广州市增城建设局网站怎样开发一个app软件
  • 机器视觉Halcon3D中add_deformable_surface_model_reference_point的作用
  • 设计一个简单的旅游网站全网拓客app
  • 从零到一构建高可用微服务架构的核心实践与挑战
  • 【深入浅出PyTorch】--4.PyTorch基础实战
  • 项目源码安全审查怎么写
  • 陕西网站建设哪家专业培训班有哪些
  • 朋友给我做网站微网站开发第三方平台
  • 基于区块链的电子投票系统的设计与实现(源码+文档+部署讲解)
  • 百度对网站的收录课程网站建设内容
  • Linux修改MAC地址