首页 > 数据库 >Redis

Redis

时间:2022-12-06 13:23:52浏览次数:37  
标签:shop 缓存 Redis 数据库 redis 更新 id

Redis缓存

一、关于缓存

缓存的定义:

缓存(Cache),就是数据交换的缓冲区,俗称的缓存就是缓冲区内的数据,一般从数据库中获取,存储于本地代码
举个例子:越野车,山地自行车,都拥有"避震器",
防止车体加速后因惯性,在酷似"U"字母的地形上飞跃,硬着陆导致的损害,像个弹簧一样;
同样,实际开发中,系统也需要"避震器",防止过高的数据访问猛冲系统,导致其操作线程无法及时处理信息而瘫痪;
这在实际开发中对企业讲,对产品口碑,用户评价都是致命的;所以企业非常重视缓存技术;

缓存的分类:

浏览器缓存:主要是存在于浏览器端的缓存

应用层缓存:可以分为tomcat本地缓存,比如之前提到的map,或者是使用redis作为缓存

数据库缓存:在数据库中有一片空间是 buffer pool,增改查数据都会先加载到mysql的缓存中

CPU缓存:当代计算机最大的问题是 cpu性能提升了,但内存读写速度没有跟上,所以为了适应当下的情况,增加了cpu的L1,L2,L3级的缓存

如何使用缓存:

实际开发中,会构筑多级缓存来使系统运行速度进一步提升,例如:本地缓存与redis中的缓存并发使用

添加商户缓存:

在我们查询商户信息时,我们是直接操作从数据库中去进行查询的,大致逻辑是这样,直接查询数据库那肯定慢咯,所以我们需要增加缓存

@GetMapping("/{id}")
public Result queryShopById(@PathVariable("id") Long id) {
    //这里是直接查询数据库
    return shopService.queryById(id);
}

缓存的思路和模型

标准的操作方式就是查询数据库之前先查询缓存,如果缓存数据存在,则直接从缓存中返回,如果缓存数据不存在,再查询数据库,然后将数据存入redis。
image
具体代码:

@Override
    public Result queryById(Long id) {
        String key = "cache:shop:" + id;
        //从redis查询商铺缓存,并判断缓存是否命中
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(shopJson)) {
            //命中就返回
            Shop shop = JSONUtil.toBean(shopJson, Shop.class); //json格式转换为对象
            return Result.ok(shop);
        }
        //未命中就根据id查询数据库
        Shop shop = getById(id);
        // 判断商铺是否存在 存在就将商铺数据写入Redis
        if (shop == null) {
            return Result.fail("店铺不存在!");
        }
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);// 否则就返回404
        return Result.ok(shop);

缓存更新策略:

缓存更新是redis为了节约内存而设计出来的,为保证redis中的数据都是热点数据,而对数据进行的淘汰
淘汰的方式有三种:

  1. 内存淘汰:
    redis自动进行,当redis内存达到咱们设定的max-memery的时候,会自动触发淘汰机制,淘汰掉一些不重要的数据(可以自己设置策略方式)
  2. 超时剔除:
    当我们给redis设置了过期时间ttl之后,redis会将超时的数据进行删除,方便咱们继续使用缓存
    主动更新:
  3. 我们可以手动调用方法把缓存删掉,通常用于解决缓存和数据库不一致问题
    image

数据库缓存不一致解决方案(即双写不一致问题)

产生的原因:

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

解决的方案:

大致上有三种方案:

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

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

  3. Write Behind Caching Pattern :调用者只操作缓存,其他线程去异步处理数据库,实现最终一致
    image
    最终我们选择第一种方案
    但是在调用第一种有几个注意事项:

    • 删除缓存还是更新缓存?
    • 更新缓存:每次更新数据库都更新缓存,无效写操作较多
    • 删除缓存:更新数据库时让缓存失效,查询时再更新缓存
  • 如何保证缓存与数据库的操作的同时成功或失败?
    • 单体系统,将缓存与数据库操作放在一个事务
    • 分布式系统,利用TCC等分布式事务方案

方案一大致上又分为四种
1、先写缓存在写数据库
2、先写数据库在写缓存
3、先删缓存在写数据库
4、先写数据库再删缓存

最终解决方案

延迟双删
image
该方案有个非常关键的地方是:第二次删除缓存,并非立马就删,而是要在一定的时间间隔之后。
sleep的时间要对业务读写缓存的时间做出评估,sleep时间大于读写缓存的时间即可。
那么,为什么一定要间隔一段时间之后,才能删除缓存呢?
请求d卡顿结束,把新值写入数据库后,请求c将数据库中的旧值,更新到缓存中。此时,如果请求d删除太快,在请求c将数据库中的旧值更新到缓存之前,就已经把缓存删除了,这次删除就没任何意义。必须要在请求c更新缓存之后,再删除缓存,才能把旧值及时删除了。

注意:如果接口对性能的要求不是很高则只需设置redis过期时间即可

标签:shop,缓存,Redis,数据库,redis,更新,id
From: https://www.cnblogs.com/lhsss9825/p/16954932.html

相关文章

  • Redis 缓存击穿问题
    解决方案一:互斥锁假设一个热门产品的缓存时间到期了,那么将会有大量的请求查询不到缓存,就只能去查询数据库然后再把数据添加到缓存中。但是如果在缓存时间到期的瞬间有很多......
  • Redis的三种模式
    一、Redis模式Redis有三种模式:分别是主从同步/复制、哨兵模式、Cluster主从复制:主从复制是高可用Redis的基础,哨兵和群集都是在主从复制基础上实现高可用的。主从复制主要......
  • redis 相关
    Redis提供了丰富的数据类型,常见的有五种:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合)。后面又支持了四种数据类型: BitMap(2.2版新增)、HyperLogLog(2.8版新增)、......
  • Redis分布式锁及分区
    redis分区的方法redis实现的分布式锁RedLock算法,分布式锁,即在多个master上获取同一个锁1.inordertogetthelock,theclientgetthecurrentmstime2.顺序对n个实......
  • 《Redis实战篇》一、短信登录
    1.1、导入黑马点评项目1.1.1、导入SQL1.1.2、有关当前模型手机或者app端发起请求,请求我们的nginx服务器,nginx基于七层模型走的事HTTP协议,可以实现基于Lua直接绕开tomcat访......
  • Redis的三种模式
    一、Redis模式Redis有三种模式:分别是主从同步/复制、哨兵模式、Cluster主从复制:主从复制是高可用Redis的基础,哨兵和群集都是在主从复制基础上实现高可用的。主从复制主要......
  • Redis的三种模式
    一、redis主从复制1、主从复制-哨兵-集群主从复制:主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于......
  • Nosql--Redis
    一、Nosql概述NoSQL(NoSQL=NotOnlySQL),意即“不仅仅是SQL”,泛指非关系型的数据库。NoSQL不依赖业务逻辑方式存储,而以简单的key-value模式存储。因此大大的增加了数据......
  • .NET 6 基于IDistributedCache实现Redis与MemoryCache的缓存帮助类
    本文通过IDistributedCache的接口方法,实现Redis与MemoryCache统一帮助类。只需要在配置文件中简单的配置一下,就可以实现Redis与MemoryCache的切换。目录IDistributedCache......
  • Redis配置、优化以及命令
    一、关系数据库和非关系型数据库1、关系型数据库关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。SQL语句(标准数据查询语言)就是一种......