概述

点击查看【bilibili】

缓存问题

  1. 什么是redis缓存穿透
  2. 缓存击穿、穿透、雪崩
  3. 布隆过滤器的核心原理
  4. 如何基于本节课知识出去吹比?

缓存穿透

缓存穿透 如果查询数据的时候,在redis查不到,去mysql中查询,这个现象就叫缓存穿透,低频高频都算

低端黑客攻击: 某低端黑客频繁使用 一定不存在的固定id请求你的接口,造成数据库超负荷,怎么办?

解决方案:
将任何mysql的查询结果都缓存到redis中 (包括Null )

正常黑客:使用脚本每次换不同的id频繁尝试.

布隆过滤器

优点:有效过滤绝大多数非法攻击; 占用内存小, 1亿数据只占用0.1164GB内存
缺点:必定存在的key必定不会被拦截,必定不存在的key可能不会被拦截(与存在的key发生hash碰撞时)
用途:1.反恶意攻击,过滤不存在的请求 2.避免推荐已读文章
image.png
-> 点我去知乎:5分钟搞懂布隆过滤器
布隆过滤器的误判率:(大概10分之1)
布隆过滤器有一个可预测的误判率(FPP):

【精品】缓存问题 - 图2

  • n 是已经添加元素的数量;
  • k 哈希的次数; 3-5个就可以了,如果过多,太多的桶位被标记为1,反而让误判率大幅提高
  • m 布隆过滤器的长度(如比特数组的大小);

阿里云redis的tailBloom数据结构实现的布隆过滤器,支持动态扩容,支持用户设定误判率(0-1之间),且扩容时误判率不变,但设定的误判率越低,内存和cpu使用率越高。

在程序设计时,如何向布隆过滤器添加key?

两种方案:1. redis或Mysql get前插入 2. 先get数据,在异步任务中,添加key.
推荐方案二, 异步标记。还没标记成功,get请求就到了怎么办?异步标记的延迟没那么高,基本没必要考虑

有哪些常见的BF常用的hash函数?

BKDRHash , SDBMHash, DJBHash

【笔试】设计一个布隆过滤器

缓存击穿

缓存失效,海量并发击穿数据库。击穿是穿透的一种特殊情况。

怎么解决缓存击穿?
  1. 分布式锁。
  2. 多级缓存 越高级的缓存时郊果越短
  3. 定时刷新 跑一个job定时主动去更新快要过期的缓存

分布式锁

什么情况需要加分布式锁?

资源共享、请求互斥、多任务环境

Redis分布式锁问题

死锁
  1. 设置超时时间;

能够避免大多数死锁,但存在问题:
a. 死锁。当正在执行的应用进程和分布式锁中间件同时挂掉,仍然存在死锁可能。redis宕机后 expire不会在下次启动时执行。
b. 一票多卖和超卖。 当timeOut超时时间=10分钟 ,但因机器卡顿/fullGC等原因,程序执行超过10分钟,锁提前释放,则可能会造成一票多卖和超卖问题.

如何优化上述问题?使用基于zookeeper的分布式锁。
【笔试】设计一个分布式锁?

缓存雪崩

所有redis数据在同一时间同时失效,大量请求压在数据上。雪崩也是穿透的一种特殊情况。

什么原因导致雪崩?
  1. 同一时间失效 : 给每条数据设置时效+随机有效期
  2. redis宕机 redis集群迁移 -> 集群和主从切换;使用一致性hash算法。

一致性hash算法

数据分片时 水平扩展做更少的数据迁移。
该算法的牛比之处在于:不管集群中有多少机器 ,每次需要迁移数据的机器 不会大于新增机器数+1
缺点:更容易发生数据倾斜(数据不能均匀分布在每台机器)。如何解决?虚拟节点。

【笔记】 设计一个一致性hash算法

缓存与db的一致性

【精品】缓存问题 - 图3

先commit数据库再更新

threadA: commit
threadB: commit
threadB: updateCache
thrreadA: updateCache

先删除缓存再commit

【精品】缓存问题 - 图4

延时双删

时间怎么确定 commit最大时间+读写分离主从同步的时间+100ms