缓存和数据库,1+1如何大于2?

一、缓存的本质

        缓存,简单说就是为了节约对原始资源重复获取的开销,而将结果数据副本存放起来以供获取的方式。

        首先,缓存往往针对的是“资源”。我们前面已经多次提到过,当某一个操作是"幂等"的和“安全"的,那么这样的操作就可以被抽象为对"资源"的获取操作,那么它才可以考虑被缓存。有些操作不幂等、不安全,比如银行转账,改变了目标对象的状态,自然就难以被缓存。

        其次,缓存数据必须是“重复"获取的。缓存能生效的本质是空间换时间。也就是说,将曾经出现过的数据以占据缓存空间的方式存放下来,在下一次的访问时直接返回,从而节约了通过原始流程访问数据的时间。有时候,某些资源的获取行为本身是幂等的和安全的,但实际应用上却不会"重复"获取,那么这样的资源是无法被设计成真正的缓存的。我们把一批数据获取中,通过缓存获得数据的次数,除以总的次数,得到的结果,叫做缓存的命中率。

        再次,缓存是为了解决“开销”的问题。这个开销,可不只有时间的开销。虽然我们在很多情况下讲的开销,确实都是在时间维度上的,但它还可以是CPU、网络、I/O等一切资源。例如我们有时在Web服务中增加一层缓存,是为了避免了对原始资源获取的时候,对数据库资源调用的开销。

二、缓存应用模式

2.1 旁路缓存模式

2.1.1 数据读写策略 

读数据时:

  • 先读缓存,若缓存有数据,直接返回
  • 若缓存没有,读数据库。若数据库有,将结果写入缓存,并返回结果
  • 若数据库没有,就返回没有

写数据时:

  • 先写数据库
  • 再令对应的缓存失效

2.1.2 操作关键 

  • 写数据时,必须先更新数据库,再令缓存失效

这个很容易理解,如果先令缓存失效了,而数据库还没来得及更新成功,那么假如这个时候有一个请求访问,他会直接击穿到数据库中,带着数据库的陈旧值去更新缓存,就会导致旧数据长期存在于缓存中,导致严重的数据不一致问题。

  • 写数据时,更新完数据库之后,必须是让缓存失效,而不是更新缓存

为什么呢?如果此时更新的策略是更新缓存而不是令缓存失效,此时几乎同时发出的请求分别更新数据库中的值为A和B,结果是A的更新早于B,那么并不能保证这两个请求更新缓存时,顺序就是A早于B,就会导致缓存中的数据可能会长期是A值。

2.1.3 数据异常情形

读操作:

  • 缓存读取异常,直接返回失败,没有数据不一致的情况
  • 数据库读取异常,直接返回失败,没有数据不一致的情况
  • 数据库读取成功,但是缓存写入失败,那么下一次读取同一数据的请求还会继续尝试写入,没有数据不一致的情况发生

写操作:

  • 数据库写入失败,直接返回失败,没有数据不一致的情况
  • 数据库写入成功,但是缓存失效的操作失败,这个问题发生了之后会非常麻烦,需要特殊处理来纠正(比如缓存数据和数据库不一致时配置告警、定期将数据库数据刷缓存)

2.2 缓存代理模式

        将缓存系统作为数据库的代理,应用的请求访问只能到缓存,数据库系统对应用来说是透明的。

 2.2.1 数据读写策略

读操作:

  • 先读缓存,如果缓存中有数据,返回
  • 如果缓存中没有数据,缓存查询数据库,并将结果写入自己,再返回给应用

写操作:

  • 先写缓存
  • 缓存再更新数据库
  • 通知应用写入成功
    • 这里更新数据库有两种策略
    • 透写(write-through):同步更新数据库完成之后再返回成功
    • 回写(write-back):更新缓存之后就直接返回成功,异步更新数据库(支持批量更新,更新效率高,速率稳定;但是存在数据丢失风险)

2.2.2 操作关键点

  • 缓存系统需要自己内部保证并发场景下,缓存更新的顺序和数据库更新的顺序一致,这个可以用乐观锁来保证

2.2.3 数据异常情形

读操作:

  • 同旁路缓存模式,没有数据不一致情况

写操作:

  • 如果缓存更新失败,直接返回失败,没有数据不一致情况
  • 如果缓存更新成功,数据库更新失败,需要回滚

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

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

相关文章

2024年原创深度学习算法项目分享

原创深度学习算法项目分享,包括以下领域: 图像视频、文本分析、知识图谱、推荐系统、问答系统、强化学习、机器学习、多模态、系统界面、爬虫、增量学习等领域… 有需要的话,评论区私聊

C语言中的难点

