【redis-05】redis保证和mysql数据一致性

redis系列整体栏目


内容链接地址
【一】redis基本数据类型和使用场景https://zhenghuisheng.blog.csdn.net/article/details/142406325
【二】redis的持久化机制和原理https://zhenghuisheng.blog.csdn.net/article/details/142441756
【三】redis缓存穿透、缓存击穿、缓存雪崩https://zhenghuisheng.blog.csdn.net/article/details/142577507
【四】redisson实现分布式锁实战和源码剖析https://zhenghuisheng.blog.csdn.net/article/details/142646301
【五】redis保证和mysql数据一致性https://zhenghuisheng.blog.csdn.net/article/details/142687101

如需转载,请输入:https://blog.csdn.net/zhenghuishengq/article/details/142687101

redis保证和mysql数据一致性

  • 一,redis保证和mysql数据一致性
    • 1,数据不一致原因
      • 1.1,更新缓存出现的问题
      • 1.2,删除缓存出现的问题
      • 1.3,理想情况
    • 2,数据不一致解决方案
      • 2.1,延迟双删(不推荐)
      • 2.2,消息队列
      • 2.3,分布式锁
      • 2.4,canal同步

一,redis保证和mysql数据一致性

在项目中,redis一般作为缓存使用,从而加快系统的读写效率和吞吐量,但是数据最终一般是存储在mysql中,因此在实际开发中,尤其是在高并发的互联网项目中,经常会遇到这种mysql和redis数据不一致的情况。如在一个电商的扣减库存的场景中,如果redis中的数据和mysql中的数据没有保证一致,那么就很有可能造成超卖的问题,那么平台就可能会因为这个问题造成商家的损失

1,数据不一致原因

数据不一致原因无非就是那几种原因,在分布式场景中,并发带来的问题,网络抖动带来的问题,分布式事务不一致问题等。

1.1,更新缓存出现的问题

如下面这个场景,以扣减库存的场景为例,假设有100个库存,此时多个线程对该商品下单。如在一个4s的时间线内,线程1和线程2先后下单,在不考虑mysql事务的情况下,来查看以下会出现的问题,其流程如下:

  • 首先在第一秒时线程1进行一个扣减库存操作,但是由于网络卡顿的原因,导致在第4秒才更新redis的缓存只为95,并且写入mysql的数据也为95;
  • 在第二秒时线程2也下单10件商品,此时redis缓存还是100,因此操作的还是这个100,那么扣减库存之后的值变成90,然后在第三秒时更新缓存值为90;
  • 由于暂时不考虑事务,因此此时mysql的值为100-10-5为85,而redis中的缓存值由于覆盖的问题导致还是95,此时就出现了mysql和redis值不一致的问题。

在这里插入图片描述

1.2,删除缓存出现的问题

更新缓存指的是在写完mysql数据之后立马就去更新缓存,效率可能会低一些,除了更新缓存还可以删除缓存,就是在写的时候不更新缓存,而是直接删掉缓存,再读数据的时候进行redis缓存数据的写入,如以下流程

  • 首先线程1在第一秒时扣减5个库存,然后将缓存删除,此时redis中的值为95
  • 第二秒一个线程3来读数据,发现缓存没有就读数据库,此时数据库的值为95
  • 在第三秒有一个用户下单,扣减库存操作为10,此时mysql中为85,删除缓存
  • 由于卡顿问题,在第四秒线程3才执行更新缓存操作,但是拿的值不是最新值,导致原本redis值为85的,由于覆盖的问题此时redis的值为95,导致redis和mysql数据不一致的问题

在这里插入图片描述

1.3,理想情况

在理想情况下,我们更希望的是每个命令都可以顺序执行,将各种无法预料的并发问题直接改成串行化操作。当然如果在此基础上进行优化的话,在加锁的同时,考虑加一把互斥锁,从而保证读读共享,其他互斥的操作

在这里插入图片描述

2,数据不一致解决方案

2.1,延迟双删(不推荐)

延迟双删顾名思义,就是延迟一段时间,删除某些线程因为卡顿原因导致更新缓存的值出错,如下图线程3由于卡顿,造成缓存覆盖的问题,从而导致了redis中缓存和mysql中的值出现不一致的问题,但是通过延迟双删的方式,对缓存做两次删除,并且两次删除间设置一定的时间间隔,从而解决部分卡顿问题

在这里插入图片描述

其伪代码如下,首先是第一次删除缓存,然后休眠个300秒,然后再次删除缓存。

#第一次删除缓存
redis.delKey(phone:1001)
#休眠300毫秒
Thread.sleep(300)
#再删除缓存
redis.delKey(phone:1001)

延迟双删的方式也不能完全解决这种数据不一致问题,只能减少这种数据不一致概率的事件发生,因为不能保证某些查询的线程要卡顿多久,比如我设置300毫秒,但是有的线程卡顿一秒,因此也不能够完全解决。

其次所有的写操作都得删除两次,这对redis来说会有一定的性能影响,除了本身的操作之外,还得额外的增加一段延时的时间,对于使用redis的初衷来说就没那么友好,更加的适用于 读多写少 的场景,如商品首页等。

