正常请求
- Redis总中存放的是访问频率很高的热点数据
- 热点请求大部分情况下都会命中redis,只有少部分请求redis没命中,去访问数据库
- 访问数据库后,需要将查询的数据回填到redis
- 原则上说,对于会进行修改的热点数据都需要设置超时时间,以保证万一出现异常,能确保数据的最终一致性。
缓存穿透
- 请求一个redis中不存在的数据,该请求必定穿透redis到达数据库,当请求足够频繁,会导致数据库崩溃
- 当redis短时间失效,请求会全部落到数据库,造成数据库短时间崩溃
- 当redis数据丢失,请求全部穿透到数据库,造成数据库崩溃,回填数据失败,并且后续的请求依然会穿透redis,造成系统持续崩溃。
解决方案
- 对于频繁访问redis一定不存在的数据,导致请求穿透到数据库,引起数据库崩溃。可以在第一次从数据库获取数据后(为获取到数据)向缓存设置一个销毁key(销毁时间5分钟)
- 对于redis数据大量丢失,导致请求都穿透到数据库,引发数据库崩溃的情况,我们可以在请求数据库失败后向redis设置一个销毁key(销毁时间30s-2m随机),缓解数据库压力,慢慢自愈。
- 布隆过滤器
布隆过滤器
- K个hash函数,每个函数把K散列成一个整数
- 初始化时,需要一个长为nbit的数组,每个bit位初始化为0
- 当加入key时,用k个hash函数计算k个散列,并把数组中对应的bit位设置为1
- 某个k是否存在,用k个hash计算k个散列值,查询数组对应的比特位,如果为1,则存在
优点:快速、省空间
缺点:
- 有一点的误差率,存入key增加,误差率增加,如果key比较少,用散列表就足够了
- 无法删除数据
如何做:先预计元素有n个,可接受的错误率为f。
k(hash函数的最佳数量)如何计算:k=0.7*(1/n)
L(位数组的长度)如何计算:f=0.6185^(L/n),计算出L
使用redis自带的bf.add, bf.exists, bf.madd,bf.reserve