缓存相关的一些东西的总结

用redis做数据缓存:用户访问接口获取数据时,先使用通过访问redis获取数据,若数据不存在,则通过访问数据库进行数据获取
  • 数据库与redis做数据同步
    • 强一致性:
      • 通过redissession的读写锁(存在性能瓶颈)
        • 读锁:读读不互斥,读写互斥
        • 写锁:读写互斥,写写互斥
      • 延迟双删,操作数据库完成后删除缓存,等一段时间(主从同步时间),再次进行缓存删除(严格说也是一种最终一致性)
        • 延迟双删中,延迟的时间不好把握(在数据库采用读写分离的情况下,不好把握数据同步到备节点的时间)
        • 两次删除之间,请求有可能读取到老的数据(第一次删除后,完成主从同步前,读取数据时,会读取到老的数据)
        • 只操作数据库前删除,操作数据库后没删除:第一次删除后,完成数据库操作前,读取数据时,会将老的数据写入到缓存中
        • 只操作数据库后删除,第一个线程读取数据时,缓存恰好失效,读取数据库获取最新数据(老数据),在此时,另一个线程恰巧在操作数据库,若在数据库操作完成,且删缓存后,第一个线程将老数据写入缓存中
    • 弱一致性(最终一致性)
      • canal伪装成MySQL的从节点,读取binlog文件,进行数据同步(代码侵入小)
      • 服务将数据发送到MQ中,缓存服务读取MQ进行数据同步
  • 缓存穿透
    • 用户使用不存在的key进行数据获取,导致查询语句透传到底层数据库中,类似场景每次都直接访问到数据库,导致缓存不生效
      • 缓存null值,若查不到,则在缓存中存null值,直接给用户返回(会导致缓存污染,恶意攻击时,会导致大量空值存在于缓存中)
      • 使用布隆过滤器: 由于hash算法存在hash冲突问题,可能存在漏网之鱼,若在更新布隆过滤器时,由于不可抗力因素导致更新失败,可能导致部分正常数据被拦截
  • 缓存击穿
    • 用户在访问数据时,当一个请求量很大时,该缓存恰好失效,导致大量请求涌入数据库中进行查找
      • 读取数据库操作增加互斥锁:当一个请求访问数据库时,另外的请求等待,当写入缓存后释放锁,其他请求直接从缓存中读取数据
      • 逻辑过期:读取数据时,若发现数据已过期,使用新的线程触发缓存更新,直接返回过期的缓存数据
      • 热点数据永不过期:使用定时任务刷新过期数据
      • 增加本地缓存Caffeine或者Guava,当redis缓存失效时,优先访问本地缓存
      • 若压力过大,可以采用熔断机制,返回默认值或错误
  • 缓存雪崩:
    • 当主缓存中,数据大量同时失效,进行数据库访问
      • 增加本地缓存Caffeine或者Guava进行缓解压力
      • 缓存失效时间随机化
      • 熔断,返回默认值或错误
      • 使用分布式锁重建缓存,当一个请求读取缓存时,其他请求等待,直接读取缓存中的数据

 

      

posted @ 2025-09-07 00:59  七月流星丶  阅读(14)  评论(0)    收藏  举报