缓存-简单介绍

一、缓存概述

1、什么是缓存

缓存在wiki上的定义:
用于存储数据的硬件或软件的组成部分,以使得后续更快访问相应的数据。
缓存中的数据可能是提前计算好的结果、数据的副本等。
典型的应用场景:有cpu cache, 磁盘cache等。
本文中提及到缓存主要是指互联网应用中所使用的缓存组件。

2、为什么引入缓存

  1. 传统的后端业务场景中,访问量以及对响应时间的要求均不高,通常只使用DB即可满足要求。
  2. 这种架构简单,便于快速部署,很多网站发展初期均考虑使用这种架构。
  3. 但是随着访问量的上升,以及对响应时间的要求提升,单DB无法再满足要求。
  4. 这时候通常会考虑DB拆分(sharding)、读写分离、甚至硬件升级(SSD)等以满足新的业务需求。
  5. 但是这种方式仍然会面临很多问题,主要体现在:
  •  性能提升有限,很难达到数量级上的提升,尤其在互联网业务场景下,随着网站的发展,访问量经常会面临十倍、百倍的上涨。
  •  成本高昂,为了承载N倍的访问量,通常需要N倍的机器,这个代价难以接受。

二、缓存分类

缓存在宏观上可以分成两类:私有缓存和共享缓存。

共享缓存就是那些能被各级代理缓存的缓存(咋觉得有点绕)。
私有缓存就是用户专享的,各级代理不能缓存的缓存。

微观上可以分下面三类:

1. 浏览器缓存

我相信只要你经常使用某个浏览器(Chrome,Firefox,IE等),肯定知道这些浏览器在设置里面都是有个清除缓存功能,这个功能存在的作用就是删除存储在你本地磁盘上资源副本,也就是清除缓存。
缓存存在的意义就是当用户点击back按钮或是再次去访问某个页面的时候能够更快的响应。尤其是在多页应用的网站中,如果你在多个页面使用了一张相同的图片,那么缓存这张图片就变得特别的有用。

2. 代理服务器缓存

代理服务器缓存原理和浏览器端类似,但规模要大得多,因为是为成千上万的用户提供缓存机制,大公司和大型的ISP提供商通常会将它们设立在防火墙上或是作为一个独立的设备来运营。(下文如果没有特殊说明,所有提到的缓存服务器都是指代理服务器。)
由于缓存服务器不是客户端或是源服务器的一部分,它们存在于网络中,请求路由必须经过它们才会生效,所以实际上你可以去手动设置浏览器的代理,或是通过一个中间服务器来进行转发,这样用户自然就察觉不到代理服务器的存在了。
代理服务器缓存就是一个共享缓存,不只为一个用户服务,经常为大量用户使用,因此在减少相应时间和带宽使用方面很有效:因为同一个缓存可能会被重用多次。

3. 网关缓存

也被称为代理缓存或反向代理缓存,网关也是一个中间服务器,网关缓存一般是网站管理员自己部署,从让网站拥有更好的性能。
CDNS(网络内容分发商)分布网关缓存到整个(或部分)互联网上,并出售缓存服务给需要的网站,比如国内的七牛云、又拍云都有这种服务。

4. 数据库缓存

数据库缓存是指当我们的应用极其复杂,表自然也很繁杂,我们必须进行频繁的进行数据库查询,这样可能导致数据库不堪重负,一个好的办法就是将查询后的数据放到内存中,下一次查询直接从内存中取就好了。关于数据库缓存本篇不会展开。

三、浏览器的缓存策略

缓存的目标:

  • 一个检索请求的成功响应: 对于 GET请求,响应状态码为:200,则表示为成功。一个包含例如HTML文档,图片,或者文件的响应;
  • 不变的重定向: 响应状态码:301;
  • 可用缓存响应:响应状态码:304,这个存在疑问,Chrome会缓存304中的缓存设置,Firefox;
  • 错误响应: 响应状态码:404 的一个页面;
  • 不完全的响应: 响应状态码 206,只返回局部的信息;
  • 除了 GET 请求外,如果匹配到作为一个已被定义的cache键名的响应;
以上,对于我们可以和应该缓存的目标有个了解。
浏览器对于缓存的处理是根据第一次请求资源时返回的响应头来确定的。
那么浏览器怎么确定一个资源该不该缓存,如何去缓存呢❓响应头!响应头!响应头!重要的事情说三遍。✌️

看图识过程

四、HTTP中和缓存相关的首部字段

1、HTTP报文是什么呢?

