【Redis】 缓存双写一致性

news2024/7/6 20:22:15

缓存双写一致性

给缓存设置过期时间,定期清理缓存并回写,是保证最终一致性的解决方案。

我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存,达到一致性,切记,要以mysql的数据库写入库为准。

上述方案和后续落地案例是调研后的主流+成熟的做法,但是考虑到各个公司业务系统的差距,

不是100%绝对正确,不保证绝对适配全部情况,请同学们自行酌情选择打法,合适自己的最好。

双检加锁

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@Service
@Slf4j
public class UserService {
    public static final String CACHE_KEY_USER = "user:";
    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 业务逻辑没有写错,对于小厂中厂(QPS《=1000)可以使用,但是大厂不行
     * @param id
     * @return
     */
    public User findUserById(Integer id)
    {
        User user = null;
        String key = CACHE_KEY_USER+id;

        //1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysql
        user = (User) redisTemplate.opsForValue().get(key);

        if(user == null)
        {
            //2 redis里面无,继续查询mysql
            user = userMapper.selectByPrimaryKey(id);
            if(user == null)
            {
                //3.1 redis+mysql 都无数据
                //你具体细化,防止多次穿透,我们业务规定,记录下导致穿透的这个key回写redis
                return user;
            }else{
                //3.2 mysql有,需要将数据写回redis,保证下一次的缓存命中率
                redisTemplate.opsForValue().set(key,user);
            }
        }
        return user;
    }


    /**
     * 加强补充,避免突然key失效了,打爆mysql,做一下预防,尽量不出现击穿的情况。
     * @param id
     * @return
     */
    public User findUserById2(Integer id)
    {
        User user = null;
        String key = CACHE_KEY_USER+id;

        //1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysql,
        // 第1次查询redis,加锁前
        user = (User) redisTemplate.opsForValue().get(key);
        if(user == null) {
            //2 大厂用,对于高QPS的优化,进来就先加锁,保证一个请求操作,让外面的redis等待一下,避免击穿mysql
            synchronized (UserService.class){
                //第2次查询redis,加锁后
                user = (User) redisTemplate.opsForValue().get(key);
                //3 二次查redis还是null,可以去查mysql了(mysql默认有数据)
                if (user == null) {
                    //4 查询mysql拿数据(mysql默认有数据)
                    user = userMapper.selectByPrimaryKey(id);
                    if (user == null) {
                        return null;
                    }else{
                        //5 mysql里面有数据的,需要回写redis,完成数据一致性的同步工作
                        redisTemplate.opsForValue().setIfAbsent(key,user,7L,TimeUnit.DAYS);
                    }
                }
            }
        }
        return user;
    }

}

延时双删

在这里插入图片描述

考虑异常和多线程并发

在这里插入图片描述
休眠时间多久?

线程A sleep的时间,就需要大于线程B读取数据再写入缓存的时间。

这个时间怎么确定呢?

  • 第一种方法:

在业务程序运行的时候,统计下线程读数据和写缓存的操作时间,自行评估自己的项目的读数据业务逻辑的耗时,以此为基础来进行估算。然后写数据的休眠时间则在读数据业务逻辑的耗时基础上加百毫秒即可。

这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。

  • 第二种方法:

新启动一个后台监控程序,比如后面要讲解的WatchDog监控程序,会加时

在这里插入图片描述

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

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

相关文章

业界主流数据加速技术路线

计算存储分离已经成为云计算的一种发展趋势。在计算存储分离之前,普遍采用的是传统的计算存储相互融合的架构,但是这种架构存在一定的问题,比如在集群扩容的时候会面临计算能力和存储能力相互不匹配的问题。用户在某些情况下只需要扩容计算能…

编译支持国密的抓包工具 WireShark

目录 前言WireShark支持国密的 WireShark小结前言 在上一篇文章支持国密的 Web 服务器中,我们搭建了支持国密的 Web 服务器,但是,我们使用 360 安全浏览器去访问,却出现了错误: 是我们的 Web 服务器没有配置好?在这里插入图片描述还是 360 安全浏览器不支持国密?还是两…

pycharm手动安装常用插件

下载插件 (1)下载地址:JetBrains Marketplace 这里以语言包为例子 2、中文语言包 进入pycharm中的设置,点击plugins,选从磁盘中安装插件

分享axios+signalr简单封装示例

Ajax Axios Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。 从浏览器创建 XMLHttpReque…

最新基于R语言lavaan结构方程模型(SEM)技术

原文链接:最新基于R语言lavaan结构方程模型(SEM)技术https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247596681&idx4&sn08753dd4d3e7bc492d750c0f06bba1b2&chksmfa823b6ecdf5b278ca0b94213391b5a222d1776743609cd3d14…

ChatGPT等AI使用的过程苦笑不得瞬间

引言: 在人工智能的浪潮中,我们见证了技术的飞速发展和智能应用的广泛渗透。特别是随着语言模型的进步,AI如ChatGPT、文心一言、通义千问、讯飞星火等已经成为人们日常生活和工作中不可或缺的助手。然而,与任何新兴技术一样&#…

