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

双重判定锁来解决缓存击穿问题

缓存击穿场景

缓存击穿是指:当热点数据过期或者不存在时,此时正好有大量请求访问热点数据,这些请求就会直接访问数据库,造成数据库的压力骤增,严重时造成宕机。

解决缓存击穿有几种方案:

  1. 缓存预热
    对热点数据进行预加载,当活动开始时,提前将热点数据从数据库加载到缓存中,可以避免海量请求第一次访问热点数据时需要从数据库读取的流程。
  2. 热点数据永不过期
    对于已知的热点数据,设置过期时间为-1,这样就不会有缓存击穿的情况出现了。
  3. 分布式锁
    使用分布式锁,使得只有一个请求可以访问数据库,避免大量请求并发访问数据库。
    但是这种方法存在一定弊端:
    获取分布式锁的请求,都会执行查询数据库并且更新缓存,理论上只有第一次加载数据库请求的记录是有效的。所以这里采用双重判定锁的形势来解决。
    在这里插入图片描述
    即在获取到分布式锁后,再次进行判断缓存是否存在,如果存在则直接返回。如果不存在,才执行访问数据库并更新缓存的操作

在这里插入图片描述
缓存击穿使用 lock 或者 tryLock 同样有所讲究,需要视场景而定:
lock:
获取锁,成功就执行操作,失败就阻塞等待。
trylock:
获取锁,成功返回true,失败则直接返回false,不用阻塞等待。

Lock源码

public interface Lock {
    /**
     * Acquires the lock.
     */
    void lock();
 
    /**
     * Acquires the lock unless the current thread is
     * {@linkplain Thread#interrupt interrupted}.
     */
    void lockInterruptibly() throws InterruptedException;
 
    /**
     * Acquires the lock if it is free within the given waiting time and the
     * current thread has not been {@linkplain Thread#interrupt interrupted}.
     */
    boolean tryLock();
 
    /**
     * Acquires the lock if it is free within the given waiting time and the
     * current thread has not been {@linkplain Thread#interrupt interrupted}.
     */
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
 
    /**
     * Releases the lock.
     */
    void unlock();
 
    /**
     * Returns a new {@link Condition} instance that is bound to this
     * {@code Lock} instance.
     */
    Condition newCondition();
}

发生极端情况时,lock和trylock如何选择?
如果希望确保线程能够按照特定的顺序访问共享资源,并且不介意可能的等待时间,那么lock方法是一个不错的选择,但是,如果希望避免线程长时间等待,并且能够处理未能立即获得锁的情况,那么tryLock方法可能更适合。

那么trylcok具体对应于什么样的场景呢?
如果是双十一抢优惠券或者真的是海量访问,在用户占便宜的情况下,推荐使用trylock,因为用户会因为失败而自己刷新页面,海量访问也推荐使用trylock,因为如果使用lock对于用户的体验非常不好。


http://www.kler.cn/a/452027.html

相关文章:

  • 【求职面试】驾照的种类
  • 水电站视频智能监控系统方案设计与技术应用方案
  • Android 之 List 简述
  • 广州大学计算机组成原理课程设计
  • 【微信小程序】2|轮播图 | 我的咖啡店-综合实训
  • 【Rust自学】5.3. struct的方法(Method)
  • VTK知识学习(27)- 图像基本操作(二)
  • Cyberchef实用功能之-批量提取XML数据文件的字段内容
  • Win10提示“缺少fbgemm.dll”怎么办?缺失fbgemm.dll文件的修复方法来啦!
  • 4-pandas常用操作
  • LeetCode:257. 二叉树的所有路径
  • 一、后端到摄像头(监控摄像头IOT)
  • Docker--宿主机执行docker容器的命令
  • 【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(三):基于BT行为树实现复杂敌人BOSS-AI
  • MVC 参考手册
  • Flink中并行度和slot的关系——任务和任务槽
  • VUE前端实现防抖节流 Lodash
  • TCN-Transformer+LSTM多变量回归预测(Matlab)添加气泡图、散点密度图
  • “自动驾驶第一股” 图森未来退市转型:改名 CreateAI、发布图生视频大模型 “Ruyi”
  • 大模型-Dify使用笔记
  • QT安装5.15之后的版本和安装后添加其他漏装模块
  • mac中idea中英文版本切换
  • 金融数据可视化实现
  • mac启ssh服务用于快速文件传输
  • [创业之路-204]:《华为战略管理法-DSTE实战体系》- 5-平衡记分卡绩效管理
  • M系列芯片切换镜像源并安装 openJDK17