Redis篇:缓存更新策略最佳实践

前景:

        缓存更新是redis为了节约内存而设计出来的一个东西,主要是因为内存数据宝贵,当我们向redis插入太多数据,此时就可能会导致缓存中的数据过多,所以redis会对部分数据进行更新,或者把他叫为淘汰更合适,一般有以下三种淘汰策略。

1.缓存更新策略

1.1.三种常见的更新策略

内存淘汰:redis自动进行,当redis内存达到咱们设定的max-memery的时候,会自动触发淘汰机制,淘汰掉一些不重要的数据(可以自己设置策略方式)

超时剔除:当我们给redis设置了过期时间ttl之后,redis会将超时的数据进行删除,方便咱们继续使用缓存

主动更新 *:我们可以手动调用方法把缓存删掉,通常用于解决缓存和数据库不一致问题 

        

        

1.2.数据库缓存不一致的解决方案

        由于我们的缓存的数据源来自于数据库,而数据库的数据是会发生变化的,因此,如果当数据库中数据发生变化,而缓存却没有同步,此时就会有一致性问题存在,其后果是:

        用户使用缓存中的过时数据,就会产生类似多线程数据安全问题,从而影响业务,产品口碑等;怎么解决呢?有如下几种方案:

Cache Aside Pattern 人工编码方式:缓存调用者在更新完数据库后再去更新缓存,也称之为双写方案

Read/Write Through Pattern : 由系统本身完成,数据库与缓存的问题交由系统本身去处理

Write Behind Caching Pattern :调用者只操作缓存,其他线程去异步处理数据库,实现最终一致

1.3.数据一致性问题采用什么方案

综合考虑:使用方案一,但是方案一调用者如何处理呢?这里有几个问题

操作缓存和数据库时有三个问题需要考虑:

如果采用第一个方案,那么假设我们每次操作数据库后,都操作缓存,但是中间如果没有人查询,那么这个更新动作实际上只有最后一次生效,中间的更新动作意义并不大,我们可以把缓存删除,等待再次查询时,将缓存中的数据加载出来

  • 删除缓存还是更新缓存?

    • 更新缓存:每次更新数据库都更新缓存,无效写操作较多

    • 删除缓存:更新数据库时让缓存失效,查询时再更新缓存

  • 如何保证缓存与数据库的操作的同时成功或失败?

    • 单体系统,将缓存与数据库操作放在一个事务

    • 分布式系统,利用TCC等分布式事务方案

应该具体操作缓存还是操作数据库,我们应当是先操作数据库,再删除缓存,原因在于,如果你选择第一种方案,在两个线程并发来访问时,假设线程1先来,他先把缓存删了,此时线程2过来,他查询缓存数据并不存在,此时他写入缓存,当他写入缓存后,线程1再执行更新动作时,实际上写入的就是旧的数据,新的数据被旧数据覆盖了。

  • 先操作缓存还是先操作数据库?

    • 先删除缓存,再操作数据库

    • 先操作数据库,再删除缓存

因为更新数据库耗时比更新缓存耗时长很多,所以第二种情况发生的概率极低,比第一种低很多,所以综合考虑还是用第二种

2.实现缓存和数据库双写一致

比如我们把黑马点评项目拿来做示例:

2.1 实现商铺的缓存与数据库双写一致

核心思路:

 修改ShopController中的业务逻辑,满足下面的需求:

        1.根据id查询店铺时,如果缓存未命中,则查询数据库,将数据库结果写入缓存,并设置超时时间

        2.根据id修改店铺时,先修改数据库,再删除缓存

先修改ShopServiceImpl中的queryById方法,设置一个过期时间:

/**
     * 根据id查询商铺
     * @param id
     * @return
     */
    @Override
    public Result queryById(Long id) {
        //1.从redis查询商铺缓存
        String key = RedisConstants.CACHE_SHOP_KEY + id;
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        //2.判断是否存在
        if(StrUtil.isNotBlank(shopJson)){
            //3.存在,返回商铺信息
            Shop shop = JSONUtil.toBean(shopJson, Shop.class);
            return Result.ok(shop);
        }

        //4.不存在,去数据库查询
        Shop shop = getById(id);
        //5判断数据库中是否存在
        if(shop == null){
            //6.数据库中不存在,返回错误信息
            return Result.fail("店铺不存在!");
        }
        //7.数据库中存在,将商铺信息写入redis,返回商铺信息
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop));
        //8.设置过期时间
        stringRedisTemplate.expire(key,RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);
        return Result.ok(shop);
    }

