ATS代理缓存的那点事

达芬奇密码2018-07-25 10:29

最近在搭建NOS多分区部署环境,其中有富媒体模块使用到了Apache Traffic Server,主要是用来缓存已处理过的富媒体资源,提升响应速度,减轻后端服务的压力。

ATS搭建完成后,重复访问同样对象发现缓存并未生效,直接代理到后端服务处理,查看ATS日志发现结果是这样的:

1498530991.859 70 10.180.192.5 TCP_MISS/200 650 GET http://10.180.194.10:8088/tobie-test-bj/car.jpg?imageView&thumbnail=10x10 - DIRECT/10.180.194.10 image/jpeg - 

显然没有命中,即本地未缓存成功,我们期望的结果是这样的:

1498531420.233 0 10.180.192.5 TCP_IMS_HIT/304 165 GET http://10.180.194.10:8088/tobie-test-bj/car.jpg?imageView&thumbnail=10x10 - NONE/- - - 

很明显问题应该出在缓存配置方面,为此深入了解了下ATS缓存机制,带着问题对ATS缓存相关配置进行详细了解。

ATS缓存机制

  • 主要组件TrafficServer

1. TS 缓存包含一个高速的对象数据库,数据库根据URL和相关头部来索引对象,对于同一对象可以缓存不同版本(如不同的编码、语言)。
2. 当缓存空间满后,TS会移除过期的数据。
3. 当磁盘出错时,TS将不再使用该块磁盘,转而使用剩下的磁盘。所有磁盘都出错时,TS将切换至proxy-only模式,即只代理,不缓存。可分区,即可以给指定的协议和源服务器划分一定数量的磁盘空间。
  • HTTP代理缓存相关机制

    用户请求到ATS,TS收到请求后通过访问资源的地址,在对象数据库中检索此对象,存在两种情况,一种是对象资源存在缓存中,另外一种是资源部在缓存中,两种情况处理分别如下:

    1. 如果对象资源在缓存中,TS会检查对象是否新鲜

      a. 如果新鲜,TS从缓存里返回该对象给用户,此时称为缓存命中

      b. 如果不新鲜,TS会连接源服务器去验证对象是否仍然新鲜,即重新验证(revalidation),如果仍然新鲜,TS立即将缓存中的副本返回给用户

    2. 如果对象不在缓存中(缓存未命中,cache miss),或者缓存的副本不再有效,TS 会去源服务器获取对象,然后同时做下面两件事

      a. 将对象返回给用户

      b. 将对象放到本地缓存中

从上面过程来看判断对象是否新鲜的过程非常重要,清楚了解判断过程对我们问题解决或许会有一定的帮助,在介绍整个判断逻辑前,让我们先熟悉下几个和缓存相关的HTTP Header。

1. Expires: 服务端返回给客户端的header,给出的日期/时间后,被响应认为是过时。通常需和Last-Modified结合使用。用于控制请求文件的有效时间,当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端,当缓存中数据失效或过期,才决定从服务器更新数据。
2. Last-Modified:在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记(HttpReponse Header)此文件在服务期端最后被修改的时间。
3. Cache-Control:max-age同Expires基本一致,不同的是前者是http1.1的产物,两个header同时存在是前者覆盖后者。max-age = 秒,表示资源在本地缓存多少秒。

了解了上面的header后再来看判断对象是否新鲜的过程:

1. 如果有 Expires 或者 max-age 头部直接定义缓存的过期时间,TS将对比当前时间和过期时间去判断对象是否新鲜
2. 如果没有上述头部,TS将检查Last-Modified和Date头部(其中Date是源服务器返回对象的时间,如果没有 Last-Modified 头部,TS会用对象写入缓存的时间以作代替),然后用以下公式算出新鲜的时间范围(freshness_limit,可理解为保质期):
                 freshness_limit = ( Date - Last-Modified ) x 0.1
    0.1 这个参数可以作调整,并且能限制 freshness_limit的上下限,默认最小是1小时,最大是 1 天(默认配置在 heuristic expiration部分配置)
3. 如果没有Expires头部或者没有Last-Modified、Date头部,TS将使用默认的fressness limit
4. TS 还会检查cache.config配置文件中的 revalidate规则,该规则可以对特定的 HTTP 对象设置特定的验证时间(特定的域名、IP、一定规则的URL、特定的客户端等等)

ATS缓存相关配置详解

ATS所有的配置在安装目录下etc/trafficserver下面,其中缓存相关配置在目录下面的records.config文件中。

在records.config文件中找到下面标记,便能看到所有cache相关的配置:

#################
# cache control #
#################  

具体关键配置介绍如下:

变量 描述
proxy.config.http.cache.http 此变量相对简单,为打开缓存功能,0表示关闭,1表示打开
proxy.config.http.cache.heuristic_lm_factor 设置这个变量来指定计算有效期的老化因子,就是我们上文提到的计算过期时间中的因子,Traffic Server存储该对象从其上次修改后这个百分比的时间。默认值为0.1(10%)
proxy.config.http.cache.heuristic_min_lifetime 上文提到的默认有效最小时间便是这个变量,设置这个变量来指定没有截止时间的HTTP对象在缓存中有效期的最小值。默认值为3600秒(1小时)
proxy.config.http.cache.heuristic_max_lifetime 上文提到的默认有效最大时间便是这个变量,设置这个变量来指定没有截止时间的HTTP对象在缓存中有效期的最大值。默认值为86400秒(1天)
proxy.config.http.cache.required_headers 设置这个变量为下列值之一:
0 = 对头部没有特殊要求,
1 = 需要是Last-Modified头部,或者有明确生命期的头部,Expires或者Cache-Control: max-age,
2 = 需要明确的生命期,Expires或者Cache-Control: max-age
proxy.config.http.cache.when_to_revalidate 设置这个变量为下列值之一:
0 = 配置TrafficServer重新生效HTTP对象,当它认为该对象在缓存中已过期(如果可以的话,TrafficServre检查对象头部和有效期极值)。这是默认配置。
1 = 配置Traffic Server重新生效没有Expires或Cache-Control头部的HTTP对象。
2 = 配置TrafficServer总是重新生效HTTP对象;Traffic Server总是认为HTTP对象是过期的。
3 = 配置Traffic Server从不重新生效HTTP对象;TrafficServer总是认为HTTP对象是有效的。

在NOS中使用到ATS的模块,本身会有一定的一致性校验,那么在ATS本身缓存来说无需进行必要的缓存更新判断,希望能够对对象保证认为不失效,除非是客户端告知ATS失效,比如通过添加no-cache头的形式。

从上面最后一个配置项可以看出,此配置项对缓存是否有效有着决定作用,为此检查了此配置项发现值设置为了2,那么必然每次请求都认为是过期的,导致出现缓存失效的现象,将此配置调整为3,问题得到解决。

本文来自网易实践者社区,经作者刘成授权发布。