Redis篇之双写一致性

一、什么的双写一致性

1.定义

双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致。

2.正常情况

读操作:缓存命中,直接返回;缓存没命中查询数据库,写入缓存,设定超时时间。

写操作:延时双删。

3.非正常情况

(1)先删除缓存,再修改数据库

                                          

缓存和数据库的初始数据:                                                        对应线程1的第一步操作:

                                                                       

对应线程2的操作:                                                                      对应线程1的第二步操作:

                                                                           

最后,可以发现缓存的数据与数据库的数据不一致了,也就是脏数据

(2)先修改数据库,再删除缓存

                                    

初始数据如下图,由于缓存数据超时,线程1只能查数据库,拿到的数据为10。

               

线程2这时先更新数据库的数据,再删除缓存。                        

 

最后,线程1把之前读到的数据也就是10放入缓存之中。

最后,可以发现缓存的数据与数据库的数据不一致了,也就是脏数据

4.延时双删

        从非正常情况就可以知道为什么需要再删除一次缓存,就是为了降低脏数据的出现。那为什么要延时呢?因为我们的数据库一般是主从模式的,就是读写分离的,数据需要从主节点同步到从节点,所以需要延时删除缓存。但是,这个延时的时间却不好控制。综述,延时双删可以降低脏数据出现的风险,但不能保证数据的强一致性。

5.那怎么保证数据强一致性

(1)分布式锁

        缺点:性能低。

(2)读写锁

因为数据库大多数都是读多写少。所以对读操作加共享锁,其他线程都可以读操作,但不能写操作。在写操作加排他锁,其他线程不得读也不能写。这样不仅保证了数据的强一致性,还兼顾了性能。

读写锁的代码可以参考网上的,核心就是使用redission,获取读写锁然后操作。

(3)异步通知

实际开发中,大部分都可以有延时的,主要是使用消息队列(mq)。

(4)使用Canal

        Canal是基于数据库的主从同步来实现的。通过二进制日志(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但不包括数据查询 (SELECT、SHOW)语句。这样的优点就是不会在业务代码上有复杂其他的代码了。

6.面试的时候应该如何回答

(1)强一致性的业务回答

面试官:redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)

候选人:就说我最近做的这个项目,里面有xxxx(根据自己的简历上写)的功能,需要让数据库与redis高度保持一致,因为要求时效性比较高,我们当时采用的读写锁保证的强一致性。

我们采用的是redisson实现的读写锁,在读的时候添加共享锁,可以保证读读不互斥,读写互斥。当我们更新数据的时候,添加排他锁,它是读写,读读都互斥,这样就能保证在写数据的同时是不会让其他线程读数据的,避免了脏数据。这里面需要注意的是读方法和写方法上需要使用同一把锁才行。

面试官:那这个排他锁是如何保证读写、读读互斥的呢?

候选人:其实排他锁底层使用也是setnx,保证了同时只能有一个线程操作锁住的方法

面试官:你听说过延时双删吗?为什么不用它呢?

候选人:延迟双删,如果是写操作,我们先把缓存中的数据删除,然后更新数据库,最后再延时删除缓存中的数据,其中这个延时多久不太好确定,在延时的过程中可能会出现脏数据,并不能保证强一致性,所以没有采用它。

(2)允许有延时的业务回答

面试官:redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)

候选人:嗯!就说我最近做的这个项目,里面有xxxx(根据自己的简历上写)的功能,数据同步可以有一定的延时(符合大部分业务)

我们当时采用的阿里的canal组件实现数据同步:不需要更改业务代码,部署一个canal服务。canal服务把自己伪装成mysql的一个从节点,当mysql数据更新以后,canal会读取binlog数据,然后在通过canal的客户端获取到数据,更新缓存即可。

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

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

相关文章

猫头虎分享已解决Bug || IndexError: index 3 is out of bounds for axis 0 with size 3

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

深入学习《大学计算机》系列之第1章 1.7节——图灵机的一个例子

一.欢迎来到我的酒馆 第1章 1.7节,图灵机的一个例子。 目录 一.欢迎来到我的酒馆二.图灵机2.1 艾伦-图灵简介2.2 图灵机简介 三.图灵机工作原理3.1 使用图灵机打印二进制数3.2 图灵机工作原理总结 四.总结 二.图灵机 本节内容主要介绍计算机科学之父——艾伦-图灵、…

java 执行方式和类加载过程

java默认属于混合执行: 编译和解释并存 java先进行解释执行,遇到多次重复的代码会把它编程成可执行文件,方便下次直接执行。 可以通过VM参数来修改执行方式。 类加载过程

前端JavaScript篇之ajax、axios、fetch的区别

目录 ajax、axios、fetch的区别AjaxAxiosFetch总结注意 ajax、axios、fetch的区别 在Web开发中,ajax、axios和fetch都是用于与服务器进行异步通信的技术,但它们在实现方式和功能上有所不同。 Ajax 定义与特点:Ajax是一种在无需重新加载整个…

记录Dynamo每个节点的运行时间

不知道小伙伴们在写Dynamo程序的时候,有没有遇到这种问题→程序运行很慢,但是却不知道该优化哪些节点,可以提高程序运行的速度。 今天呢,就给大家分享一个节点包→TuneUp,在节点包管理器里就可以下载,安装…

10个常考的前端手写题,你全都会吗?(上)

前言 📫 大家好,我是南木元元,热爱技术和分享,欢迎大家交流,一起学习进步! 🍅 个人主页:南木元元 今天来分享一下10个常见的JavaScript手写功能。 目录 1.实现new 2.call、apply、…

stm32Cubmax PWM实验

一、基本概念 PWM(脉冲宽度调制)是一种常用于控制电子设备的技术。它通过改变电信号的脉冲宽度来控制设备的输出功率或电流。在PWM中,所谓的脉冲宽度是指一个周期内脉冲的持续时间。周期是指脉冲重复的时间间隔。 在PWM中,一个周…

Hive窗口函数详解

一、 窗口函数知识点 1.1 窗户函数的定义 窗口函数可以拆分为【窗口函数】。窗口函数官网指路: LanguageManual WindowingAndAnalytics - Apache Hive - Apache Software Foundationhttps://cwiki.apache.org/confluence/display/Hive/LanguageManual%20Windowing…

机器学习2--逻辑回归(案列)

糖尿病数据线性回归预测 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.datasets import load_diabetes diabetesload_diabetes() datadiabetes[data] targetdiabetes[target] feature_namesdiabetes[feature_names] data.shape df …

提升MySQL访问性能

1. 读写分离 设置多个从数据库,从数据库可能在多个机器中。写操作在主数据库进行主数据库提供数据的主要依据 缓解了MySQL的读压力。 主从复制原理图如下 如果对于读操作有一致性要求,那么读操作去主数据库即可。 2. 连接池 因为一个请求必须要…

springboot177健身房管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

关于创建vue项目报错command failed: npm install --loglevel error

一、首先 在这个目录下有个文件叫.vuerc 二、其次 进去之后把里面的"useTaobaoRegistry": false,修改下,我之前是true,后来改成了false才成功。