浅谈缓存三大问题

关于缓存

​ 大部分系统都存在缓存机制,防止过多直接对数据库的请求操作,增加系统的稳定性与效率。

##可能导致的问题

###问题一:缓存穿透

​ 缓存穿透是指查询一个不存在的数据,由于缓存不存在该数据,因此该请求会直接去数据库查询(直接穿透了缓存层)。若有人恶意多次进行该操作可能导致数据库瘫痪

####解决方案

  1. 把所有可能的查询生成一个类似于哈希表的结构,在进行数据库查询前会利用该结构进行过滤,如果不在其中直接过滤掉,从而减轻数据库层面的压力

  2. 在第一次查询不到某个key对应的val值时,我们把该key和空值存入缓存中

###问题二:缓存雪崩

​ 一般缓存都会有一个失效时间,如果所有缓存的实效时间相同,可能会导致在某一时刻同时失效后,所有请求都发送到数据库层从而导致数据库崩溃

####解决方案

  1. 只让一个线程构建缓存,其它线程等待构建缓存的线程执行完毕后再重新从缓存中获取数据。

    1. 错开不同失效时间即可从一定长度上避免这种问题,因此我们设置缓存实效时间时可以在一个范围内取随机值

###问题三:缓存击穿

​ 缓存击穿是缓存雪崩的特例,缓存击穿是指某一个缓存失效后有大量请求发送到数据库层导致其崩溃。与雪崩相比,它只是一个点并不是全部(比如微博的一个热点缓存失效后依然有大量该热点信息的请求)

####解决方案

  1. 对热点数据进行二级缓存,并对不同级别的缓存设定不同的失效时间

  2. 采用LRU算法,即最近最少使用。依据“长期不被使用的数据,未来用到的概率也不大“,因此当内存达到阈值时,首先淘汰最近最少被使用的数据,具体实现过程为:

    (1)创建一个缓存哈希链表用于存储数据(相比哈希表多了一个指针用于链表排序)

    (2)添加新节点的时候,将新节点添加到链表尾部

    (3)若该节点以存在,把该节点移动到链表的尾部

    (4)当缓存链表已满时,添加新节点的时候,会把链表头部移除,然后将新节点添加到尾部

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/88527557