缓存与数据库双写一致性几种策略分析
作者:京东零售 于泷
一、背景
在高并发场景中,为防止大量请求直接访问数据库,缓解数据库压力,常用的方式一般会增加缓存层起到缓冲作用,减少数据库压力。引入缓存,就会涉及到缓存与数据库中数据如何保持一致性问题,本文将对几种缓存与数据库保证数据一致性的使用方式进行分析。为保证高并发性能,以下分析场景不考虑执行的原子性及加锁等强一致性要求的场景,仅追求最终一致性。
二、读取过程
三、更新过程
更新操作有多种策略,各有优劣,主要针对此场景进行分析
策略1:先更新db,再删除缓存(常用的Cache-Aside Pattern旁路缓存)
问题:
1.如果更新db成功,删缓存失败,将导致数据不一致
2.极端场景,请求A读,B写
1)此时缓存刚好失效 2)A查库得到旧值 3)B更新DB成功
4)B删除缓存 5)A将查到的旧值更新到缓存中
此场景的发生需要步骤2)查db 始终慢于 3)的更新db,才能导致4)先于5)执行,通常db的查询是要快于写入的,所以此极端场景的产生过于严格,不易发生
策略2:先更新db,再更新缓存
问题:
1.并发更新场景下,更新缓存会导致数据不一致
2.根据读写比,考虑是否有必要频繁同步更新缓存,而且,如果构造缓存中数据过于复杂,或者数据更新频繁,但是读取并不频繁的情况,还会造成不必要的性能损耗
此种方式不推荐
策略3:先更新缓存,再更新db
同上,不推荐
策略4:先删缓存,再更新db
先删缓存,虽然解决了策略1中,后删缓存如果失败的场景,但也会发生不一致的问题
例如:请求 A 删除缓存,这时请求B来查,就会击穿到数据库,B读取到旧的值后写入缓存,A正常更新db,由于时间差导致数据不一致的情况
策略5:缓存延时双删
该策略兼容了策略1和策略4,解决了先删缓存还是后删缓存的问题,如策略1中,更新db后删缓存失败和策略4中的不一致场景,该策略可以将延时时间内(比如延时10ms)所造成的缓存脏数据,再次删除。但是,如果延时删缓存失败,策略4中不一致问题还会发生,同时延时的实现,如创建线程,或者引入mq异步,可能会增加系统复杂度问题。
策略6:变种双删,前置缓存过期时间
该策略针对策略1中后删缓存失败的场景,前置一层缓存数据过期时间(具体时间根据自身系统本身评估,如可覆盖db读写耗时或一致性容忍度等),更新db后就算删缓存失败,在expire时间后也能保证缓存中无数据。同时,前置expire失败,或者更新db失败,都不会影响数据一致。
能够解决策略4中的问题:请求 A 删除缓存,这时请求B来查,就会击穿到数据库,B读取到旧的值后写入缓存,A正常更新db,由于时间差导致数据不一致的情况,描述图如下:
本策略中步骤1为expire缓存,不会发生击穿缓存到数据库的情况,数据将直接返回。除非更极端情况,如下图:
expire时间没有覆盖住更新db的耗时,类似策略1中极端场景,此处不赘述
四、总结
对于每种方案策略,各有利弊,但一致性问题始终存在(文章开头排除了原子性和锁),只是发生的几率在一点点慢慢变小了,方案的评估不仅要根据自身系统的业务场景,如读写比、并发量、一致性容忍度,还要考虑系统复杂度,投入产出比等,寻找最合适的方案。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
泛全志芯片内核G2D模块sample深究
1. g2d 模块概述 g2d 主要功能: 1)旋转:支持90、180、270旋转; 2)镜像反转:H / V; 3) scale:放缩 4)格式转换:yuv 转 rgb 等,多种格式相互间转换; 5)透明叠加功能:实现两个rgb图片叠加; 6)矩形填充,等诸多功能; 2. g2d 配置 1)源码目录:tina-v853-docker/kernel/linux-4.9/drivers/char/sunxi_g2d 2)make kernel_menuconfig 配置 Device Drivers > Character devices > sunxi g2d driver 按空格键选中【*】 3)Device Tree 设备树配置 sun8iw21p1.dtsi路径: tina-v853-docker/kernel/linux-4.9/arch/arm/boot/dts/sun8iw21p1.dtsi g2d: g2d@05410000 { compatible = "allwinner,sunxi-g2d"; reg = <0x0 0x05410000 0x0...
- 下一篇
多云转晴:Databend 的天空计算之路
作者:尚卓燃(PsiACE) 澳门科技大学在读硕士,Databend 研发工程师实习生 Apache OpenDAL(Incubating) Committer https://github.com/psiace/ 内容提要:本文将会介绍天空计算的背景,以及 Databend 是如何从数据存储、数据管理、数据共享等视角考虑跨云数据存储与访问的。 背景 云计算时代的开端可以追溯到 2006 年,当时 AWS 开始提供 S3 和 EC2 服务。2013 年,云原生概念刚刚被提出,甚至还没有一个完整的愿景。时间来到 2015 年 CNCF 成立,接下来的五年中,这一概念变得越来越流行,并且成为技术人绕不开的话题。 根据 CNCF 对云原生的定义:云原生技术使组织能够在公共、私有和混合云这类现代、动态的环境中构建和运行可扩展的应用程序。典型示例包括:容器、服务网格、微服务、不变基础设施和声明式 API 。 然而,无论是公有云还是私有云、无论是云计算还是云服务,在天空中都已经存在太多不同类型的“云”。每个“云”都拥有自己独特的 API 和生态系统,并且彼此之间缺乏互操作性,能够兼容的地方也是寥寥...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- 2048小游戏-低调大师作品
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库