就是HTTP报文,这是一个概念,主要由以下两部分构成:
  1. 首部(header):包含了很多字段,比如:cookie、缓存、报文大小、报文格式等等);
  2. 主体(body):HTTP请求真正要传输的部分,比如:一个HTML文档,一个js文件;
以上我们知道浏览器对于缓存的处理过程,也简单的提到了几个相关的字段。
接下来我们具体看下这几个字段:

1.通用首部字段

字段名称:                                            说明:

  • Cache-Control                          控制缓存具体的行为
  • Pragma                                     HTTP1.0时的遗留字段,当值为”no-cache”时强制验证缓存
  • Date                                          创建报文的日期时间(启发式缓存阶段会用到这个字段)

2. 响应首部字段

字段名称:                                            说明:

  • ETag                                             服务器生成资源的唯一标识
  • Vary                                              代理服务器缓存的管理信息
  • Age                                                资源在缓存代理中存贮的时长(取决于max-age和s-maxage的大小)

3. 请求首部字段

字段名称:                                            说明:

  • If-Match                                      条件请求,携带上一次请求中资源的ETag,服务器根据这个字段判断文件是否有新的修改
  • If-None-Match                          和If-Match作用相反,服务器根据这个字段判断文件是否有新的修改
  • If-Modified-Since                     比较资源前后两次访问最后的修改时间是否一致
  • If-Unmodified-Since                比较资源前后两次访问最后的修改时间是否一致

4. 实体首部字段

字段名称:                                            说明:

  • Expires                                         告知客户端资源缓存失效的绝对时间
  • Last-Modified                             资源最后一次修改的时间

五、浏览器缓存控制

 

1. Cache-Control

通过cache-control的指令可以控制告诉客户端或是服务器如何处理缓存。这也是11个字段中指令最多的一个,我们先来看看请求指令:
指令
参数
说明
  • no-cache
强制源服务器再次验证
  • no-store
不缓存请求或是响应的任何内容
  • max-age=[秒]
缓存时长,单位是秒
缓存的时长,也是响应的最大的Age值
  • min-fresh=[秒]
必需
期望在指定时间内响应仍然有效
  • no-transform
代理不可更改媒体类型
  • only-if-cached
从缓存获取
  • cache-extension
-
新的指令标记(token)

2、响应指令:

指令
参数
说明
  • public
任意一方都能缓存该资源(客户端、代理服务器等)
  • private
可省略
只能特定用户缓存该资源
  • no-cache
可省略
缓存前必须先确认其有效性
  • no-store
不缓存请求或响应的任何内容
  • no-transform
代理不可更改媒体类型
  • must-revalidate
可缓存但必须再向源服务器进确认
  • proxy-revalidate
要求中间缓存服务器对缓存的响应有效性再进行确认
  • max-age=[秒]
缓存时长,单位是秒
缓存的时长,也是响应的最大的Age值
  • s-maxage=[秒]
必需
公共缓存服务器响应的最大Age值
  • cache-extension
-
新指令标记(token

请注意
no-cache指令很多人误以为是不缓存,这是不准确的,no-cache的意思是可以缓存,但每次用应该去想服务器验证缓存是否可用。no-store才是不缓存内容。另外部分指令也可以组合使用,
比如:
Cache-Control: max-age=100, must-revalidate, public

 

上面指令的意思是缓存的有效时间为100秒,之后访问需要向源服务器发送请求验证,此缓存可被代理服务器和客户端缓存。

 

六、避免雪崩

     雪崩效应是由于缓存服务器宕机等原因导致命中率降低,大量的请求穿透到数据库,导致数据库被冲垮,业务系统出现故障,服务很难再短时间内回复。避免雪崩主要从以下几方面考虑:
  • 缓存高可用
    避免单点故障,保证缓存高命中率
  • 降级和流控
    故障期间通过降级非核心功能来保证核心功能可用性
    故障期间通过拒掉部分请求保证有部分请求还能正常响应
  • 清楚后端资源容量
    更好的预知风险点,提前做好准备
    即使出现问题,也便于更好的流控(具体应该放量多少)

数据一致性

    我们知道,在CAP理论下,只能取其二,而无法保证全部。在分布式缓存中,通常要保证可用性(A)和可扩展性(P),并折中采用数据最终一致性,最终一致性包括:
  • Master与副本一致性
  • Cache与Storage一致性
  • 业务各维度缓存数据一致性

缓存容量规划

    进行缓存容量规划时,主要从以下几个方面进行考虑:
  • 请求量
  • 命中率:预热,防止雪崩
  • 网络带宽:网卡、交换机
  •  存储容量:预估存储大小,过期策略、剔除率
  • 连接数

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注