再说nginx cache

上一次写nginx cache应该还是10年前了,那时候好像是nginx 0.7.4开始的。
当时记得用的是tmpfs做的缓存目录,主要那时候公司钱多。96G的机器随便堆。

这次又要缓存后面rest服务器的静态资源。用的ssd,可观察了下iowait还是会到50%左右经常。看了下主要是写导致的。

下面这个是这次的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
proxy_temp_path /cache/nginx/proxy_temp;
proxy_cache_path /cache/nginx/cx_cache levels=1:2 keys_zone=cx_cache:200m inactive=1d max_size=100g;

proxy_cache cx_cache;
proxy_cache_revalidate on;
proxy_cache_key "$request_uri $http_thumbnail";
proxy_cache_methods HEAD GET;
proxy_cache_valid 200 301 302 304 1d;
proxy_cache_min_uses 1;
add_header Cache-Concrol public;
expires 1d;
add_header Nginx-Cache "$upstream_cache_status";
proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;

proxy_ignore_headers 这个是一定要加的,这次发现要是后端返回内容里带了cookie信息就居然无法缓存了。

下面这个是官方的解释,这个我记得原先最老的版本是没有,看来确实要与时俱进啊。

1
2
3
4
5
6
7
8
9
10
11
Disables processing of certain response header fields from the proxied server. 
The following fields can be ignored:
“X-Accel-Redirect”, “X-Accel-Expires”, “X-Accel-Limit-Rate” (1.1.6), “X-Accel-Buffering” (1.1.6), “X-Accel-Charset” (1.1.6), “Expires”, “Cache-Control”, “Set-Cookie” (0.8.44), and “Vary” (1.7.7).

If not disabled, processing of these header fields has the following effect:

“X-Accel-Expires”, “Expires”, “Cache-Control”, “Set-Cookie”, and “Vary” set the parameters of response caching;
“X-Accel-Redirect” performs an internal redirect to the specified URI;
“X-Accel-Limit-Rate” sets the rate limit for transmission of a response to a client;
“X-Accel-Buffering” enables or disables buffering of a response;
“X-Accel-Charset” sets the desired charset of a response.

然后关于proxy_cache_path这块也有更新的了。

关于max_size超过的大小,nginx会进行LRU。原先貌似也没有。但是还是没有多级缓存。(这个意思就是最热的数据在内存,次热的在ssd这种,nginx自动的在多级缓存里进行lru)。网上所有说多个proxy_cache_path的做法都没解决这个问题。

1
2
3
4
The cache manager is activated periodically to check the state of the cache.
If the cache size exceeds the limit set by the max_size parameter to the proxy_cache_path directive,
the cache manager removes the data that was accessed least recently.
As previously mentioned, the amount of cached data can temporarily exceed the limit during the time between cache manager activations.

这个从对应的配置上也没有体现, 但是每次清理的间隔,时间这些都有了默认值也可以进行配置了。

1
2
3
4
Syntax:	proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size
[inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time]
[manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time]
[purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

最后关于cache_key的设置,这个原先我记得只能是url和对应的参数,但是其实现在是可以加入http请求头来作为参数的。

1
proxy_cache_key "$request_uri $http_thumbnail";

最后说一下,虽然内存已经已经飞快了,那我们还是在mount的时候加下noatime。