1请求数据时候,先从缓存中取数据, 取到就返回结果,没有话则从数据库取,数据库取到的话返回结果,如果数据库中没有数据就返回空结果
1.缓存穿透
缓存穿透是用户对不的存在的数据进行发起请求 such as: 用户请求的id= -1 的数据,当然肯定不会有这条数据、那就的去数据库里查找,数据库里找不到,就全表扫描,那么很可能此用户就是攻击者,而收到攻击,数据库的压力会增大,进而导致数据库压力巨大。
solution(解决方法)
Reference 引用(布隆过滤器)
原理是对于一个 key 进行n个把不同的hash算法获取n个值,在比特数组中将这个n值的数据下表为1,查的时候如果某个key的在数组中k个位置都为1,布隆过滤器判断该key可能存在(并不一定存在)
例如: 比特数组 Bytearray 大小为 16, 则其原始数据为 [ 0000 0000 0000 0000 ].
添加:对"hello"经过2个不同的hash算法获得该数组中两个下标(3,5)则比特数组为 [0001 0100 0000 0000], 下标位置 Bytearray[3] = 1,Bytearray[5] = 1;
查找: 对"hello" j经过两个不同hash算法获取值(3,5),去查找Bytearray[3]和Bytearrat[5]
的值,都为1,则肯恶搞存在,因为下标Bytearray[3]和 Bytearray[5]等于1 可能是其他元素经过hash留下的标记,Hello可能不存在
“结论:”
每个元素k次hash后,在数据的下标都不相同,则可以认为布隆过滤器的准确率为100
BloomFilter的核心思想
1.多个hash,增大随机性,来减少hash碰撞的概率
2.扩大数据范围,使hash值均匀分布,进一步减少hash碰撞的概率.
- 缓存击穿
缓存击穿是指缓存中没有但数据库中有的单条数据(通常由缓存过期造成)被并发查询,并发请求非常多,同时读缓存没有读到又同时去读数据库,造成数据库压力过大.
解决方法:
设置热点数据永不过期.
加互斥锁,读数据库时需要获取锁,一条请求拿到锁之后读取数据并更新缓存,其他未获得锁请求延时后再去读取缓存数据.
3. 缓存雪崩
缓存雪崩发生时说明缓存中大批量的数据过期,而查询量巨大,请求直接到达数据库,造成数据库压力剧增.
解决方法:
随机设置缓存数据过期是时间,防止大规模缓存数据同时间过期.
设置热点数据永不过期.
分布式部署的缓存将热点数据均匀分布在不同的缓存数据库中.
4. 缓存一致性
要求数据库数据更新时缓存中的数据也能实时更新.
解决方法:
数据库更新时立即去更新缓存.
读缓存数据前判断缓存是否是最新的,不是则先进行更新.
5. 缓存清理策略
1.FIFO(先进先出) :最先进入缓存的数据在缓存空间不足时被优先清除.
2.LFU(最少使用) :无论数据是否过期,根据其使用的次数判断,清除使用次数最少的数据.
3.LRU(最近最少使用):
无论数据是否过期,根据数据最后一次被使用的时间戳,清除最远使用时间戳的数据.
实现:
LinkedHashMap 中的 accessOrder 属性设置为 true 时将根据元素的访问顺序将最近访问的数据放在双向链表尾部, 同时重写其 removeEldestEntry() 方法指定数据淘汰条件,即可实现LRU.
6. 缓存分类
6.1.本地缓存
缓存数据保存在单个服务器内存中,各个服务器之间缓存的数据相互独立
优点:读取速度快
缺点:分开存储可能出现一台应用服务器的数据有更新,而其他服务器数据没有更新,导致数据不一致的问题.
6.2.集中式缓存
缓存数据保存在专门的缓存服务器中,应用服务器通过网络请求从缓存服务器获取缓存数据。
优点:集中管理缓存,保证数据一致性
缺点:网络请求需要消耗时间,读取频繁的话网络请求消耗的时间成本可能比将数据从内存读取出来的成本还要高。