当前位置: 首页 > news >正文

点评项目(Redis中间件)第四部分缓存常见问题

缓存穿透

请求的数据在Redis里面没有,这种请求直接打到数据库,然后数据库里面也没有这个数据,数据库只能返回空,如果继续请求,就会一直打到数据库,可能数据库就会因此被打崩。

缓存雪崩

缓存击穿

第二种办法保证了绝对不会因为过期问题使访问直接打到数据库,但是为了实现过期这个功能我们就得用更复杂的办法,额外维护一个过期时间来实现过期这个功能。

逻辑过期里面也有锁的使用,但是是交给别的线程,所以不在我们的对比行列里面。

互斥锁解决击穿问题

Redis设置锁的方法

SETNX 是 Redis 的一个字符串(String)操作命令,它的全称是 SET if Not eXists

  • 功能:当且仅当指定的 key 不存在时,为这个 key 设置一个值。

  • 返回值

    • 1:表示设置成功(key 原本不存在)。

    • 0:表示设置失败(key 已经存在)。

这是一个原子性操作,意味着它是不可分割的。在并发环境下,多个客户端同时执行 SETNX 时,Redis 能确保只有一个客户端会成功。

关于拆箱

核心概念:值类型 vs 引用类型

许多语言中,数据类型分为两大类:

  • 值类型:变量直接存储数据本身。例如:intfloatcharbool 等基本数据类型。

    • 就像你口袋里直接揣着现金。

  • 引用类型:变量存储的是一个内存地址(引用),这个地址指向实际的数据所在的内存位置。例如:接口数组字符串

    • 就像你口袋里揣着一张银行卡,钱存在银行的保险柜里。

 为什么需要装箱和拆箱?

有时候,我们需要在需要引用类型的地方使用一个值类型

一个经典例子:Java 中的集合(如 ArrayList)
Java 的 ArrayList 类的 add 方法定义是 add(Object obj),它只能接收引用类型(因为 Object 是所有类的超类)。但如果我们想往里面存一个整数(int,它是值类型),该怎么办?

这就需要 “装箱”—— 把值类型“包装”成一个引用类型的对象。

装箱

装箱 就是将值类型转换为对应的引用类型的过程。

这个过程通常是隐式的(编译器自动完成)。

Java 示例(在 Java 中称为“自动装箱”):

拆箱

拆箱 是装箱的逆过程,它将引用类型转换回对应的值类型

这个过程有时需要显式地进行(需要手动指定目标类型)。

Java 示例(在 Java 中称为“自动拆箱”):

拆箱操作本质上是一个强制类型转换。你告诉编译器:“相信我,这个引用类型变量里面装的一定是某个特定的值类型,现在请把它拿出来。”

编译器在编译时无法100%确定你的这个“信任”是否正确,所以它允许代码通过编译。但如果在运行时发现你的“信任”是错的,就会立即抛出一个异常来中断程序。

操作代码背后原理比喻
手动装箱Integer box = Integer.valueOf(100);调用静态工厂方法valueOf,创建一个新对象。去工厂订做一个盒子。
自动装箱Integer box = 100;编译器帮你写Integer.valueOf(100)告诉助理“我要个盒子”,助理帮你订做。
手动拆箱int i = box.intValue();调用对象实例方法intValue(),取出其内部值。自己动手打开盒子拿钱。
自动拆箱int i = box;编译器帮你写box.intValue()
特性boolean (基本类型)Boolean (包装类)
数据类型基本数据类型(引用类型)
默认值falsenull
存储位置栈内存堆内存(对象本身),栈上存引用
占用空间约1位(实际按1字节处理)一整个对象的内存开销(更大)
比较方式== 比较== 比较内存地址equals() 比较包装的值
功能仅能表示 true/false是一个类,拥有方法(如 toString()parseBoolean()
允许为null不允许允许
用途普通的条件判断、循环控制需要对象的地方(如泛型、集合)
public <R,ID> R queryWithPassThrough(String keyPrefix, ID id, Class<R> type, Function<ID, R> dbFallback, Long time, TimeUnit unit){String key = keyPrefix + id;// 1.从redis查询商铺缓存String json = stringRedisTemplate.opsForValue().get(key);// 2.判断是否存在if (StrUtil.isNotBlank(json)) {// 3.存在,直接返回return JSONUtil.toBean(json, type);}// 判断命中的是否是空值if (json != null) {// 返回一个错误信息return null;}// 4.不存在,根据id查询数据库R r = dbFallback.apply(id);// 5.不存在,返回错误if (r == null) {// 将空值写入redisstringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);// 返回错误信息return null;}// 6.存在,写入redisthis.set(key, r, time, unit);return r;}

逻辑过期解决击穿问题

http://www.dtcms.com/a/392575.html

相关文章:

  • 动态水印也能去除?ProPainter一键视频抠图整合包下载
  • DevSecOps 意识不足会导致哪些问题
  • LeetCode:27.合并两个有序链表
  • 适用于双节锂电池的充电管理IC选型参考
  • 格式说明符
  • 层数最深叶子节点的和(深度优先搜索)
  • 【git】安装和基本指令
  • 如何利用AI技术快速生成专业级的PPT和视频内容
  • Linux系统之----线程互斥与同步
  • ARM SMMUv2架构下的安全和非安全状态(secure/non-secure)下的的资源分配解析
  • 面向linux新手的OrcaTerm AI 最佳实践
  • 构建高可用 LVS-DR + Keepalived 负载均衡集群实战指南
  • 网络协议总结
  • Python多线程爬虫加速电商数据采集
  • JVM之直接内存(Direct Memory)
  • 深入理解C指针(四):回调函数与qsort——指针实战的终极舞台
  • 翻拍图像检测(即拍摄屏幕的照片)功能实现思路
  • 【Linux】进程概念(上):从冯诺依曼到进程入门
  • 计算机视觉(opencv)实战二十八——基于 OpenCV CSRT 跟踪器的实时目标
  • 【Mysql】深分页问题、页分裂问题、加密/解密、执行计划
  • 【名人简历】牛顿
  • coze开发的牙科AI智能体助手web页面
  • JavaEE初阶——从入门到掌握线程安全
  • GitHub热门大数据项目:基于人体生理指标管理的可视化分析系统技术解析
  • 零基础学Docker(2)--基本命令
  • 华为FusionCloud私有云:企业数字化转型的智能底座
  • 【LVS入门宝典】LVS NAT模式深度解析:从原理到实战配置指南
  • MQ 项目(实习项目,初步更新)
  • Redis中Lua脚本的应用场景分析
  • phpkg 让 PHP 摆脱 Composer 依赖地狱