深入理解 Go 语言缓解压力利器 SingleFlight

        缓存系统是我们提高程序性能最常用的手段之一,它把经常要读取的程序放在内存中,避免对后台数据库等进行频繁的访问。常用的缓存系统有 Memcached、Redis等,或者自定义缓存系统。

        缓存系统虽然好,但也面临着三大问题。

  • 缓存雪崩:某一时刻大规模的缓存同时失效,或者缓存系统重启,导致大量的请求无法从缓存中读取到数据,请求就会直接访问数据库,导致后台数据库等无法承受巨大的压力,可能瞬间就会崩溃。这种情况就称作缓存雪崩。

        解决缓存雪崩的方法是将 key 的失效时间加一个随机值,避免大量的 key 同时失效。通过限          流,避免大量的请求同时访问数据库。新缓存节点上线前先进行预热,也可以避免刚上线就            发生雪崩。

  • 缓存击穿:如果有大量的请求同时访问某个 key, 一旦这个 key 失效(过期),就会导致这些请求同时访问数据库。这种情况就称作缓存击穿。它和缓存雪崩不同,雪崩是访问大量的 key 导致的,而击穿是访问同一个 key 导致的。解决方法就是使用 SingleFlight 同步原语。

  • 缓存穿透:如果请求要访问的 key 不存在,那么它就访问不到缓存系统,它就会去访问数据库。假如有大量这样的请求,这些请求像 “穿透” 了缓存一样直接访问数据库,这种情况就称作缓存穿透。解决方法是在缓存系统中给不存在的 key 设置一个空值或特殊值,或者使用布隆过滤器等快速检查 key 是否存在。

         SingleFlight 是 Go 团队提供的一个扩展同步原语。它的作用是在处理多个 goroutine 同时调用同一个函数时,只让一个 goroutine 调用这个函数,当这个 goroutine 返回结果时,再把结果返回给这几个同时调用的 goroutine, 这样就可以减少并发调用的数量。

        Go 标准库中的 sync.Once 也可以保证并发的 goroutine 只会执行一次函数 f ,那么 SingleFlight 和 sync.Once 有什么区别呢?

         其实,sync.Once 不仅在并发访问时保证只有一个 goroutine 执行函数 f,而且会保证永远只执行一次这个函数;而 SingFlight 是每次调用时都重新执行函数 f,并且有多个请求同时调用时只有一个请求执行这个函数。它们面对的场景是不同的,sync.Once 主要被应用在单次初始化的场景中,而 SingleFlight 主要被应用在合并并发请

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mindfulness code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值