缓存读写策略 - Cache Aside.md

场景描述

比如一条数据同时存在数据库、缓存,现在你要更新此数据,你会怎么更新?

先更新数据库?还是先更新缓存?

其实这两种方式都有问题。

(1)先更新数据库,后更新缓存

这样会造成数据不一致。

A 先把数据库更新为 123,由于网络问题,更新缓存的动作慢了。

这时,B 去更新数据库了,改为了 456,紧接着把缓存也更新为 456。

现在 A 更新缓存的请求到了,把缓存更新为了 123。

那么这时数据就不一致了,数据库里是最新的 456,而缓存是 123,是旧数据。

因为数据库更新、缓存更新这2个动作不是原子的,在高并发操作时,这2个动作直接会插入其他动作。

(2)先更新缓存,再更新数据库

同样可能数据不一致。

缓存更新成功,数据为最新的,但数据库更新失败,回滚了,还是旧数据。

还是非原子操作的原因。

Cache Aside 策略

其实,在更新数据时,我们可以不更新缓存,而是删除缓存中的数据,在读取数据时,发现缓存中没有,再从数据库中读取数据,更新到缓存中。

这就是 Cache Aside 策略(旁路缓存策略)

  • 读策略步骤

  • 写策略步骤

写时可以不可以先删除缓存?不行!

例如这个场景:

A 先删了缓存,还没等数据库更新完成呢,就被 B 把缓存更新为了旧值。

  • 注意

Cache Aside 策略也是不保证数据一致性的,它的作用是大大减少不一致性。

某些极端情况还是存在不一致,如果业务上不允许,可以考虑加分布式锁。

原文地址:https://www.cnblogs.com/yogoup/p/12033159.html

时间: 2024-10-10 09:59:21

缓存读写策略 - Cache Aside.md的相关文章

Redis缓存失效策略

一.背景 线上你写代码的时候,想当然的认为写进 redis 的数据就一定会存在,后面导致系统各种 bug,谁来负责? 常见的有两个问题: 往 redis 写入的数据怎么没了? 可能有同学会遇到,在生产环境的 redis 经常会丢掉一些数据,写进去了,过一会儿可能就没了.我的天,同学,你问这个问题就说明 redis 你就没用对啊.redis 是缓存,你给当存储了是吧? 啥叫缓存?用内存当缓存.内存是无限的吗,内存是很宝贵而且是有限的,磁盘是廉价而且是大量的.可能一台机器就几十个 G 的内存,但是可

HTML5离线缓存(Application Cache)

HTML5离线缓存又名Application Cache,是从浏览器的缓存中分出来的一块缓存区,要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源. Manifest 文件 manifest 文件是简单的文本文件,它告知浏览器被缓存的内容(以及不缓存的内容). manifest 文件可分为三个部分: CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存 NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓

利用Spring.Net技术打造可切换的分布式缓存读写类

利用Spring.Net技术打造可切换的Memcached分布式缓存读写类 Memcached是一个高性能的分布式内存对象缓存系统,因为工作在内存,读写速率比数据库高的不是一般的多,和Radis一样具有高效的读写和分布式的优势,上一篇博文<Memcached在Windows下的配置和使用>已经对介绍过它在windows上的配置和使用. 新建ICacheWriter类--CacheWriter的接口,以达到通过配置文件可以切换缓存读写方式,例如,缓存读写也可以通过httpruntime.cach

.NET4缓存过期策略摘录

以下是网上搜索的资料,仅供参考: 资料一:ASP.NET缓存中Cache过期的三种策略(转自51CTO) 我们在页面上添加三个按钮并双击按钮创建事件处理方法,三个按钮使用不同的过期策略添加ASP.NET缓存. <asp:Button ID="btn_InsertNoExpirationCache" runat="server" Text="插入永不过期缓存" OnClick="btn_InsertNoExpirationCache

zt:缓存一致性(Cache Coherency)入门 cach coherency

http://www.infoq.com/cn/articles/cache-coherency-primer http://www.cnblogs.com/xybaby/p/6641928.html 本文是RAD Game Tools程序员Fabian “ryg” Giesen在其博客上发表的<Cache coherency primer>一文的翻译,经作者许可分享至InfoQ中文站.该系列共有两篇,本文系第一篇. 我计划写一些关于多核场景下数据组织的文章.写了第一篇,但我很快意识到有大量的

高性能服务器架构(二):缓存清理策略

原文链接:https://mp.weixin.qq.com/s/OopSWbLrzT-V11VDZOpxJw 虽然使用缓存思想似乎是一个很简单的事情,但是缓存机制却有一个核心的难点,就是--缓存清理.我们所说的缓存,都是保存一些数据,但是这些数据往往是会变化的,我们要针对这些变化,清理掉保存的"脏"数据,却可能不是那么容易. 首先我们来看看最简单的缓存数据--静态数据.这种数据往往在程序的运行时是不会变化的,比如Web服务器内存中缓存的HTML文件数据,就是这种.事实上,所有的不是由外

.NET 数据库缓存依赖策略实现

处理大型门户网站 一般都需要 使用缓存技术这个web加速器在 PHP 和 java 一般 使用的是 基于squid 来做. 当然在 windows .NET 平台也是可以的 squid有 windows版本.这个以后再去研究,现在 就介绍一下 .NET 自带的 缓存策略.Microsoft的petshop就用到了它; 一.基于数据库触发(设置缓存依赖策略,当数据库中数据发生变化时,触发缓存失效;但微软提供的解决方案目前仅支持SQL Server,如果是ORACLE需要自己实现触发接口). 二.基

redis数据结构、持久化、缓存淘汰策略

Redis 单线程高性能,它所有的数据都在内存中,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能损耗问题.redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器. 1.Redis数据结构及简单操作指令 String.list.set.hash.zset(有序set) 总体来说redis都是通过Key-Value的形式来存储数据的.只是不用数据类型Value的形式不同. String:最简单数据结构,比如我们

redis缓存淘汰策略

缓存淘汰策略 介绍 当 Redis 内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换 (swap).交换会让 Redis 的性能急剧下降,对于访问量比较频繁的 Redis 来说,这样龟速的存取效率基本上等于不可用. 在生产环境中我们是不允许 Redis 出现交换行为的,为了限制最大使用内存,Redis 提供了配置参数 maxmemory 来限制内存超出期望大小. 当实际内存超出 maxmemory 时,Redis 提供了几种可选策略 (maxmemory-policy) 来让用户自己