数据库和缓存一致性的问题

【云时代的技术博客】【http://cloudate.net/?p=379】

2015/01/13  |  DB,Memcache,并发和多线程 |  罗伯特

有一个key/value存储在数据库中,但是缓存在memcache中,对这个key/value有高并发的查询和更新操作,怎么保证数据库和缓存的一致性呢?

方案1 – 更新数据库时失效缓存

 when updateDb(key) invalideCache(key)
 when query(key) updateCache(key)

问题: 查询时有不一致的情况,如下,

 Step1: Thread1 getDb(key) = A
 Step2: Thread3 updateDb(key) = B
 Step3: Thread2 getDb(key) = B
 Step4: Thread2 updateCache(key) = B
 Step5: Thread1 updateCache(key) = A

当前最新数据应该是Thread3更新的B, 但是缓存里面是A,出现了不一致的现象,即使在更新缓存的时候使用CAS,还是会出现后者覆盖前者,还是有不一致的现象。

方案2 – 更新数据库时更新缓存

 Step1: cas get cache
 Step2: update db
 Setp3: cas set cache

问题: 更新数据库的时候直接提交,那么缓存里数据是B,数据库里面是A,如下,

 Thread1 cas get cache with uniqueNum = 1
 Thread2 cas get cache with uniqueNum = 1
 Thread2 update DB with new value B
 Thread2 cas set cache B with uniqueNum = 1
 Thread1 update DB with new value A
 Thread1 cas set cache A with uniqueNum = 1, fail

方案3 – 利用数据库的事物/乐观锁和缓存的CAS

数据库在更新缓存成功后进行提交,如果CAS更新缓存失败,那么滚回数据库的提交。

 Thread1 cas get cache with uniqueNum = 1
 Thread1 update DB with new value A
 Thread1 cas set cache A with uniqueNum = 1
 Thread1 commit update DB
 Thread2 cas get cache with uniqueNum = 1
 Thread2 update DB with new value B
 Thread2 cas set cache B with uniqueNum = 1
 Thread2 commit update DB

暂时没有想出来方案3有任何问题,欢迎大家拍砖。

时间: 2024-10-08 06:01:45

数据库和缓存一致性的问题的相关文章

Redis和数据库的缓存一致性问题

redis和数据库的缓存一致性问题 缓存的读取流程 缓存更新策略 按照数据库和缓存的更新顺序有两种更新策略:(1)先更新数据库,再更新缓存:(2)先删除缓存,再更新数据库.(3)先更新数据库,再删缓存 先更新数据库,再更新缓存 这套方案,大家是普遍反对的.为什么呢?有如下两点原因. 原因一(线程安全角度) 同时有请求A和请求B进行更新操作,那么会出现 (1)线程A更新了数据库(2)线程B更新了数据库(3)线程B更新了缓存(4)线程A更新了缓存 这就出现请求A更新缓存应该比请求B更新缓存早才对,但

缓存一致性和跨服务器查询的数据异构解决方案canal

当你的项目数据量上去了之后,通常会遇到两种情况,第一种情况应是最大可能的使用cache来对抗上层的高并发,第二种情况同样也是需要使用分库 分表对抗上层的高并发...逼逼逼起来容易,做起来并不那么乐观,由此引入的问题,不见得你有好的解决方案,下面就具体分享下. 一:尽可能的使用Cache 比如在我们的千人千面系统中,会针对商品,订单等维度为某一个商家店铺自动化建立大约400个数据模型,然后买家在淘宝下订单之后,淘宝会将订单推 送过来,订单会在400个模型中兜一圈,从而推送更贴切符合该买家行为习惯的

数据异构解决方案缓存一致性和跨服务器查询

缓存一致性和跨服务器查询的数据异构解决方案canal 当你的项目数据量上去了之后,通常会遇到两种情况,第一种情况应是最大可能的使用cache来对抗上层的高并发,第二种情况同样也是需要使用分库 分表对抗上层的高并发...逼逼逼起来容易,做起来并不那么乐观,由此引入的问题,不见得你有好的解决方案,下面就具体分享下. 一:尽可能的使用Cache 比如在我们的千人千面系统中,会针对商品,订单等维度为某一个商家店铺自动化建立大约400个数据模型,然后买家在淘宝下订单之后,淘宝会将订单推 送过来,订单会在4

