直接硬核干货,去掉前戏。

方案大致说明

1:假设对redis中存在一对key,value的对应关系是 key=money,value=666

2:当修改线程修改key时先将key设置成value=666_write,(这里需要说明的是:线上实际应用可以将_wirte改成非常复杂的UUID等字符串,只要保证不要和线上实际set的值冲突即可,例如666_write_@#$%^&*_qwerty

3:当读取时发现key的存在读取标识666_read_@#$%^&*_qwerty,发现有其他读取线程已经在从DB中load数据了,这种情况休眠一下重试就可以了,不需要从DB中load数据,因为这样做会引起大量线程访问数据库引发灾难。如果不存在读取标识则判断一下是否含有写入标识若不存在则直接返回数据即可,若存在读取标识将所有读取标识去掉之后看看是否为空,不为空则返回当前value即可。

4:为什么一个字符串会出现多个写入标识呢。假设线程A和B对 key=money,value=666的数据进行修改,那么线程A将value变成了value=666_write_@#$%^&*_qwerty,这个时候线程B也来掺和一下,会变成666_write_@#$%^&*_qwerty_write_@#$%^&*_qwerty,这个地方是需要注意的。同时也会出现业务数据被删除了这个时候加上了修改标记,value变成_write_@#$%^&*_qwerty这种只有修改标识但是没有业务数据的的情况。

5:还有一个需要特别注意的是setnx在客户端2.8之后 支持超时时间,这块需要设置一个超时的时间处理,防止读取线程setnx之后服务器挂了,引起永远无法同步的问题,至于超时时间设置成多少和实际环境有关。

6:同时也会出现_read_@#$%^&*_qwerty_write_@#$%^&*_qwerty这种同时带有read和write的情况,出现在并发读取的场景。

7:这种需要DB缓存强一致读写应该在master中进行,不应该在slave中读,很有可能出现延迟导致问题

8:redis主从切换这种极端的场景出现在读取或者修改的情况下也会引起数据不一致的问题,一般上线这种问题的解决方案是跨机房多机缓存或者允许短期内不一致的job任务定时校验兜底等。

总结起来就是一下几点:

当存在_read_@#$%^&*_qwerty时说明有读取线程正请求DB,从新load对象。

当存在_write_@#$%^&*_qwerty时说明当前key正在被写入。

当存在多个_write_@#$%^&*_qwerty时 存在并发修改。

当有_read_@#$%^&*_qwerty和_write_@#$%^&*_qwerty时 存在读和写的并发。

读取详细设计方案

更新时设计方案:

其他问题加群讨论吧 QQ群号:825199617。

DB缓存一致性的更多相关文章

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

    问题 我们在生产环境中使用SQLite时中发现建表报“table xxx already exists”错误,但DB文件中并没有该表.后面才发现这个是SQLite在实现过程中的一个bug,而这个bug ...

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

    当你的项目数据量上去了之后,通常会遇到两种情况,第一种情况应是最大可能的使用cache来对抗上层的高并发,第二种情况同样也是需要使用分库 分表对抗上层的高并发...逼逼逼起来容易,做起来并不那么乐观, ...

  3. Web应用中的缓存一致性问题

    上篇总结了缓存中出现频率比较高的一些问题,今天详细说说web应用中的缓存一致性问题. 主要说以下三个方面 数据库与缓存中数据不一致出现的情形 发生不一致时的优化思路 如何保证数据库与缓存的一致性 先来 ...

  4. Redis缓存穿透、击穿、雪崩,数据库与缓存一致性

    Redis作为高性能非关系型(NoSQL)的键值对数据库,受到了广大用户的喜爱和使用,大家在项目中都用到了Redis来做数据缓存,但有些问题我们在使用中不得不考虑,其中典型的问题就是:缓存穿透.缓存雪 ...

  5. Java的多线程机制系列:(二)缓存一致性和CAS

    一.总线锁定和缓存一致性 这是两个操作系统层面的概念.随着多核时代的到来,并发操作已经成了很正常的现象,操作系统必须要有一些机制和原语,以保证某些基本操作的原子性.首先处理器需要保证读一个字节或写一个 ...

  6. Web集群缓存一致性的思考

    共享cache+数据库实现缓存一致性: 1.1 memcache + mongo+定时器 1.1.1 memcache 优点:web集群共享数据 缺点:数据生命周期的不可预估性 1.1.2 mongo ...

  7. 缓存一致性(Cache Coherency)入门

    作者: Fabian “ryg” Giesen  来源: infoq 参考原文:http://fgiesen.wordpress.com/2014/07/07/cache-coherency/ 本文是 ...

  8. 缓存一致性(Cache Coherency)入门(转)

    参考原文:http://fgiesen.wordpress.com/2014/07/07/cache-coherency/ 本文是RAD Game Tools程序员Fabian “ryg” Giese ...

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

    今天阅读了一下大型网络技术架构这本苏中的分布式缓存一致性hash算法这一节,针对大型分布式系统来说,缓存在该系统中必不可少,分布式集群环境中,会出现添加缓存节点的需求,这样需要保障缓存服务器中对缓存的 ...

随机推荐

  1. SQL查询月、天、周、年(MySql的实例对比)

    SQL Server实现 日期部分 缩写 year yy, yyyy quarter qq, q month mm, m dayofyear dy, y day dd, d week wk, ww w ...

  2. @PostConstruct注解原理解析

    所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 正文 @PostConstruct注解使用简介 在了解一个东西的原理之前,我们得初步的懂得如何 ...

  3. C++标准库里自带的数值类型和字符串互相转换函数

    需要包含头文件 #include <string> 数值类型转成string类型: string to_string(int val); string to_string(unsigned ...

  4. <script> 为什么不再使用 type="text/javascript" 【问题】

    1.为什么在 <script> 标签中不需要使用 type="text/javascript" 就可以写jQuery代码 ? <head> <scri ...

  5. 关于NavigationBar的笔记

    1常用几个方法 全局 //设置navigationBar 的类型 ,ps: status bar的状态受navigationbar控制(当用navigationcontroller时,通过设置此属性改 ...

  6. crunch离线密码生成

     Crunch是一种创建密码字典工具,按照指定的规则生成密码字典,可以灵活的制定自己的字典文件. 一.Crunch为kali自带工具之一在kali环境下进行,默认基于26个小写英文字母. 语法:cru ...

  7. bash基础——终端

    前言 自学Linux的时候,我们用的显示器+键盘 是物理终端.Linux开机后,会在物理终端(显示器)之上,以软件的方式虚拟出多个终端,CentOS是6个.Ctrl+Alt+F1~6切换 默认情况下, ...

  8. sqlmap中文帮助文档

    Options(选项):  -h,--help             显示基本帮助消息并退出  -hh                     显示高级帮助消息并退出  --version      ...

  9. synchronized 和 Lock 有什么区别?(未完成)

    synchronized 和 Lock 有什么区别?(未完成)

  10. ndk学习之C语言基础复习----虚拟内存布局与malloc申请

    在这一次中来学习一下C语言的内存布局,了解它之后就可以解释为啥在用malloc()申请的内存之后需要用memset()来对内存进行一下初始化了,首先来了解一下物理内存与虚拟内存: 物理内存:通过物理内 ...