相关文章推荐
谈吐大方的山楂  ·  有没有使用python将pdf转html的工 ...·  8 月前    · 
风度翩翩的麦片  ·  【腾讯优图首度开源深度学习框架ncnn】主打 ...·  1 年前    · 
冷静的鞭炮  ·  Python调用本地打印机打印PDF文件 - 知乎·  1 年前    · 
强悍的楼梯  ·  如何手动关闭elementUI的popove ...·  1 年前    · 
不拘小节的电影票  ·  论如何从APP测试搞到刷机 - 知乎·  1 年前    · 
Code  ›  高并发场景下,到底先更新缓存还是先更新数据库?开发者社区
大数据 云数据库 缓存服务器 缓存
https://cloud.tencent.com/developer/article/1774867
奔跑的足球
1 年前
作者头像
用户1516716
0 篇文章

高并发场景下,到底先更新缓存还是先更新数据库?

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > A周立SpringCloud > 高并发场景下,到底先更新缓存还是先更新数据库?

高并发场景下,到底先更新缓存还是先更新数据库?

作者头像
用户1516716
发布 于 2021-01-18 14:34:20
2.5K 2
发布 于 2021-01-18 14:34:20
举报

在大型系统中,为了减少 数据库 压力通常会引入缓存机制,一旦引入缓存又很容易造成缓存和数据库数据不一致,导致用户看到的是旧数据。

为了减少数据不一致的情况,更新缓存和数据库的机制显得尤为重要,接下来带领大家踩踩坑。

Cache aside

Cache aside 也就是 旁路缓存 ,是比较常用的缓存策略。

(1) 读请求 常见流程

Cache aside 读请求

应用首先会判断缓存是否有该数据,缓存命中直接返回数据,缓存未命中即缓存穿透到数据库,从数据库查询数据然后回写到缓存中,最后返回数据给客户端。

(2) 写请求 常见流程

Cache aside 写请求

首先更新数据库,然后从缓存中删除该数据。

看了写请求的图之后,有些同学可能要问了:为什么要删除缓存,直接更新不就行了?这里涉及到几个坑,我们一步一步踩下去。

Cache aside踩坑

Cache aside策略如果用错就会遇到深坑,下面我们来逐个踩。

踩坑一:先更新数据库,再更新缓存

如果同时有两个 写请求 需要更新数据,每个写请求都先更新数据库再更新缓存,在并发场景可能会出现数据不一致的情况。

先更新数据库,再更新缓存

如上图的执行过程:

(1) 写请求1 更新数据库,将 age 字段更新为18;

(2) 写请求2 更新数据库,将 age 字段更新为20;

(3) 写请求2 更新缓存,缓存 age 设置为20;

(4) 写请求1 更新缓存,缓存 age 设置为18;

执行完预期结果是数据库 age 为20,缓存 age 为20,结果缓存 age为18,这就造成了缓存数据不是最新的,出现了脏数据。

踩坑二:先删缓存,再更新数据库

如果 写请求 的处理流程是 先删缓存再更新数据库 ,在一个 读请求 和一个 写请求 并发场景下可能会出现数据不一致情况。

先删缓存,再更新数据库

如上图的执行过程:

(1) 写请求 删除缓存数据;

(2) 读请求 查询缓存未击中(Hit Miss),紧接着查询数据库,将返回的数据回写到缓存中;

(3) 写请求 更新数据库。

整个流程下来发现 数据库 中age为20, 缓存 中age为18,缓存和数据库数据不一致,缓存出现了脏数据。

踩坑三:先更新数据库,再删除缓存

在实际的系统中针对 写请求 还是推荐 先更新数据库再删除缓存 ,但是在理论上还是存在问题,以下面这个例子说明。

先更新数据库,再删除缓存

如上图的执行过程:

(1) 读请求 先查询缓存,缓存未击中,查询数据库返回数据;

(2) 写请求 更新数据库,删除缓存;

(3) 读请求 回写缓存;

整个流程操作下来发现 数据库age为20 , 缓存age为18 ,即数据库与缓存不一致,导致应用程序从缓存中读到的数据都为旧数据。

但我们仔细想一下,上述问题发生的概率其实非常低,因为通常数据库更新操作比内存操作耗时多出几个数量级,上图中最后一步回写缓存(set age 18)速度非常快,通常会在更新数据库之前完成。

如果这种极端场景出现了怎么办?我们得想一个兜底的办法: 缓存数据设置过期时间 。通常在系统中是可以允许少量的数据短时间不一致的场景出现。

Read through

在 Cache Aside 更新模式中,应用代码需要维护两个数据源头:一个是缓存,一个是数据库。而在 Read-Through 策略下,应用程序无需管理缓存和数据库,只需要将数据库的同步委托给缓存提供程序 Cache Provider 即可。所有数据交互都是通过 抽象缓存层 完成的。

Read-Through流程

如上图,应用程序只需要与 Cache Provider 交互,不用关心是从缓存取还是数据库。

