今天我们就来说说在大规模分布式系统中应该如何使用缓存。毕业已经三年多了,我们经历了几十个大大小小的系统。今天我们就从各个角度来探讨一下。让我们看看我们不同的缓存应该如何使用,以便能够有效地使用它们。

我们团队目前正在研发直播产品。以抖音为例。比如我们要开发一个顶哥、二哥等排行榜,怎么开发呢?对于抖音对于这个亿级产品来说,缓存设计一定是家常便饭。

对于百万级、千万级的接口调用,如果没有缓存设计,直接命中数据持久层,那将是一场毁灭性的灾难。我每天都会经历数百万次的接口调用。由于缓存设计不严谨,缓存失效后,瞬间冲击到数据库层。幸好报警及时修复,差点就遭遇了p0故障。

一般来说,缓存分为客户端缓存服务器缓存。最常见的客户端缓存是浏览器缓存,它是通过http控制的缓存。

客户端缓存

基于请求响应模式,大多数场景下客户端通过https协议请求后台获取数据。如果高频接口每天被调用数百万次,即使是短期的客户端缓存也会带来高效的收益。

由于客户端到服务器要经过较长的网络链路以及多变的网络环境,数据包小到几十K,大到几十M,使得复杂多变的网络得救了。要求的时间。

客户端缓存减少了客户端和服务器之间的通信次数和成本。只要缓存可用,就可以及时响应数据。

最常见的客户端缓存是浏览器缓存。简而言之,就是http缓存。不知道大家在实际开发过程中是否使用过这段代码:

ResponseEntity.ok().cacheControl(CacheControl.maxAge(3, TimeUnit.SECONDS)).body()

看他的包,是springframework框架下的http包下的工具类。

导入org.springframework.http.CacheControl;
导入org.springframework.http.ResponseEntity;

在浏览器缓存中,http协议头有这样一个键值字段进行控制,称为Cache-Control:max-age=30,max-age标记了资源缓存在多少上客户 第二。

如果max-age=0,则表示不缓存数据。除了max-age可以控制数据的缓存状态之外,还有以下三个属性可以控制缓存状态no_store、no_cache、must-revalidate

  1. no_store表示不缓存数据,每次都去服务器获取
  2. no_cache 好像也是不缓存的意思,其实是可以缓存的意思。不过在使用缓存之前,你得去服务器验证数据是否有效、是否过期、是否是最新版本
  3. must-revalidate有点类似于no_cache,就是如果缓存没有过期,就可以继续使用。如果过期了,需要去服务器验证

除了Cache-Control可以使用客户端缓存之外,http中还有一个条件请求头可以更智能地使用客户端缓存。

条件请求是根据响应消息中返回的“Last-modified”和“ETag”来实现的。 Last-modified 资源的最后修改时间,ETag 代表资源的唯一标识。你可以理解,只要修改资源,就会不一样

再次请求时,请求头中会包含“If-None-Match:ETag 返回的值”,以验证资源是否有效。

如果

有效,则会返回“304 Not Modified”,表示缓存资源有效,可以继续使用。