再添加更新商铺时,需要进行删除缓存的操作:

        代码分析:通过之前的淘汰,我们确定了采用删除策略,来解决双写问题,当我们修改了数据之后,然后把缓存中的数据进行删除,查询时发现缓存中没有数据,则会从mysql中加载最新的数据,从而避免数据库和缓存不一致的问题。

ShopServiceImpl中的update方法:

 /**
     * 更新商铺信息
     * @param shop
     * @return
     */
    @Override
    @Transactional
    public Result update(Shop shop) {
        Long id = shop.getId();
        if(id == null){
            return Result.fail("店铺id不存在");
        }
        //1.更新数据库
        updateById(shop);
        //2.删除缓存
        stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY +shop.getId());
        //返回
        return Result.ok();
    }

2.2. 测试

重启服务之后,先访问一下浏览器,访问商铺界面:

                ​​​​​​​        

先去redis客户端查看,目前是有shop的缓存的:

接下来进行更新商铺操作,看看数据库发生改变的同时,是否会删除redis中缓存的shop:

我们使用postman发起更新请求:

发起请求之后,来到redis客户端:

可以看到,shop的缓存被删除了,说明没问题。

然后可以再去刷新一下浏览器,shop会重新添加缓存。

        ​​​​​​​        ​​​​​​​        

这就保证了当数据库更新时,会立即删除redis中的缓存,实现双写一致。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue3的监听属性watch和计算属性computed

监听属性watch 计算属性computed 一、监听属性watch watch 的第一个参数可以是不同形式的“数据源,watch 可以监听以下几种数据: 一个 ref (包括计算属性)、 一个响应式对象、 一个 getter 函数、 或多个数据源组成的数组 watch 的参数:监视的回调&…

代码随想录算法训练营第三十五天|860.柠檬水找零、406.根据身高重建队列、452. 用最少数量的箭引爆气球

860. 柠檬水找零 思路: 只需要维护三种金额的数量,5,10和20。 有如下三种情况: 情况一:账单是5,直接收下。情况二:账单是10,消耗一个5,增加一个10情况三:…

好友关注-实现分页查询收邮箱

9.5好友关注-实现分页查询收邮箱 需求:在个人主页的“关注”卡片中,查询并展示推送的Blog信息: 具体操作如下: 1、每次查询完成后,我们要分析出查询出数据的最小时间戳,这个值会作为下一次查询的条件 2…

考研党打印资料怎么使用云打印服务?

对于准备考研的同学们来说,在备考的时候需要准备许多资料,这些资料的打印费用成为了考研党的巨额支出。那么在生活费有限的情况下,考研党打印资料最好是选择云打印服务,因为易绘创云打印服务低至5分钱/页还包邮。那么考研党打印资…

Pytest精通指南(28)钩子函数-测试报告(pytest-html)

文章目录 前言应用场景插件安装参数分析使用方法拓展-定制化报告 前言 在软件开发过程中,测试是确保代码质量的关键环节。 而测试报告则是测试过程中不可或缺的输出物,它为我们提供了关于测试用例执行情况的详细信息,帮助我们快速定位和解决问…

服务器(AIX、Linux、UNIX)性能监视器工具【nmon】使用介绍

