Redis与MySQL的数据情感:延迟双删的秘密揭示

news2025/7/18 1:01:25

Redis与MySQL的数据情感:延迟双删的秘密揭示

  • 前言
  • 第一:mysql与redis数据不一致问题
  • 第二:为什么需要双删
  • 第三:如何实现延迟双删

前言

在现代应用程序中,MySQL 和 Redis 是两种常用的数据存储解决方案。然而,它们之间的数据不一致性问题一直是开发人员头痛的难题。Redis 延迟双删是一种有趣的技术,能够解决这一难题,本篇博客将带你深入了解如何使用它来确保 MySQL 与 Redis 数据的一致性,就像一场奇迹一样。

第一:mysql与redis数据不一致问题

MySQL 与 Redis 数据不一致性问题是在将这两种数据存储系统结合使用时经常遇到的挑战。以下是一些常见的原因和挑战:

  1. 异步性质:

    • MySQL通常是一个持久性数据库,而Redis是一个内存数据库,以提供快速访问。因此,Redis通常是异步地从MySQL中读取数据,并且在同步期间可能发生延迟,这可能导致数据不一致性。
  2. 数据缓存问题:

    • Redis常用于缓存数据,以提高访问速度。但是,如果Redis中的数据与MySQL中的数据不同步,用户可能会看到过期或不一致的数据。
  3. 写入操作问题:

    • 当应用程序执行写入操作时,这些操作必须同步到MySQL和Redis。如果写入到其中一个存储中失败,会导致不一致性。
  4. 并发问题:

    • 在高并发环境中,多个客户端可能同时更新MySQL和Redis中的数据。如果不加以控制,这可能导致数据不一致。

为解决这些问题,可以采取以下策略:

  1. 事务和同步写入:

    • 使用事务确保数据同时写入MySQL和Redis,以减少不一致性。如果写入其中一个失败,回滚事务,以确保数据的一致性。
  2. 定期数据同步:

    • 定期将MySQL中的数据同步到Redis中,以减少数据不一致的机会。这可以通过定时任务或触发器来实现。
  3. 缓存失效策略:

    • 使用适当的缓存失效策略,以确保Redis中的数据与MySQL中的数据保持一致。例如,可以设置数据在一定时间后自动失效,或者在MySQL数据更新时手动刷新Redis中的数据。
  4. 分布式锁:

    • 在并发写入场景中,使用分布式锁来协调写入操作,以避免数据不一致。

需要注意的是,解决MySQL与Redis数据不一致性问题需要根据具体应用的需求和架构选择合适的方法和工具。此外,需要在代码中添加适当的注释以便维护和理解代码的逻辑。

第二:为什么需要双删

image-20230429162619219

⚠️不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况

先删除缓存

  • 如果先删除Redis缓存数据,然后还没有来得及写入MySQL,另一个线程就来读取
  • 这个时候发现缓存为空,则去MySQL数据库读取旧数据写入缓存,此时缓存中为脏数据
  • 然后数据库更新后发现Redis和MySQL出现了数据不一致的问题

后删除缓存

  • 如果先写了库,然后再删除缓存,不幸的写库的线程挂了,导致了缓存没有删除
  • 这个时候就会直接读取旧缓存,最终也导致了数据不一致的情况
  • 因为写和读是并发的,没办法保证顺序,就会出现缓存和数据库不一致的问题

第三:如何实现延迟双删

延迟双删策略主要是为了维护数据一致性,特别是在高并发的情况下。它确保了在写入数据库之前,缓存数据被删除,然后在延迟一段时间后再次删除缓存,以应对以下情况:

  1. 数据修改并发问题:如果多个请求同时尝试修改数据库中的数据,而缓存中的数据没有被删除,就有可能导致数据不一致。某个请求可能会在缓存中获取旧数据并写入数据库,然后其他请求又读取了旧数据,从而导致数据不一致。

  2. 缓存与数据库同步问题:即使写入数据库是同步的,缓存的删除可能是异步的,这意味着缓存中的数据可能在数据库写入之后仍然存在,导致不一致性。

延迟双删策略通过以下步骤解决了这些问题:

  1. 删除缓存:首先,缓存中的数据被删除,确保了缓存中不再有旧数据。

  2. 写入数据库:然后,数据被写入数据库,以确保数据的持久性。

  3. 休眠一段时间:在写入数据库后,应用程序等待一段时间。这个等待时间是为了确保在这段时间内,所有可能的读取操作都能够访问数据库中的最新数据,而不再访问缓存。

  4. 再次删除缓存:最后,在休眠时间结束后,再次删除缓存。这可以确保即使有一些读取操作仍然从缓存中获取数据,它们也会获得最新的数据。

