分布式缓存数据库一致性问题

缓存和数据库一致性问题,有很多解决方案,没有最完美的方案,只有适合自身业务的尽可能完美的方案。

缓存由于其高并发和高性能的特征,已经在项目中被广泛应用。

  查询时一般先查询缓存,如果缓存命中的话,那么直接将数据返回。

  如果缓存中没有数据(如失效,或者根本没设置数据),那么,应用程序先从数据库中查询数据,如果不为空,则将数据放在缓存中。

那么更新时,怎么处理缓存和数据库呢?先更新数据库后更新缓存?先更新数据库后更新缓存?或者先淘汰缓存后更新数据库?

为什么没有先更新缓存后更新数据库?

  1):如果更新数据库失败,那么就造成了数据不一致

先更新数据库后更新缓存的问题

  1):两个线程并发更新数据库再更新缓存可能出现缓存更新顺序问题

  2):如果更新频繁,读少的情况,那么缓存也被频繁更新,造成不必要的开销

  3):如果缓存的值是需要经过一系列复杂计算的,那么每次都去更新缓存无疑是浪费性能的

先删缓存后更新数据库的问题:

  1):线程A删除缓存更新完数据库前,线程B没有命中缓存,从数据库中查询到了更新前的值存入缓存中

  解决方案:延时双删策略(推荐使用)

  即先删除缓存,再更新数据库,休眠一段时间,再删除缓存

  伪代码如下:

public void write(String key,Object data){
    redis.delKey(key);
    db.updateData(data);
    Thread.sleep(1000); redis.delKey(key);
 }

为什要休眠1秒钟?为了将这1秒内造成的脏数据删除,可能有线程读取到了更新前的旧数据还未来得及写入缓存

休眠的时间多少如何确定?评估自身项目读数据业务逻辑的耗时,在这基础了加100ms即可。可以确保脏数据已经写入缓存中

读写分离怎么办?

  也是采用延时双删策略,休眠时间确保完成主从同步

为了避免休眠造成吞吐量降低,可以将第二次删除作为异步操作

第二次删除失败怎么办?

  删除在更新期间写入缓存的旧值失败

  解决方案:将需要删除的key发送到消息队列,然后自己消费消息,获得需要删除的key,继续重试删除操作,直到成功。

先更新数据库后删缓存

  即Cache Aside Pattern,即缓存旁路模式

  失效:应用程序先从缓存中取数据,没有取到,则从数据库中取数据,成功后,放到缓存中

  命中:应用程序从缓存中渠道数据,然后返回

  更新:先把数据存到数据库中,成功后,再删除缓存

原文地址:https://www.cnblogs.com/yangyongjie/p/11094437.html

时间: 2024-10-10 18:45:16

分布式缓存数据库一致性问题的相关文章

分布式缓存的一致性hash算法

基本场景 比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache : 常规取余的hash算法 hash(key) % N 对于N台缓存服务器构成的集群缓存,依次编号为0 - (N-1)先对要存储的key进行hash取值,然后用hash值对N取余,得到一个在缓存服务器编号区间的一个数字,则将当前key存到这台服务器

大型网站技术架构,6网站的伸缩性架构之分布式缓存集群的伸缩性设计

和所有服务器都部署相同应用的应用服务器集群不同,分布式缓存服务器集群中不同的服务器中缓存的数据各不相同,缓存访问请求不可以在缓存服务器集群中的任意一台处理,必须先找到缓存有需要数据的服务器,然后才能访问. 这个特点制约了分布式缓存集群的伸缩性设计,因为新上线的缓存服务器没有缓存任何数据,而已下线的缓存服务器还缓存这网站的许多热点数据. 必须让新上线的缓存服务器对整个分布式缓存集群影响最小,也就是说新加入的缓存服务器应使整个缓存服务器集群中已经缓存的数据尽可能还被访问到,这是分布式缓存集群伸缩性设

分布式缓存Memcached

   分布式缓存服务器,既然用到数据缓存很明显就是想高效性的获取数据,大容量的存储数据.为了可以缓存大量的数据以及可以高效获取数据,那么分布式缓存数据库就要解决数据可以水平线性扩展,这样可以扩大数据容量,其次是缓存在大并发下本身的性能问题.分布式缓存服务需要做如下考虑,需要水平线性扩展,那么就要有合理的路由算法来解决负载均衡问题,以及提供数据备份,这样某结点服务器done机时,可以启动副本.这样就需要考虑数据一致性问题.分布式缓存的核心技术包括首先是内存本身的管理问题,包括了内存的分配,管理和回

分布式之数据库和缓存双写一致性方案解析

引言 为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作. 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存.又或者是先删除缓存,再更新数据库,其实大家存在很大的争议.目前没有一篇全面的博客,对这几种方案进行解析.于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章. 正文 先做一个说明,从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案.这种方案下,我们可以对存入缓存的数据设置

缓存与数据库一致性保证

本文主要讨论这么几个问题: (1)啥时候数据库和缓存中的数据会不一致 (2)不一致优化思路 (3)如何保证数据库与缓存的一致性 一.需求缘起 上一篇<缓存架构设计细节二三事>引起了广泛的讨论,其中有一个结论:当数据发生变化时,"先淘汰缓存,再修改数据库"这个点是大家讨论的最多的. 上篇文章得出这个结论的依据是,由于操作缓存与操作数据库不是原子的,非常有可能出现执行失败. 假设先写数据库,再淘汰缓存:第一步写数据库操作成功,第二步淘汰缓存失败,则会出现DB中是新数据,Cach

缓存与数据库一致性保证(转)

本文主要讨论这么几个问题: (1)啥时候数据库和缓存中的数据会不一致 (2)不一致优化思路 (3)如何保证数据库与缓存的一致性 一.需求缘起 上一篇<缓存架构设计细节二三事>(点击查看)引起了广泛的讨论,其中有一个结论:当数据发生变化时,"先淘汰缓存,再修改数据库"这个点是大家讨论的最多的. 上篇文章得出这个结论的依据是,由于操作缓存与操作数据库不是原子的,非常有可能出现执行失败. 假设先写数据库,再淘汰缓存:第一步写数据库操作成功,第二步淘汰缓存失败,则会出现DB中是新数

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

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

【58沈剑架构系列】缓存与数据库一致性保证

本文主要讨论这么几个问题: (1)啥时候数据库和缓存中的数据会不一致 (2)不一致优化思路 (3)如何保证数据库与缓存的一致性 一.需求缘起 上一篇<缓存架构设计细节二三事>(点击查看)引起了广泛的讨论,其中有一个结论:当数据发生变化时,“先淘汰缓存,再修改数据库”这个点是大家讨论的最多的. 上篇文章得出这个结论的依据是,由于操作缓存与操作数据库不是原子的,非常有可能出现执行失败. 假设先写数据库,再淘汰缓存:第一步写数据库操作成功,第二步淘汰缓存失败,则会出现DB中是新数据,Cache中是旧

分布式缓存技术memcached学习系列(四)—— 一致性hash算法原理

文章主目录 分布式一致性hash算法简介 分布式一致性hash算法使用背景 环形hash空间 映射key到环形hash空间 映射server节点到hash空间 映射key到server节点 添加server节点 删除server节点 虚拟节点的引入 节点变化数据分流的问题 一致性hash算法与取模算法的比较 参考文档 回到顶部 分布式一致性hash算法简介 当你看到“分布式一致性hash算法”这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法