learning_notes

学习笔记

View project on GitHub

缓存

设计缓存面临问题

缓存穿透

  • 原因:查询一个一定不存在的数据,每次都需要去数据库查,如果访问量大,DB挂掉,利用不存在的Key可以造成攻击
  • 解决:
    1. DB不存在的数据,缓存空值
    2. 采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉

      缓存雪崩

  • 原因:所有的key设置了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩
  • 解决:过期时间随机,降低缓存在同一时刻全部失效

缓存击穿

  • 原因:热点访问,同一个key,缓存过期,大量请求并发访问DB,压垮DB
  • 解决:
    1. 缓存失效,加互斥锁,只有一个线程可以访问DB去请求数据缓存,其他线程sleep,然后再请求缓存
    2. key不过期,维护一个假定过期时间,异步更新数据,性能好,代码复杂
    3. 如果生成缓存数据十分耗时,需要主动更新缓存

缓存一致性

  • 原因: 数据更新的同时缓存数据没有实时更新
  • 解决:
    1. 主动更新

缓存 “无底洞” 现象

  • 原因: 为了满足业务要求添加了大量缓存节点,客户端一次批量操作会涉及多次网络操作,这意味着批量操作的耗时会随着节点数目的增加而不断增大
  • 解决:
    1. 优化批量数据操作命令
    2. 减少网络通信次数

缓存淘汰算法

  • FIFO(First In First Out)先进先出,时间维度缺点:最早添加但也最常被访问
  • LFU(Least Frequently Used)最少使用,频率维度缺点:历史访问次数过高,而迟迟不能被淘汰
  • LRU(Least Recently Used):最近最少使用,综合时间和频率

缓存高可用和可拓展

一致性哈希算法

HTTP-CACHE

varnish 页面缓存