以下是一个使用Java代码实现延迟双删策略的示例:

import java.util.concurrent.TimeUnit;

public class CacheManager {

    public void deleteCache(String key) {
        // 删除缓存的实现
        // 请根据您的缓存库的具体方法来删除缓存数据
    }

    public void writeToDatabase(String data) {
        // 写入数据库的实现
        // 请根据您的数据库访问库来执行写入操作
    }

    public void delayDoubleDelete(String key, String data, long delayTimeInSeconds) {
        // 先删除缓存
        deleteCache(key);

        // 写入数据库
        writeToDatabase(data);

        // 休眠一段时间(根据业务需求设置的延迟时间)
        try {
            TimeUnit.SECONDS.sleep(delayTimeInSeconds);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 再次删除缓存
        deleteCache(key);
    }

    public static void main(String[] args) {
        CacheManager cacheManager = new CacheManager();
        String key = "example_key";
        String data = "example_data";
        long delayTimeInSeconds = 5; // 延迟时间为5秒

        cacheManager.delayDoubleDelete(key, data, delayTimeInSeconds);
    }
}

上述代码示例中,我们创建了一个CacheManager类,其中包含了删除缓存和写入数据库的方法,以及delayDoubleDelete方法来执行延迟双删策略。在main方法中演示了如何使用它来执行延迟双删操作。确保根据您的实际需求和缓存库、数据库库的具体方法来实现deleteCachewriteToDatabase方法。请注意,这只是一个简单的示例,实际实现可能需要考虑错误处理、并发控制和合适的延迟时间。延迟时间的选择应根据应用的需求来确定,以确保足够的时间供所有可能的读取操作从数据库中获取最新数据。

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

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

相关文章

金蝶云星空自定义校验器和使用

文章目录 金蝶云星空自定义校验器和使用 金蝶云星空自定义校验器和使用 1、创建类,并继承抽象接口 using Kingdee.BOS.Core; using Kingdee.BOS.Core.Validation; using System;namespace mm.K3.SCM.App.Service.PlugIn.SC.Validator {public class AfterOrderChe…

Python使用got库如何写一个爬虫代码?

got库是一个Python的HTTP库,可以用于爬取网页数据。它提供了简单易用的API,支持异步请求和爬虫IP设置等功能。使用got库进行爬虫开发,可以快速地获取所需数据。下面是使用got库进行爬虫的基本步骤: 1、安装got库:可以使…

如何正确学习中国传统画——画家蒋旗

艺术简介 蒋旗: 师从张建中、张立辰 授教于郭石夫、陈曦林、薛永年、张旭光、乔森、于光华、高卉民、潘晓云 中国书画院院士 清华美院大写意花鸟画高研班助教导师 安徽美术家协会会员 泗县美术家协会副主席 青藤画社社长。 在艺术多元发展的当下&#xff0c…

【23真题】Top3简单专业课似双非!

今天分享的是23年复旦大学957的信号与系统试题及解析。 本套试卷难度分析:这套卷子平均分为120左右,最高分145分。22年复旦大学957信号与系统,我也发布过,若有需要戳这里自取!本套试题内容难度中等偏下,说…

AutoGen完整教程和加载本地LLM示例

Autogen是一个卓越的人工智能系统,它可以创建多个人工智能代理,这些代理能够协作完成任务,包括自动生成代码,并有效地执行任务。 在本文中,我们将深入探讨Autogen,并介绍如何让AutoGen使用本地的LLM Auto…

山西电力市场日前价格预测【2023-11-02】

日前价格预测 预测说明: 如上图所示,预测明日(2023-11-02)山西电力市场全天平均日前电价为151.67元/MWh。其中,最高日前电价为280.23元/MWh,预计出现在22:15。最低日前电价为0.00元/MWh,预计出…

编程助手DevChat:让开发更轻松

#AI编程助手哪家好?DevChat“真”好用 # 目录 前言一、安装Vscode1、下载链接2、安装 二、注册DevChat1、打开注册页2、验证成功完成邮箱绑定3、绑定微信可获得8元 三、安装插件四、配置Access Key1、获取Access Key2、设置Access Key①、点击左下角管理&#xff08…

(五)库存超卖案例实战——使用zookeeper分布式锁解决“超卖”问题

前言 本节内容使用zookeeper实现分布式锁,完成并发访问“超卖”问题的解决。相对于redis分布式锁,zookeeper能够保证足够的安全性。关于zookeeper的安装内容这里不做介绍,开始本节内容之前先自行安装好zookeeper中间键服务。这里我们利用创建…

Redis与Mysql的数据一致性(双写一致性)

双写一致性:当修改了数据库的数据也要同时的更新缓存的数据,使缓存和数据库的数据要保持一致。 一般是在写数据的时候添加延迟双删的策略 先删缓存 再修改数据 延迟一段时间后再次删除缓存 这种方式其实不是很靠谱 一致性要求高 共享锁:读…

Leetcode刷题---删除有序数组中的重复项 II(双指针问题)

题目描述: 题目中已经给出该数组是一个升序的数组。要求数组中最多出现两个相同的元素,而且不能使用额外的存储空间,并且将新的数组的长度返回。 解题思想: 该题可以使用双指针来解决,我们可以定义一个快指针和一个…

安装docker报错:except yum.Errors.RepoError, e:

问题描述: 在安装docker的时候,配置阿里云地址出现以下问题 问题原因: linux 系统中存在多版本的python. yum 依赖 python 2, 而个人使用 python 3 导致. 解决办法: 修改 /usr/bin/yum-config-manager文件中第一行 #!/usr/bin/p…

项目间的”藕断丝连“——从零到一搓个组件库

文章从零到一的封装设计 Starter,并提供可插拔 Starter 以及元数据配置等说明,并在可插拔上与开源 Zuul 进行比对,希望大家看后有所收获。 SpringBoot Starter 1. Starter 定义 SpringBoot Starter 类似于一种插件机制,抛弃了之…

pycharm更改远程服务器地址

一、问题描述 在运行一些项目时,我们常需要在pycharm中连接远程服务器,但万一远程服务器的ip发生了变化,该如何修改呢?我们在file-settings-python interpreter中找到远程服务器,但是发现ip是灰色的,没有办…

kkFileview任意文件读取漏洞复现

一、kkFileview简介 kkFileView,一款成熟且开源的文件文档在线预览项目解决方案。kkFileView为文件文档在线预览解决方案,该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,x…

你一般会什么时候使用CHATGPT?

在当今数字时代,人们对于人工智能(AI)的依赖程度日益增加,而ChatGPT作为一种强大的自然语言处理工具,吸引了人们的广泛关注和应用。那么,人一般在什么时候会想要使用ChatGPT呢?这个问题涵盖了多…

Debookee 8 for Mac网络数据分析工具

Debookee是一款用于网络数据流量分析和嗅探的软件。它为用户提供了一个直观的界面,让他们能够查看和分析来自从网络上的各种设备的数据流量。 Debookee具有以下主要功能: 实时监控:Debookee可以实时监控网络上的数据流量,并将其显…

对话InfoQ,聊聊百度开源高性能检索引擎 Puck

近日,百度宣布在 Apache 2.0 协议下开源自研检索引擎 Puck,这也是国内首个适用于超大规模数据集的开源向量检索引擎。向量检索算法在个性化推荐系统、多模态检索、自然语言处理等应用场景中都发挥着重要作用,特别是在处理大规模数据和高维特征…

MyBatis无法读取XML中的Method的乌龙事件

事件背景 同事反馈,相同的jar包,在多人本地的电脑、多台服务器中,都是可以正常启动的,只有在其中一台服务器,简称它为A,无法启动,因为启动后的初始化操作中有一个调用mybatis方法的操作&#x…

python实现MC协议(SLMP 3E帧)的TCP服务端(篇二)

python实现MC协议(SLMP 3E帧)的TCP服务端是一件稍微麻烦点的事情。它不像modbusTCP那样,可以使用现成的pymodbus模块去实现。但是,我们可以根据协议帧进行组包,自己去实现帧的格式,而这一切可以基于socket模…

聊聊无源滤波器与有源滤波器的概念、区别与应用

随着电子技术的迅速发展,电子设备得到广泛的应用,然而电磁环境污染日趋严重,已成为当今主要公害之一。在很多领域里,电磁兼容性已成为电气和电子产品必须有的技术指标或性能评价的依据,通过使用电源滤波器来过滤掉电源…