缓存问题

缓存穿透

  • 请求跳过缓存,直接打到 db
  • 解决方法
    1. 缓存null值,但是可能会导致 redis 占满
    2. 使用过滤器,但是查询条件很多,导致过滤器很大
      1. 布隆算法,bit数组+多个hash函数进行映射,只能保证没有就绝对没有,直接返回 null
        1. 全为一咋办,说明 bit数组太小了
        2. 如何删除 布谷鸟算法
      2. 面试题,大文件中查找相同的 url
        1. 非精准: 布隆过滤器,有一定错误率,返回 true 就是 true
        2. 精准: 分而治之,根据 hash % 文件数,分为多个文件,然后两个一组多线程计算

缓存雪崩

  • 大量缓存失效,导致请求打到 db
  1. cache集中过期
    1. random 即可
  2. redis 宕机
    1. redis 高可用 or local cache

缓存击穿

  • 一条热门数据失效导致请求打到 db
  1. 用 分布式锁,缺点,效率鸡儿慢
  2. while true + timeout + 设置空数据

上面得关系

  • 缓存雪崩和缓存击穿本质上就是缓存穿透
  • 击穿和雪崩是穿透的特殊表现形式,点和面的区别

分布式锁

  • 锁的使用场景
    • 资源是共享的
    • 资源使用是互斥的
    • 多个调用会同时要使用该资源
  • redis 锁和 zk 锁的对比
    • 性能
      • redis 锁,需要不断的尝试获取锁,消耗性能
      • zk 锁,利用临时顺序节点,注册监听器即可,不用轮询获取锁
    • timeout
      • redis 锁的 timeout 设置比较难以取舍、
        • 过长 意外导致锁没能即使释放,timeout 时间内性能很低
        • 过短 意外导致锁太快释放,导致并发问题
      • zk 锁,临时 znode 只要客户端挂了,znode 就没了

zk

  • zk 是分布式一致性服务,数据绝对同步
  • zk 节点分为
    1. 持久节点 create <node>
    2. 持久有序节点 create -s <node>
    3. 临时节点 create -e <node>
    4. 临时有序节点 create -e -s <node>

疑问 临时节点,cli 自主断开连接 ,会删除该node;但是分布式环境下,cli 直接挂了,在一个心跳时间内 (tickTime) 后,对应的 zk 才会发送一个心跳,才会 意识到 cli 丢失了,才能通知其他的 zk 节点该 node 丢失

zk 事件回调机制:可以给 node 设置回调和触发条件,条件触发时,会调用 cli 的回调函数

  • zk分布式锁实现
    1. 多个 cli 创建临时顺序节点
    2. 判断自己是不是最小的节点,是,就是获得分布式锁,执行业务
    3. 不是,给自己节点的前一个节点注册事件回调,当该节点删除了,说明轮到自己了获得分布式锁了,执行业务