在云端构建和部署工作负载的最佳方式是怎样的?

如果要问当今企业希望从云计算中获得什么,那么 “低延迟” 以及 “更接近客户” 可能会是很多企业的首要目标。低延迟可以带来诸多好处,如提升用户满意度、增加竞争优势、降低运营成本等;更接近客户则有助于降低网络拥塞、减少数据丢失、符合…

【算法】一类支持向量机OC-SVM

【算法】一类支持向量机OC-SVM 前言一类支持向量机OC-SVM 概念介绍示例编写数据集创建实现一类支持向量机OC-SVM完整的示例输出 前言 由于之前毕设期间主要的工具就是支持向量机,从基础的回归和分类到后来的优化,在接触到支持向量机还有一类支持向量机的…

可免费使用的AI平台汇总 + 常用赋能科研的AI工具推荐

赋能科研,AI工具助你飞跃学术巅峰!(推荐收藏) 文章目录 赋能科研,AI工具助你飞跃学术巅峰!(推荐收藏)一、可免费使用的AI平台汇总1. ChatGPT2. New Bing3. Slack4. POE5. Vercel6. 其他平台7. 特定功能平台8. 学术资源平台9. 中文…

Linux学习——线程的控制

目录 ​编辑 一,线程的创建 二,线程的退出 1,在子线程内return 2,使用pthread_exit(void*) 三,线程等待 四,线程获取自己的id值 五,线程取消 六,线程分离 一,线程的创建 在对…

MySQL常见的索引类型介绍

我将为您详细讲解 MySQL 中常见的索引类型,以及它们的使用场景、特点、区别和优势。索引是提高数据库查询性能的关键工具,它可以加速数据检索速度,减少服务器的负担。在 MySQL 中,索引类型主要包括 B-Tree 索引、哈希索引、全文索…

025—pandas 根多列判断不在其他列的数据

思路 是有两个相同结构的数据表,已知第二个表是第一个表的部分数据,需要以其中两列为单位,判断在第一个表中存在,在另外一个表中不存在的数据。 思路: 我们先将 df1 和 df2 的 x、y 列取出,组合为元组形成…

深入探索HAProxy:高性能负载均衡器的奥秘

目录 引言 一、HAProxy基础知识 (一)HAProxy概述 (二)核心特性 (三)支持调度算法 二、安装haproxy (一)下载源码包 (二)解决依赖环境 (三…

教你实现微信公众号消息每日自动推送-俘获妹子芳心

教你实现微信公众号消息每日自动推送-俘获妹子芳心,我们使用的是github的这个库。链接:https://github.com/limoest/daily_reminder 。作者的仓库已经有足够详细的教程。本文主要描述搭我自己的建过程,帮助更多小白一步一步搭建实现~ 首先要fork该项目 申请微信接口公众测试…

高端竞赛活动,财会知识竞赛复赛方案

复赛环节共计有48名选手参与,随机分为2组,每组24名选手,经过与预赛环节相同的关卡及赛制,即每组选手皆通过两轮关卡赛一轮复活赛,每组角逐12名选手晋级。2组共计24名选手晋级决赛,而未进入决赛的选手则获得…

分享软件项目实施方案模板

本项目在实施过程中将遵守做到以下几个方面: 与建设单位共同完成整个系统软件、网络等设计,负责系统的开发、测试、调试、人员培训、系统的试运行和交付,并保证系统质量。负责系统的维护、应用软件的升级和更新。提出对系统硬件设备的相关技术要求。在项…

redis源码分析

是什么 是基于内存(而不是磁盘)的kv(而不是关系型mysql那种)数据库,通过空间换时间 源码分析 跳表skiplist 假设你有个有序链表,你想看某个特定的值是否出现在这个链表中,那你是不是只能遍历一次链表才能知道,时间复杂度为O(n…

JavaEE--SpringBoot配置⽂件

配置文件的基本概念 properties的语法格式 读取配置文件的内容 properties的缺点 yml 主要使用yml yml的文件格式 先举一个例子,简单了解一下 验证结果如下: yml读取配置文件的内容 配置文件内容为空的时候的情况 配置内容为null时的情况 配置…

算法项目(7)—— 文本检索图片

本文包含什么? 免环境配置,实现文本搜索图片全套代码以及代码介绍运行有问题? csdn上后台随时售后.项目说明 本文主要实现用文本搜索数据库中图片的功能. 项目运行 代码地址在文末 点击链接后选择T4的GPU: 将云盘中的代码文件clip_search.tar拖到下图位置上传代码: 执行…

OD_2024_C卷_200分_9、园区参观路径【JAVA】【动态规划】

package odjava;import java.util.Scanner;public class 九_园区参观路径 {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt(); // 长 -> 行数int m sc.nextInt(); // 宽 -> 列数int[][] matrix new int[n][m]; // 地图…