2.2,消息队列

如果为了强一致性,那么可以直接使用消息队列来使用,其本质也很简单,将并行的操作,全部加入到消息队列中串行执行。

消息队列确实可以解决这种数据不一致问题,因为都串行执行,不会有那种并行和并发的问题。但是使用消息队列需要额外的引入中间件,还需要考虑数据的持久化,不丢失,以及顺序消费等问题,如果整个系统是已经有再使用消息中间件的话,如kafka、rocketMq这些,那么是可以考虑使用这种方式的

在这里插入图片描述

2.3,分布式锁

在上一篇中,讲解了redis分布式锁的使用和底层原理,分布式锁的机制和上面的消息队列的机制一样,都是将并行执行的操作方式改成串行的执行方式,直接通过redisson实现的分布式锁即可

RLock lock = redisson.getLock(PHONE_ID);
lock.lock();
lock.unlock();

通过这种分布所锁机制,可以保证数据的串行执行,不出现redis数据脏写问题和覆盖问题

在这里插入图片描述

当然也可以通过redis的 读写锁 进行优化,部分代码如下,直接在读的接口中使用读锁,使用后需要释放锁

//获取一把读写锁
RReadWriteLock readWriteLock = redissoon.getReadWriteLock(lockKey);
//获取读锁
RLock readLock = readWriteLock.readLock();
//加锁
readLock.lock();
//解锁
readLock.unlock();

写的接口中使用写锁即可,使用后也许把锁释放。

//获取一把读写锁
RReadWriteLock readWriteLock = redissoon.getReadWriteLock(lockKey);
//获取写锁
RLock writeLock = readWriteLock.writeLock();
//加锁
writeLock.lock();
//解锁
writeLock.unlock();

不管是原生的Redission锁还是这种读写锁,底层都是通过lua脚本实现,这种方式也更加的适用于 读多写少 的场景。相对于消息队列,可以选这种方式实现

2.4,canal同步

上面几种方式都是需要通过手动的删除缓存或者更新缓存的数据实现数据同步,除了上面几种方式之外,还可以用阿里的canal开源中间件来实现数据的同步,并且通过这种方式,不需要认为的去操作缓存

其原理也很简单,就类似于mysql的主从复制原理,伪装成一个从结点,监听mysql的binlog日志,然后将执行的mysql的操作,通过这个canal中间件同步到redis中。

在这里插入图片描述

这样的话,也不需要去考虑redis的更新和删除操作,只需要查即可,查不到再查mysql。

当然如果想直接使用这种canal中间件的话,需要手动的重新部署,也相当于重新引入了一个新的中间件。如果数据量大的话,可以考虑使用这种方式来解决数据不一致问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不只是前端,后端、产品和测试也需要了解的浏览器知识(一)

目录标题 一、我们为什么要了解浏览器?1. 对于前端开发者2. 对于后端开发者 二、浏览器发展概述1. 宏观发展2. 微观发展 三、浏览器核心部件1. 浏览器界面介绍2. 目前浏览器的使用的渲染引擎和解释器总结3. 浏览器的解释器 四、各家浏览器目前的市场占比五、整体总结…

索尼MDR-M1:超宽频的音频盛宴,打造沉浸式音乐体验

在音乐的世界里,每一次技术的突破都意味着全新的听觉体验。 索尼,作为音频技术的先锋,再次以其最新力作——MDR-M1封闭式监听耳机,引领了音乐界的新潮流。 这款耳机以其超宽频播放和卓越的隔音性能,为音乐爱好者和专…

tornado

Tornado通过使用非阻塞网络I/O,可以扩展到数以万计的开放链接,非常适合 长时间轮询,WebSockets和其他需要与每个用户建立长期连接的应用程序。 特点 注重性能优越,速度快解决高并发异步非阻塞websockets 长连接内嵌了HTTP服务器…

04 B-树

目录 常见的搜索结构B-树概念B-树的插入分析B-树的插入实现B树和B*树B-树的应用 1. 常见的搜索结构 种类数据格式时间复杂度顺序查找无要求O(N)二分查找有序O( l o g 2 N log_2N log2​N)二分搜索树无要求O(N)二叉平衡树无要求O( l o g 2 N log_2N log2​N)哈希无要求O(1) 以…

IO模型介绍

一、理解IO 网络通信的本质就是进程间通信,进程间通信本质就是IO TCP中的IO接口:read / write / send / recv,本质都是:等 拷贝 所以IO的本质就是:等 拷贝 那么如何高效的IO? 减少“等”在单位时间的…

CORDIC算法笔记整理

CORDIC算法有两种模式,分别为旋转模式和向量模式。而在数字硬件实现混频处理时,CORDIC算法是比较好的方法,使用的是CORDIC的旋转模式,只需通过移位操作和加法就可以实现频谱搬移的乘法操作。 1 CORDIC算法理解 1.1 单次旋转 对…

SpringCloud学习记录|day1

