singleflight在缓存击穿中的应用(缓存穿透、缓存雪崩、缓存击穿的介绍,以及go版源码赏析)

一、先简单介绍下缓存穿透、缓存雪崩、缓存击穿及一些解决思路

1、缓存

缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。——百度百科

我理解的缓存就是能使应用更快更方便地获取数据的一种技术。

2、缓存穿透

缓存穿透指的是:同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。

比如说:用户查询的id是数据库不存在的,所以这个时候这些并发请求都不会命中缓存,将直接访问数据库,同时数据库中也没有查到该数据,也没法放入缓存,这样如果同一时刻大量的并发请求到达数据库,数据库承受不住这么高的并发,就会导致数据库直接挂了,这就是缓存穿透。

一些解决方法:

(1)缓存空值:

当某个值在缓存中查不到,在数据库中也查不到时,也需要将该值缓存起来,只不过值是空的。这样后面的请求,再拿相同的值发起请求时,就能从缓存中获取空数据,直接返回了,而无需再去查一次数据库。

但这个方法也有问题,万一这个空值刚缓存起来,数据库就加了这个数据,导致明明存在的数据查出来的确实空值。

(2)布隆过滤器:

一种些许暴力的方法:如果数据比较少,直接把数据库中的数据全部放到内存的一个map中。这样能够非常快速的识别数据在缓存中是否存在。如果存在,则让其访问缓存。如果不存在,则直接拒绝该请求。

但一般数据量都很大,上述方法会占用太多的内存空间了。这样就可以考虑使用一些技术来减少内存空间,比如之前分享的布隆过滤器

使用布隆过滤器也是可以,但是也有问题:比如误判率(如果布隆过滤器判断出某个key存在,可能出现误判。如果判断某个key不存在,则它在数据库中一定不存在),感觉影响不大。

使用布隆过滤器还有个问题是:如果数据库中的数据更新了,需要同步更新布隆过滤器。但它跟数据库是两个数据源,就可能存在数据不一致的情况。

当然还有一些别的方法,但是感觉并没有十分完美的方法能去解决缓存穿透,多多少少都有一些问题。

3、缓存雪崩

在使用缓存时,通常会对缓存设置过期时间,一方面目的是保持缓存与数据库数据的一致性,另一方面是减少冷缓存占用过多的内存空间。

缓存雪崩指的是:当缓存中大量热点缓存采用了相同的实效时间,就会导致缓存在某一个时刻同时实效,请求全部转发到数据库,从而导致数据库直接挂了,从而形成一系列的连锁反应,造成系统崩溃等情况,这就是缓存雪崩。(当然还有可能缓存服务器出问题了也可能会导致缓存雪崩)

一些解决方法:

通常的解决方案是将key的过期时间后面加上一个随机数(比如随机1-5分钟),让key均匀的失效。

当然还有很多别的方法,这里就先不具体展开。

4、缓存击穿

上面的缓存雪崩是大量热点key同时失效的情况,如果是单个热点key,在不停的扛着大并发,在这个key失效的瞬间,持续的大并发请求就会击破缓存,直接请求到数据库,数据库受不了又直接挂了,这就是缓存击穿

比如热搜排行上,一个热点新闻被同时大量访问,当缓存过期的一瞬间就可能导致缓存击穿。

解决方法:

在下面主要介绍如何使用golang的singleflight库来解决缓存击穿以及其原理。

当然还有别的方法。

二、singleflight在缓存击穿中的应用

偶然发现golang里面自带singleflight包

但是不幸的是它是go的内部包,并不能直接使用,但是官方辅助包golang.org/x/...里提供了singlefligh

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值