在进行大量读取时, Read-Through 可以减少数据源上的负载,也对缓存服务的故障具备一定的弹性。如果缓存服务挂了,则缓存提供程序仍然可以通过直接转到数据源来进行操作。

Read-Through 适用于多次请求相同数据的场景 ,这与 Cache-Aside 策略非常相似,但是二者还是存在一些差别,这里再次强调一下:

  • 在 Cache-Aside 中,应用程序负责从数据源中获取数据并更新到缓存。
  • 在 Read-Through 中,此逻辑通常是由独立的缓存提供程序(Cache Provider)支持。

Write through

Write-Through 策略下,当发生数据更新(Write)时,缓存提供程序 Cache Provider 负责更新底层数据源和缓存。

缓存与数据源保持一致,并且写入时始终通过 抽象缓存层 到达数据源。

Cache Provider 类似一个代理的作用。

Write-Through流程

Write behind

Write behind 在一些地方也被成为 Write back , 简单理解就是:应用程序更新数据时只更新缓存, Cache Provider 每隔一段时间将数据刷新到数据库中。说白了就是 延迟写入 。

Write behind流程

如上图,应用程序更新两个数据,Cache Provider 会立即写入缓存中,但是隔一段时间才会批量写入数据库中。

这种方式有优点也有缺点:

  • 优点 是数据写入速度非常快,适用于频繁写的场景。
  • 缺点 是缓存和数据库不是强一致性,对一致性要求高的系统慎用。

总结一下

学了这么多,相信大家对缓存更新的策略都已经有了清晰的认识。最后稍稍总结一下。

缓存更新的策略主要分为三种:

  • Cache aside
  • Read/Write through
  • Write behind

Cache aside 通常会先更新数据库,然后再删除缓存,为了兜底通常还会将数据设置缓存时间。

Read/Write through 一般是由一个 Cache Provider 对外提供读写操作,应用程序不用感知操作的是缓存还是数据库。

Write behind简单理解就是延迟写入,Cache Provider 每隔一段时间会批量输入数据库,优点是应用程序写入速度非常快。

好了,今天先到这里了,大家学会了吗?

- END -

本文参与 腾讯云自媒体分享计划 ,分享自微信公众号。
原始发表:2021-01-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除
缓存
数据库
sql

本文分享自 IT牧场 微信公众号, 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

缓存
数据库
sql
评论
登录 后参与评论
0 条评论
热度
最新
登录 后参与评论
关于作者
用户1516716
0
文章
0
累计阅读量
0
获赞
前往专栏
目录
  • Cache aside
  • Cache aside踩坑
  • Read through
  • Write through
  • Write behind
  • 总结一下
  • 社区

    • 专栏文章
    • 阅读清单
    • 互动问答
    • 技术沙龙
    • 技术视频
    • 团队主页
    • 腾讯云TI平台
  • 活动

    • 自媒体分享计划
    • 邀请作者入驻
    • 自荐上首页
    • 技术竞赛
  • 资源

    • 技术周刊
    • 社区标签
    • 开发者手册
    • 开发者实验室
  • 关于

    • 社区规范
    • 免责声明
    • 联系我们
    • 友情链接

腾讯云开发者

扫码关注腾讯云开发者

扫码关注腾讯云开发者

领取腾讯云代金券

热门产品

  • 域名注册
  • 云服务器
  • 区块链服务
  • 消息队列
  • 网络加速
  • 云数据库
  • 域名解析
  • 云存储
  • 视频直播

热门推荐

  • 人脸识别
  • 腾讯会议
  • 企业云
  • CDN加速
  • 视频通话
  • 图像分析
  • MySQL 数据库
  • SSL 证书
  • 语音识别

更多推荐

  • 数据安全
  • 负载均衡
  • 短信
  • 文字识别
  • 云点播
  • 商标注册
  • 小程序开发
  • 网站监控
  • 数据迁移

Copyright © 2013 - 2023 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有

深圳市腾讯计算机系统有限公司 ICP备案/许可证号: 粤B2-20090059 深公网安备号 44030502008569

腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287

问题归档 专栏文章 快讯文章归档 关键词归档 开发者手册归档 开发者手册 Section 归档

Copyright © 2013 - 2023 Tencent Cloud.

All Rights Reserved. 腾讯云 版权所有

登录 后参与评论
2
 
推荐文章
谈吐大方的山楂  ·  有没有使用python将pdf转html的工具 - CSDN文库
8 月前
风度翩翩的麦片  ·  【腾讯优图首度开源深度学习框架ncnn】主打手机端,同类cpu框架最快-腾讯云开发者社区-腾讯云
1 年前
冷静的鞭炮  ·  Python调用本地打印机打印PDF文件 - 知乎
1 年前
强悍的楼梯  ·  如何手动关闭elementUI的popover_element关闭popover回调事件_大大大石頭的博客-CSDN博客
1 年前
不拘小节的电影票  ·  论如何从APP测试搞到刷机 - 知乎
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号