Go singleflight 第三方库在防止缓存击穿中的重要作用

本文介绍了Go语言中的singleflight库,如何通过重复请求抑制机制降低并发读请求对数据库的压力,避免缓存击穿,并详细讲解了其工作原理、使用方法和注意事项,包括DoCall和Forget函数的异步调用以及数据结构的设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:

一、背景

介绍:Go的singleflight库提供了一个重复的函数调用抑制机制。
场景:适用于并发读请求量较大的后台服务,以降低存储层的压力。
在大量请求同时请求某一个热点key的场景下,singleflight方法可以很好的解决缓存击穿问题。

  • 优点:可以避免同一时间内,大量相同的流量请求都打到数据库上进而引起其压力。通过限制对同一个键值对的多次重复请求,减少对下游如MySQL的瞬时流量。
  • 缺点:但是依然有可能阻塞大量请求导致系统等待获取缓存数据的goroutine激增,因此需要灵活使用 DoCall()异步调用方法和 Forget()方法。

二、原理

将一组相同的请求合并成一个请求。实际上最终只会有 第一个 请求会访问DB,在其获取到结果后,通过本地内存对剩余其他阻塞的请求返回相同结果
在这里插入图片描述
如上图所示:请求1、2、3同时请求相同的key,singleflight机制只会让请求1访问DB,请求1返回的value不仅返回给客户端1,也作为请求2、请求3的结果返回给客户端。这里的多请求理解为多个goroutine并发执行。

底层实际上是通过 go map(区分是否是相同key的请求) + lock(线程安全) + waitgroup(阻塞其他请求),将请求1从DB获取的结果直接通过本地内存去返回给其他相同的请求。

三、使用方法

// Do:传入key和fn回调函数,如果key相同,fn方法只会执行一次,同步等待
// 返回值v:表示fn执行结果
// 返回值err:表示fn的返回的err
// 返回值shared:表示是否是真实fn返回的还是从保存的map[key]返回的,也就是共享的
func (g *Group) Do(key string, fn func() (interface{
   }, error)) (v interface{
   }, err error, shared bool) {
   ...}

// DoChan:与Do方法类似,区别在于执行函数fn非阻塞,结果通过chan返回给同组请求
func (g *Group) DoChan(key string, fn 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值