目录 ■nmon简介 1.安装 2.使用简介 3.使用(具体使用的例子【CPU】【内存】) 4.采集数据 5.查看log(根据结果,生成报表) 6.分析结果 ■nmon简介 nmon("Nigels performance Monitor"&…

比特币成长的代价

作者:Jeffrey Tucker,作家和总裁。曾就经济、技术、社会哲学和文化等话题广泛发表演讲。编译:秦晋 2017 年之后参与比特币市场的人遇到了与之前的人不同的操作和理想。如今,没有人会太在意之前的事情,说的是 2010-2016…

SL3038 耐压150V恒压芯片 60V降24V 72V降12V降压IC

SL3038 是一款恒压芯片,其耐压值为 150V。这意味着它可以在高达 150V 的电压下工作而不会损坏。现在,让我们来讨论您提到的两个降压应用:从 60V 降到 24V 和从 72V 降到 12V。 1. 60V 降到 24V: 输入电压:60V 输出电…

02 IO口的操作

文章目录 前言一、IO的概念1.IO接口2.IO端口 二、CPU和外设进行数据传输的方法1.程序控制方式1.1 无条件1.2 查询方式 2.中断方式3.DMA方式 一、方法介绍和代码编写1.前置知识2.程序方式1.1 无条件方式1.1.1 打开对应的GPIO口1.1.2 初始化对应的GPIO引脚1.1.2.1 推挽输出1.1.2.…

【Hadoop】-Hive部署[12]

目录 思考 VMware虚拟机部署 规划 步骤1:安装MySQL数据库 步骤2:配置Hadoop 步骤3:下载解压Hive 步骤4:提供MySQL Driver包 步骤5:配置Hive 步骤6:初始化元数据库 步骤7:启动Hive&…

TDSQL同一个所属Set显示3个备份节点

欢迎关注“数据库运维之道”公众号,一起学习数据库技术! 本期将为大家分享《TDSQL同一个所属Set显示3个备份节点》的处置案例。 关键词:分布式数据库、TDSQL、备份节点 1、问题描述 登录赤兔管理平台,单击左侧导航栏“实例管理/集群管理”…

漫谈-AI 时代的信息模型

模型化- 数字化转型的重要基石 在各行各业推行数字化转型过程中,构建信息化模型十分重要,它是数字化转型的基石。事实上,数字化转型的核心是“万物皆模型”,在工业领域,以德国为主导的工业4.0 发展进程中,…

Access denied for user ‘zabbix‘@‘localhost‘ (using password: NO)

现象 排查过程 进入数据库show grants for zabbixlocalhost;select host,user from mysql.user;cat /etc/zabbix/zabbix_server.conf | grep DB | grep -vE ‘#|$’cat /etc/zabbix/web/zabbix.conf.php | grep DB 解决办法 mysql 8.0以下 DPassword123.com mariadb -e "…

java多线程-并发和并行

进程 并发 进程中的线程是由CPU进行调度的,但是CPU能够处理的进程数量有限为了保证所有的线程都在运行,CPU会快速切换,给外界的感觉就是所有的线程都在运行,这就是并发。 并行

【力扣 Hot100 | 第六天】4.21(最长连续序列)

文章目录 10.最长连续序列10.1题目10.2解法:哈希法10.2.1哈希思路10.2.2代码实现 10.最长连续序列 10.1题目 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时…

php 编译安装oracel扩展

第一步安装Oracle客户端 1,需要下载基础包和sdk oracle客户端下载链接:Oracle Instant Client Downloads for Linux x86-64 (64-bit) https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html 选择最新版本 versi…

国产PLC有哪些,哪个牌子比较好用?

你知道国产PLC有哪些吗,哪个牌子更好用吗? 今天拿出国产先锋的汇川与台达对比,注:视频后方有各品牌学习资料免费送,需要的移步自取。话说回来,只要基于Codesys开发的都比较好用,只是使用底层芯片不同&…

2013-2021年各省经济韧性相关测度指标面板数据

2013-2021年各省经济韧性相关测度指标面板数据 1、时间:2013-2021年 2、指标:城镇化率 %、财政科学技术支出(亿元)、万人高等教育在校人数(万人)、财政教育支出(亿元)、第三产业占…

AD 21、22 软件安装教程

AD2022安装包链接 链接:https://pan.baidu.com/s/1oMNbXibQ1Zjl0RTLdPDVGw 提取码:xfs4 软件下载 1.以管理员身份运行 2. 3. 4. 5.路径最好改为C盘以外的,如D盘,要新建一个空文件夹 6. 7.下载好以后 8.在Crack文件夹下找…

程序员周末提升计划:朝网络安全工程师转型之路

作为一名软件开发人员,我一直对网络安全充满兴趣,并希望在未来转型成为一名网络安全工程师。面对网络安全领域的挑战和机遇,我制定了一个周末提升计划,希望能系统地增强我的技能并为这一跨界做好准备。下面,我将分享我…
最新文章