一、更新策略
1、如果Redis中有数据,需要和数据库中的值相同。
2、如果Redis中无数据,数据库中的最新值要对Redis进行同步更新。
二、读写缓存
1、同步直写策略
写入数据库也同步写Redis缓存,缓存和数据库中的数据一致;对于读写缓存来说,要保证缓存和数据库中的数据一致,就要保证同步直写策略。
2、异步缓写策略
某些业务运行中,MySQL数据更新之后,允许在一定时间后再进行Redis数据同步,比如物流系统。
当出现异常情况时,不得不将失败的动作重新修补,需要借助rabbitmq或kafka进行重写。
三、双检加锁策略
多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。
其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。
后面的线程进来发现已经有缓存了,就直接走缓存。
public String get(String key){ // 从Redis缓存中读取 String value = redisTemplate.get(key); if(value != null){ return value; } synchronized (RedisTest.class){ // 重新尝试从Redis缓存中读取 value = redisTemplate.get(key); if(value != null){ return value; } // 从MySQL数据库中查询 value = studentDao.get(key); // 写入Redis缓存 redisTemplate.setnx(key,value,time); return value; } }
四、数据库和缓存一致性的更新策略
1、先更新数据库,再更新Redis
按照常理出牌的话,应该都是如此吧?那么,这种情况下,会有啥问题呢?
如果更新数据库成功后,更新Redis之前异常了,会出现什么情况呢?
数据库与Redis内缓存数据不一致。
2、先更新缓存,再更新数据库
多线程情况下,会有问题。
比如
线程1更新redis = 200;
线程2更新redis = 100;
线程2更新MySQL = 100;
线程1更新MySQL = 200;
结果呢,Redis=100、MySQL=200;我擦!
3、先删除缓存,再更新数据库
线程1删除了Redis的缓存数据,然后去更新MySQL数据库;
还没等MySQL更新完毕,线程2杀来,读取缓存数据;
但是,此时MySQL数据库还没更新,线程2读取了MySQL中的旧值,然后线程2,还会将旧值写入Redis作为数据缓存;
线程1更新完MySQL数据后,发现Redis中已经有数据了,之前都删过了,那我就不更新了;
完蛋了。。
延时双删
延时双删可以解决上面的问题,只要sleep的时间大于线程2读取数据再写入缓存的时间就可以了,也就是线程1的二次清缓存操作要在线程2写入缓存之后,这样才能保证Redis缓存中的数据是最新的。
/** * 延时双删 * @autor 哪吒编程 */ public void deleteRedisData(Student stu){ // 删除Redis中的缓存数据 jedis.del(stu); // 更新MySQL数据库数据 studentDao.update(stu); // 休息两秒 try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } // 删除Redis中的缓存数据 jedis.del(stu); }
延迟双删最大的问题就是sleep,在效率为王的今天,sleep能不用还是不用为好。
你不睡我都嫌你慢,你还睡上了…
4、先更新数据库,再删除缓存
线程1先更新数据库,再删除Redis缓存;
线程2在线程1删除Redis缓存之前发起请求,得到了未删除的Redis缓存;
线程1此时才删除Redis缓存数据;
问题还是有,这翻来覆去的,没完没了了。
这种情况如何解决呢?
引入消息中间件解决战斗,再一次详细的复盘一下。
更新数据库;
数据库将操作信息写入binlog日志;
订阅程序提取出key和数据;
尝试删除缓存操作,发现删除失败;
将这些数据信息发送到消息中间件中;
从消息中间件中获取该数据,重新操作;
5、总结
哪吒推荐使用第四种方式,先更新数据库,再删除缓存。
方式①和方式②缺点太过明显,不考虑;
方式③中的sleep,总是让人头疼;
方式④是一个比较全面的方案,但是增加了学习成本、维护成本,因为增加了消息中间件。
五、MySQL主从复制工作原理
1、当 master 主服务器上的数据发生改变时,则将其改变写入二进制事件日志文件中;
2、salve 从服务器会在一定时间间隔内对 master 主服务器上的二进制日志进行探测,探测其是否发生过改变,
如果探测到 master 主服务器的二进制事件日志发生了改变,则开始一个 I/O Thread 请求 master 二进制事件日志;
3、同时 master 主服务器为每个 I/O Thread 启动一个dump Thread,用于向其发送二进制事件日志;
4、slave 从服务器将接收到的二进制事件日志保存至自己本地的中继日志文件中;
5、salve 从服务器将启动 SQL Thread 从中继日志中读取二进制日志,在本地重放,使得其数据和主服务器保持一致;
6、最后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒。
以上是MySQL数据库和Redis缓存一致性的更新策略是什么的详细内容。更多信息请关注PHP中文网其他相关文章!

MySQL值得学习,因为它是强大的开源数据库管理系统,适用于数据存储、管理和分析。1)MySQL是关系型数据库,使用SQL操作数据,适合结构化数据管理。2)SQL语言是与MySQL交互的关键,支持CRUD操作。3)MySQL的工作原理包括客户端/服务器架构、存储引擎和查询优化器。4)基本用法包括创建数据库和表,高级用法涉及使用JOIN连接表。5)常见错误包括语法错误和权限问题,调试技巧包括检查语法和使用EXPLAIN命令。6)性能优化涉及使用索引、优化SQL语句和定期维护数据库。

MySQL适合初学者学习数据库技能。1.安装MySQL服务器和客户端工具。2.理解基本SQL查询,如SELECT。3.掌握数据操作:创建表、插入、更新、删除数据。4.学习高级技巧:子查询和窗口函数。5.调试和优化:检查语法、使用索引、避免SELECT*,并使用LIMIT。

MySQL通过表结构和SQL查询高效管理结构化数据,并通过外键实现表间关系。1.创建表时定义数据格式和类型。2.使用外键建立表间关系。3.通过索引和查询优化提高性能。4.定期备份和监控数据库确保数据安全和性能优化。

MySQL是一个开源的关系型数据库管理系统,广泛应用于Web开发。它的关键特性包括:1.支持多种存储引擎,如InnoDB和MyISAM,适用于不同场景;2.提供主从复制功能,利于负载均衡和数据备份;3.通过查询优化和索引使用提高查询效率。

SQL用于与MySQL数据库交互,实现数据的增、删、改、查及数据库设计。1)SQL通过SELECT、INSERT、UPDATE、DELETE语句进行数据操作;2)使用CREATE、ALTER、DROP语句进行数据库设计和管理;3)复杂查询和数据分析通过SQL实现,提升业务决策效率。

MySQL的基本操作包括创建数据库、表格,及使用SQL进行数据的CRUD操作。1.创建数据库:CREATEDATABASEmy_first_db;2.创建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入数据:INSERTINTObooks(title,author,published_year)VA

MySQL在Web应用中的主要作用是存储和管理数据。1.MySQL高效处理用户信息、产品目录和交易记录等数据。2.通过SQL查询,开发者能从数据库提取信息生成动态内容。3.MySQL基于客户端-服务器模型工作,确保查询速度可接受。

构建MySQL数据库的步骤包括:1.创建数据库和表,2.插入数据,3.进行查询。首先,使用CREATEDATABASE和CREATETABLE语句创建数据库和表,然后用INSERTINTO语句插入数据,最后用SELECT语句查询数据。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

Dreamweaver CS6
视觉化网页开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1
功能强大的PHP集成开发环境