关于golang:缓存系统稳定性-架构师峰会演讲实录

29次阅读

共计 2214 个字符,预计需要花费 6 分钟才能阅读完成。

前言

大家好!我是万俊峰,go-zero 作者。感激 ArchSummit 提供这么好的机会来跟大家分享一下 go-zero 的缓存最佳实际。

首先,大家能够想一想:咱们在流量激增的状况下,服务端哪个局部最有可能会是第一个瓶颈?我置信大部分人遇到的都会是数据库首先扛不住,量一起来,数据库慢查问,甚至卡死。此时,下层服务有怎么强的治理能力都是杯水车薪的。

所以咱们常说看一个零碎架构设计的好不好,很多时候看看缓存设计的如何就晓得了。咱们已经遇到过这样的问题,在我退出之前,咱们的服务是没有缓存的,尽管过后流量还不算高,然而每天到流量顶峰时间段,大家就会特地缓和,一周宕机好几回,数据库间接被打死,而后啥也干不了,只能重启;我过后还是参谋,看了看零碎设计,只能救急,就让大家先加上了缓存,然而因为大家对缓存的认知不够以及老零碎的凌乱,每个业务开发人员都会依照本人的形式来手撕缓存。这样导致的问题就是缓存用了,然而数据七零八落,压根没有方法保证数据的一致性。这的确是一个比拟苦楚的经验,应该能引起大家的共鸣和回顾。

而后我把整个零碎推倒从新设计了,其中缓存局部的架构设计在其中作用非常明显,于是有了明天的分享。

我次要分为以下几个局部跟大家探讨:

  • 缓存零碎常见问题
  • 单行查问的缓存与主动治理
  • 多行查问缓存机制
  • 分布式缓存零碎设计
  • 缓存代码自动化实际

缓存零碎波及的问题和知识点是比拟多的,我分为以下几个方面来探讨:

  • 稳定性
  • 正确性
  • 可观测性
  • 标准落地和工具建设

因为篇幅太长,本文作为系列文章第一篇,次要跟大家探讨『缓存零碎稳定性』

缓存零碎稳定性

缓存稳定性方面,网上根本所有的缓存相干文章和分享都会讲到三个重点:

  • 缓存穿透
  • 缓存击穿
  • 缓存雪崩

为什么首先讲缓存稳定性呢?大家能够回顾一下,咱们何时会引入缓存?个别都是当 DB 有压力,甚至常常被打挂的状况下才会引入缓存,所以咱们首先就是为了解决稳定性的问题而引入缓存零碎的。

缓存穿透

缓存穿透存在的起因是申请不存在的数据,从图中咱们能够看到对同一个数据的申请 1 会先去拜访缓存,然而因为数据不存在,所以缓存里必定没有,那么就落到 DB 去了,对同一个数据的申请 2、申请 3 也同样会透过缓存落到 DB 去,这样当大量申请不存在的数据时 DB 压力就会特地大,尤其是可能会歹意申请打垮(不怀好意的人发现一个数据不存在,而后就大量发动对这个不存在数据的申请)。

go-zero 的解决办法是:对于不存在的数据的申请咱们也会在缓存里短暂(比方一分钟)寄存一个占位符,这样对同一个不存在数据的 DB 申请数就会跟理论申请数解耦了,当然在业务侧也能够在新增数据时删除该占位符以确保新增数据能够立即查问到。

缓存击穿

缓存击穿的起因是热点数据的过期,因为是热点数据,所以一旦过期可能就会有大量对该热点数据的申请同时过去,这时如果所有申请在缓存里都找不到数据,如果同时落到 DB 去的话,那么 DB 就会霎时接受微小的压力,甚至间接卡死。

go-zero 的解决办法是:对于雷同的数据咱们能够借助于 core/syncx/SharedCalls 来确保同一时间只有一个申请落到 DB,对同一个数据的其它申请期待第一个申请返回并共享后果或谬误,依据不同的并发场景,咱们能够抉择应用过程内的锁(并发量不是十分高),或者分布式锁(并发量很高)。如果不是特地须要,咱们个别举荐过程内的锁即可,毕竟引入分布式锁会减少复杂度和老本,借鉴奥卡姆剃刀实践:如非必要,勿增实体。

咱们来一起看一下上图缓存击穿防护流程,咱们用不同色彩示意不同申请:

  • 绿色申请首先达到,发现缓存里没有数据,就去 DB 查问
  • 粉色申请达到,申请雷同数据,发现已有申请在解决中,期待绿色申请返回,singleflight 模式
  • 绿色申请返回,粉色申请用绿色申请共享的后果返回
  • 后续申请,比方蓝色申请就能够间接从缓存里获取数据了

缓存雪崩

缓存雪崩的起因是大量同时加载的缓存有雷同的过期工夫,在过期工夫达到的时候呈现短时间内大量缓存过期,这样就会让很多申请同时落到 DB 去,从而使 DB 压力激增,甚至卡死。

比方疫情下在线教学场景,高中、初中、小学是分几个时间段同时开课的,那么这时就会有大量数据同时加载,并且设置了雷同的过期工夫,在过期工夫达到的时候就会对等呈现一个一个的 DB 申请波峰,这样的压力波峰会传递到下一个周期,甚至呈现叠加。

go-zero 的解决办法是:

  • 应用分布式缓存,避免单点故障导致的缓存雪崩
  • 在过期工夫上加上 5% 的标准偏差,5% 是假设检验里 P 值的经验值(有趣味的读者能够自行查阅)

咱们做个试验,如果用 1 万个数据,过期工夫设为 1 小时,标准偏差设为 5%,那么过期工夫会比拟平均的散布在 3400~3800 秒之间。如果咱们的默认过期工夫是 7 天,那么就会均匀分布在以 7 天为中心点的 16 小时内。这样就能够很好的避免了缓存的雪崩问题。

未完待续

本文跟大家一起探讨了缓存零碎的常见稳定性问题,下一篇我来跟大家一起剖析缓存的数据一致性问题。

所有这些问题的解决办法都已蕴含在 go-zero 微服务框架里,如果你想要更好的理解 go-zero 我的项目,欢送返回官方网站上学习具体的示例。

视频回放地址

ArchSummit 架构师峰会 - 海量并发下的缓存架构设计

我的项目地址

https://github.com/tal-tech/go-zero

欢送应用 go-zero 并 star 反对咱们!

微信交换群

关注『微服务实际 』公众号并点击 进群 获取社区群二维码。

go-zero 系列文章见『微服务实际』公众号

正文完
 0