由一个bug引发的SQLite缓存一致性探索

问题 我们在生产环境中使用SQLite时中发现建表报“table xxx already exists”错误,但DB文件中并没有该表.后面才发现这个是SQLite在实现过程中的一个bug,而这个bug与数据字典的一致性相关,下面这篇文章主要讨论SQLite的缓存机制,以及缓存一致性实现的策略,希望对大家了解SQLite缓存机制有一定的帮助. 缓存 SQLite中缓存主要包括两方面,数据字典缓存和数据页缓存.SQLite本身是一个文件数据库,所有的数据都在一个DB文件中,文件以块(page)的形式

分布式缓存一致性hash算法理解

今天阅读了一下大型网络技术架构这本苏中的分布式缓存一致性hash算法这一节,针对大型分布式系统来说,缓存在该系统中必不可少,分布式集群环境中,会出现添加缓存节点的需求,这样需要保障缓存服务器中对缓存的命中率,就有很大的要求了: 采用普通方法,将key值进行取hash后对分布式缓存机器数目进行取余,以集群3台分布式缓存为例子: 对于数据进行取hash值然后对3其进行取余,余数为0则进入node 0,余数位1则进入node1,余数位2则进入node2. 如果增加一个节点则对4进行取余,则会将node

redis系列之数据库与缓存数据一致性解决方案

redis系列之数据库与缓存数据一致性解决方案 数据库与缓存读写模式策略 写完数据库后是否需要马上更新缓存还是直接删除缓存? (1).如果写数据库的值与更新到缓存值是一样的,不需要经过任何的计算,可以马上更新缓存,但是如果对于那种写数据频繁而读数据少的场景并不合适这种解决方案,因为也许还没有查询就被删除或修改了,这样会浪费时间和资源 (2).如果写数据库的值与更新缓存的值不一致,写入缓存中的数据需要经过几个表的关联计算后得到的结果插入缓存中,那就没有必要马上更新缓存,只有删除缓存即可,等到查询的

缓存一致性问题

缓存更新策略 被动更新: 设置key过期的时间,让其自动失效. 主动更新: 更新DB的时候,同时更新缓存 一般业务都是主动更新和被动更新结合使用. 缓存更新实现 调用者调用.失败重试3次,再失败,扔给消息队列异步处理.消息队列从数据库取最新的更新,保证成功 DB中间件监听DB变化,更新缓存 利用DB中间件监听DB变化(比如阿里的Canal中间件,点评的Puma),从而对缓存进行更新. 这种办法的一个好处就是:把缓存的更新逻辑,和业务逻辑解藕.业务只更新DB,缓存的更新被放在另外一个专门的系统里面

ASP.NET MVC 数据库依赖缓存的实现

当数据库中的信息发生变化的时候,应用程序能够获取变化的通知是缓存依赖得以实现的基础.应用程序可以通过轮询获取数据变化的信息,使用轮询的话也不可能重新查一次后再和以前的数据做比较,如果这样的话如果我一个表里面有1000行数据我要是读100次的话是不是得比较1000 x 100 次,显然这种方法是不可行的,那怎么办呢?大家都学过触发器吧,实现数据库依赖缓存的轮询机制就是通过触发器来实现的. 实现步骤简单分析:     首先创建一个用于记录监控信息的表,表的字段就两个一个是表名,一个是版本号.然后,对

数据库和缓存

1. 什么是Cookie对象:Cookie 提供了一种在 Web 应用程序中存储用户特定信息的方法.例如,当用户访问您的站点时,您可以使用 Cookie 存储用户首选项或其他信息.当该用户再次访问您的网站时,应用程序便可以检索以前存储的信息.   Session对象:Session对象是HttpSessionState类的一个实例,其功能和Application对象类似,都是用来存储跨网页程序的变量或者对象,但Session对象和Application对象有些特性存在着差异.Session对象只