缓存及缓存穿透解决方案
缓存的认识
我们的程序中频繁地使用到某些数据和对象,而这些数据和对象的获取和初始化需要消耗大量的时间或服务器性能,这时我们就要考虑对它们进行缓存,以使程序的执行更高效。例如从磁盘读取xml配置文件,若程序中需要频繁地使用配置文件中的配置信息,每次使用时都直接从磁盘读取,频繁的IO操作必然带来程序性能的下降,这时我们需要使用缓存;
缓存中间件
缓存的设计
-
Insert:
新增数据至数据库 -
Update:
删除缓存中对应的数据
修改数据库的数据 -
Delete:
删除缓存中对应数据
删除数据库的数据 -
Query:
查询缓存中数据,存在数据即返回查询的数据
缓存中不存在数据则查询数据库存在数据则返回数据库中数据并同步更新到缓存
缓存和数据库都不存在数据返回null
总结: 数据的修改和更新都是在查询数据的时候实时更新的.
缓存穿透:
缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。(应用程序穿过缓存中间件产品,直达数据库进行数据访问的过程)
缓存穿透问题:
1.如果用户无限基于不存在的key进行重复请求,怎么办
把key和查询出来null值,作为键值对,存入缓存中,下次查询的时候直接将null值返回给用户
2.如果恶意攻击者发现系统的漏洞,频繁用大量不存的key进行请求,怎么办?
使用布隆过滤器,判断元素是否存在,呢么如果有一亿无序的无规则,不重复的元素数据的数据集,快速判断元素是否存在.
如何从大数据集中判断元素是否存在
- 容器选择:(bitmap位图)
1.内存占用小(1G大约可存80亿的bit)
2.快速查找(可以以数组下表的方式进行访问)
- **算法选择:**哈希算法
- 1.确定性(计算多次的结果一致)
- 2.允许任意的输入且保证固定长度的输出
哈希算法缺点:
不同的数值的哈希值有几率是相同,产生了哈希碰撞,目前来说没办法彻底解决哈希碰撞问题,但是可以降低哈希碰撞的误报
至于为什么采用三种不同的哈希函数取值, 因为三个哈希值只要有一个不存在就说明数据一定不在过滤器中, 这样做是可以减小因哈希碰撞产生的错误概率.
Boom Filter不存在漏报,存在误报
空间越大,数组长度越大,要求误报率越小,呢么位数组长度越长导致计算成本越高(耗时耗内存).