学习材料 2024最新SpringCloud微服务开发与实战,java黑马商城项目微服务实战开发(涵盖MybatisPlus、Docker、MQ、ES、Redis高级等) 学redis讲到微服务就停了,nginx也是。 所以嘛,我终于来到微服务了。 复习MyBatisP…

CMU 10423 Generative AI:lec14(Vision Language Model:CLIP、VQ-VAE)

文章目录 1 概述2 CLIP (Used in GPT-V)3 VQ-VAE (Used in Gemini)**VQ-VAE 详细笔记****VQ-VAE 的模块组成与数据流** **1. 输入数据****2. 编码器(Encoder)****2.1 编码器的作用****2.2 数据流与维度变化****2.3 编码器输出** **3. 量化器(…

IP 数据包分包组包

为什么要分包 由于数据链路层MTU的限制,对于较⼤的IP数据包要进⾏分包. 什么是MTU MTU相当于发快递时对包裹尺⼨的限制.这个限制是不同的数据链路对应的物理层,产⽣的限制. • 以太⽹帧中的数据⻓度规定最⼩46字节,最⼤1500字节,ARP数据包的⻓度不够46字节,要在后⾯补填 充…

云栖实录 | 开源大数据全面升级:Native 核心引擎、Serverless 化、湖仓架构引领云上大数据发展

本文根据2024云栖大会实录整理而成,演讲信息如下: 演讲人: 王 峰 | 阿里云智能集团研究员、开源大数据平台负责人 李 钰|阿里云智能集团资深技术专家 范 振|阿里云智能集团高级技术专家 李劲松|阿里云…

MongoDB聚合操作及索引底层原理

目录 链接:https://note.youdao.com/ynoteshare/index.html?id=50fdb657a9b06950fa255a82555b44a6&type=note&_time=1727951783296 本节课的内容: 聚合操作: 聚合管道操作: ​编辑 $match 进行文档筛选 ​编辑 将筛选和投影结合使用: ​编辑 多条件匹配: …

【AI】AIOT简介

随着技术的快速发展,人工智能AI和物联网IoT已经成为当今最热门的技术领域。AIOT是人工智能和物联网的结合,使物联网设备更加智能化,能够进行自主决策和学习的技术。 通过物联网产生、收集来自不同维度的、海量的数据存储于云端、边缘端&#…

数据治理006-数据标准的管理

元数据的分类和标准有哪些? 一、元数据的分类 元数据可以根据其描述的对象和属性不同,被分为不同的类型。以下是几种常见的元数据分类方法: 基于数据的类型:根据数据的类型,元数据可以被分为结构化元数据、非结构化元…

SQL连接Python

对于运营部门的Yoyo来说,她想要知道夜曲优选的订单都来自哪些省份,每个省份的总订单数以及总订单金额分别是多少。 这时小鹿就会通过SQL对连接的数据库进行查询,再将结果传递给Python处理,并帮助Yoyo生成可视化图表。 我们先来快…

拆解维修飞科剃须刀

原因 用了好几年的剃须刀,经过一次更换电池。后来上面的盖帽松动,无法合盖,经过把弹片矫正后修复。最近一次”大力出奇迹“的操作直接断送了这个老伤员最后的可能性。最终只能花了将近十块大洋买了一套盖着和中间座。简单更换了一下。 记录…

目前最好用的爬虫软件是那个?

作为一名数据工程师,三天两头要采集数据,用过十几种爬虫软件,也用过Python爬虫库,还是建议新手使用现成的软件比较方便。 这里推荐3款不错的自动化爬虫工具,八爪鱼、亮数据、Web Scraper 1. 八爪鱼爬虫 八爪鱼爬虫是一…

Linux:深入理解冯诺依曼结构与操作系统

目录 1. 冯诺依曼体系结构 1.1 结构分析 1.2 存储结构分布图 2. 操作系统 2.1 概念 2.2 如何管理 2.3 什么是系统调用和库函数 1. 冯诺依曼体系结构 1.1 结构分析 不管是何种计算机,如个人笔记本电脑,服务器,都是遵循冯诺依曼结构。…

可视化图表与源代码显示配置项及页面的动态调整功能分析

可视化图表与源代码显示配置项及页面的动态调整功能分析 文章目录 可视化图表与源代码显示配置项及页面的动态调整功能分析1.分析图表源代码2.分析源代码显示功能**完整代码参考:** 3.分析源代码显示及动态调整**完整代码参考:** 4.分析代码编辑器及运行…

华为云LTS日志上报至观测云最佳实践

华为云LTS简介 华为云云日志服务(Log Tank Service,简称 LTS),用于收集来自主机和云服务的日志数据,通过海量日志数据的分析与处理,可以将云服务和应用程序的可用性和性能最大化,为您提供实时、…

基于SSM的爱心慈善公益网站的设计与实现

文未可获取一份本项目的java源码和数据库参考。 选题意义 随着经济的不断进步,发展各种进行公益事业的渠道不断的出现,作为一个礼仪之邦,中华民族一直秉承先人的团结与友善精神,对社会和他人给予帮助关怀。但中国的公益事业相对…