C语言把内存划分成四个区,它把一般的变量和数组等存在于内存中的栈区,全局变量在静态区若指针没有被初始化,那么指针可能会指向任何内存位置,这样可能会导致程序崩溃或者行为不确定,野指针就是指针指向的位置是不可知的(随机的、不…

搭建FTP服务器

目录 一、FTP 1.1 FTP简介 1.2 FTP服务器搭建 1.2.1 前提 1.2.2 创建组 1.2.3 创建用户 1.2.4 安装FTP服务器 1.2.5 配置FTP服务器 1.2.6 配置FTP的文件夹权限 1.2.7 连接测试 1.2.8 允许外部访问 二、计算机端口介绍 2.1 端口简介 2.2 开启端口 2.3 端口相关 2…

【单元测试】使用Gradle运行@SpringBootTest单元测试提示“No tests found for given includes。。。 “解决

问题: 在IntelliJ IDEA中运行Gradle服务的单元测试时报错 错误提示: Task :test FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ‘:test’. No tests found for given includes: [DemoTest.queryStri…

探索PySimpleGUI:一款简洁易用的图形用户界面库

目录 PySimpleGUI 安装使用 代码框架 常用控件 Text Input Button 布局方法 事件循环 示例代码 调试窗口 主题 theme Listbox控件 简单实例 小结 PySimpleGUI PySimpleGUI是一个基于Tkinter、WxPython、Qt等底层库构建的图形界面框架,其设计目标是使…

图像分割实战-系列教程4:unet医学细胞分割实战2(医学数据集、图像分割、语义分割、unet网络、代码逐行解读)

🍁🍁🍁图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 上篇内容: unet医学细胞分割实战1 下篇内容: unet医学细胞分割实战3 3、指…

再薅!Pika全球开放使用;字节版GPTs免费不限量;大模型应用知识地图;MoE深度好文;2024年AIGC发展轨迹;李飞飞最新自传 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 👀 终于!AI视频生成平台 Pika 面向所有用户开放网页端 https://twitter.com/pika_labs Pika 营销很猛,讲述的「使…

qt中信号槽第五个参数

文章目录 connent函数第五个参数的作用自动连接(Qt::AutoConnection)直接连接(Qt::DirectConnection - 同步)同线程不同线程 队列连接(Qt::QueuedConnection - 异步)同一线程不同线程 锁定队列连接(Qt::BlockingQueuedConnection) connent函数第五个参数的作用 connect(const …

LSTM Siamese neural network

本文中的代码在Github仓库或Gitee仓库中可找到。 Hi, 你好。我是茶桁。 大家是否还记得,在「核心基础」课程中,我们讲过CNN以及LSTM。 卷积神经网络(CNN)已经在计算机视觉处理中得到广泛应用,不过,2017年…

Shell脚本自动化部署LAMP环境

[rootlocalhost ~]# vim liang.sh #!/bin/bash# LAMP终极部署cat <<-EOF-------------------------------------------------------------------------| LAMP终极部署 V1.0 |-------------------------------------------------------------------------| a. 部署Apache服…

Go 泛型之明确使用时机与泛型实现原理

Go 泛型之明确使用时机与泛型实现原理 文章目录 Go 泛型之明确使用时机与泛型实现原理一、引入二、何时适合使用泛型&#xff1f;场景一&#xff1a;编写通用数据结构时场景二&#xff1a;函数操作的是 Go 原生的容器类型时场景三&#xff1a;不同类型实现一些方法的逻辑相同时…

pycharm python环境安装

目录 1.Python安装 2.PyQt5介绍 3.安装pyuic 4.启动designer.exe 5.pyinstaller(打包发布程序) 6.指定源安装 7.PyQt5-tools安装失败处理 8.控件介绍 9.错误记录 1.NameError: name reload is not defined 10.开发记录 重写报文输出和文件 ​编辑 1.Python安装 点…

docker里面不能使用vim的解决办法

docker里面不能使用vim的解决办法 目录 docker里面不能使用vim的解决办法 1.在使用时会出现 2.在使用这些都不能解决的时候考虑 3.测试是否可用 1.在使用时会出现 bash: vim: command not found 出现这种错误时首先考虑使用 apt-get update 然后在用 apt-get install …

Oracle中decode函数详解

Oracle中decode函数详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将深入探讨Oracle数据库中的DECODE函数&#xff0c;这是一种强大的条件…

大模型入门0: 基础知识

transformerscaling law分布式训练 自然语言处理包括几大任务 NLP: 文本分类&#xff0c;词性标注&#xff0c;信息检索NLG&#xff1a;机器翻译&#xff0c;自动摘要&#xff0c;问答QA、对话机器ChatBot Transformer T5 Bert GPT in context learning: (zero-shot tra…

vue3中pinia的使用及持久化(详细解释)

解释一下pinia&#xff1a; Pinia是一个基于Vue3的状态管理库&#xff0c;它提供了类似Vuex的功能&#xff0c;但是更加轻量化和简单易用。Pinia的核心思想是将所有状态存储在单个store中&#xff0c;并且将store的行为和数据暴露为可响应的API&#xff0c;从而实现数据&#…

cnn lstm结合网络

目录 特征处理例子&#xff1a; cnn 5张图片一组&#xff0c;提取特征后&#xff0c;再给lstm&#xff0c;进时间序列分类。 特征处理例子&#xff1a; import torch# 假设 tensor 是形状为 15x64 的张量 tensor torch.arange(15 * 2).reshape(15, 2) # 生成顺序编号的张量&…

中国历史长河图

历史是一种传承和记忆&#xff0c;不管你是否承认&#xff0c;他就在那里。你也身处其中&#xff0c;就像一条小鱼身处波澜壮阔的大河中&#xff0c;没留下一点痕迹。 了解历史&#xff0c;不是只为了多知道些古代人物、历史事件&#xff0c;或者为了应付考试。而是应该想到&am…

2024年元旦,祝福所有的人和事物

愿风调雨顺&#xff0c;国泰民安。 愿人生平安健康&#xff0c;安居乐业&#xff0c;福慧增长&#xff0c;丰足富饶。 愿我们能一起进步。

今年努力输出的嵌入式Linux视频

今年努力了一波&#xff0c;几个月周六日无休&#xff0c;自己在嵌入式linux工作有些年头&#xff0c;结合自己也是一直和SLAM工程师对接&#xff0c;所以输出了一波面向SLAM算法工程师Linux课程&#xff0c;当然嵌入式入门的同学也可以学习。下面是合作的官方前面发的宣传文章…