背景
在项目中,有些产品介绍类图片、文档会存储到hdfs中,但hdfs的存取速度比较慢,不能满足互联网用户的要求,这里就使用缓存方式,将不经常变化文件缓存到nginx代理服务器,以减少HDFS的读取次数,提高用户访问速度。
Nginx缓存原理
缓存技术的基本思想其实是对用户已经访问过的内容在Nginx建立副本,如果在一段时间内(缓存尚未过期)再次访问该数据,则不需要重新发起请求获取数据,可以直接从缓存中读取到该数据,好处在于减少了Nginx与后端服务之间的网络交互,减轻了网络的压力,而且在减少数据传输的延迟时同时可以提升用户访问速度。而且如果碰上后端服务出现异常时,还可以通过缓存进行相应用户请求,提高了后端服务的稳定性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kUtfe4tx-1579162275349)(en-resource://database/2234:1)]
启用代理缓存
启用代理缓存需要进行两步操作,一是配置缓存通用配置包括路径、目录级别、失效策略等,二是在对应的地址使用缓存。
配置proxy_cache_path
在http模块下配置对应信息。格式如下:
proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];
示例代码:
proxy_cache_path /opt/app/cache_test levels=1:2 keys_zone=cache_test:10m inactive=1d max_size=1g;
参数说明:
- path:指定缓存区的根路径,此目录不会自动创建,需要提前创建成功。
- levels:设置缓存文件目录层次,默认所有缓存文件都放在同一个path参数路径下,但是会影响缓存的性能,因此通常会在此路径下面建立子目录用来分别存放不同的文件。最高三层,每层1-2个字符表示。如1:1:2三层,1:2 表示两级目录;假设levels=1:2,Nginx为将要缓存的资源生成的key为f4cd0fbc769e94925ec5540b6a4136d0,那么key的最后一位0,以及倒数第2-3位6d作为两级的子目录,也就是该资源最终会被缓存到/path/to/cache/0/6d目录中
- keys_zone:设置缓存名字和共享内存大小。在共享内存中设置一块存储区域来存放缓存的key和metadata(类似使用次数),这样nginx可以快速判断一个request是否命中或者未命中缓存,1m可以存储8000个key,10m可以存储80000个key。如cache_item:10m表示声明一个名为cache_item大小为10m。超出大小 后最早的数据将被清除。
- inactive:内存中缓存的过期检查周期。1h:1小时;1d:1天。示例配置中如果在指定时间内都没有被访问,则不论状态是否为expired,都会清除缓存。需要注意的是,inactive 和 expired 配置项的含义是不同的。
- max_size: 最大cache空间,如果不指定,会使用掉所有disk space,当达到配额后,会删除最近最少使用的cache文件。
- use_temp_path:如果为 off,则 nginx 会将缓存文件直接写入指定的 cache 文件中,而不使用 temp_path 指定的临时存储路径
Nginx启动后,缓存加载程序只进行加载一次,加载时会将缓存的元数据加载到共享内存区域,但是如果一次加载整个缓存全部内容可能会使Nginx刚启动的前几分钟性能消耗严重,大幅度降低Nginx的性能。所以可以在proxy_cache_path命令中配置缓存迭代加载。缓存迭代加载一共可以设置三个参数:
- loader_threshold - 迭代的持续时间,以毫秒为单位(默认为200)
- loader_files - 在一次迭代期间加载的最大项目数(默认为100)
- loader_sleeps - 迭代之间的延迟(以毫秒为单位)(默认为50)
配置proxy_cache
在对应的location节点下启用缓存。参数说明:
- proxy_cache:对应 http 段的 key_zone,是你定义的 proxy_cache 所使用的共享空间的名称,上面定义的是cache_test,所以在这里也写的是cache_test。
- proxy_cache_valid:对指定的 HTTP 状态进行缓存,并指定缓存时间。可以自定义写入多个配置项。这里我们对200和304的返回码缓存12小时。其余的缓存10分钟
- proxy_cache_key:Web缓存的Key值,Nginx根据Key值md5哈希存储缓存缓存,is_args:如果$args设置,值为"?",否则为""
- proxy_next_upstream 当请求服务器发生错误或超时时,会尝试到下一台服务器
示例
location / {
proxy_pass http://slbserver_cache; #通过upstrean定义的服务器组名调用后端服务器
proxy_redirect off ;
proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#跟后端服务器连接超时时间,发起握手等候响应时间
proxy_connect_timeout 300;
#后端服务器回传时间,就是在规定时间内后端服务器必须传完所有数据
proxy_send_timeout 300;
#连接成功后等待后端服务器的响应时间,已经进入后端的排队之中等候处理
proxy_read_timeout 600;
#代理请求缓冲区,会保存用户的头信息以供nginx进行处理
proxy_buffer_size 256k;
#同上,告诉nginx保存单个用几个buffer最大用多少空间
proxy_buffers 4 256k;
#如果系统很忙时候可以申请最大的proxy_buffers
proxy_busy_buffers_size 256k;
#proxy缓存临时文件的大小
proxy_temp_file_write_size 256k;
#如果某台应用服务器出现500,400或者超时情况,直接访问下一台
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
#使用Web缓存区cache_test,proxy_cache_path中设置好的那个名字,关闭参数为off。
proxy_cache cache_test ;
#对不同HTTP状态码缓存设置不同的缓存时间
proxy_cache_valid 200 304 1m ;
#设置Web缓存的Key值,Nginx根据Key值md5哈希存储缓存,这里根据"域名,URI,#参数"组合成Key
proxy_cache_key $uri$is_args$args;
}
在http头中体现,以及在nginx日志中查看缓存命中情况
在location配置中添加:
add_header Nginx-Cache "$upstream_cache_status";
在nginxlog中添加:
log_format combinedio …$upstream_cache_status;
原理:
利用nginx $upstream_cache_status变量,该变量代表缓存命中的状态,状态包括:
- MISS: 未命中,请求被传送至后台处理;
- HIT: 缓存命中;
- EXPIRED: 缓存已经过期,请求被传送至后台处理;
- UPDATING: 正在使用缓存,将使用新的应答;
- STALE: 后端得到过期的应答;
问题:配置成功后一直显示miss
在配置完成后,缓存一直显示miss,发现一般有两个原因导致此问题。
一, 返回信息中包含错误的header.
当返回信息中Cache-Control
和Set-Cookie
。可以在nginx中通过proxy_ignore_headers设置忽略它们,如:
server {
listen 80;
listen [::]:80;
server_name 镜像服务器主机名;
location / {
......
proxy_ignore_headers Set-Cookie Cache-Control;
proxy_hide_header Cache-Control;
proxy_hide_header Set-Cookie;
......
}
}
二,关闭了响应内容的缓冲区,导致无法缓存返回信息
需要打开缓存,将proxy_buffering
设置为on。如:
location ~ (^/).*\.(gif|jpg|jpeg|png|js|css|html|cab|bmp)${
......
proxy_buffering on;
......
}
参考:
Nginx proxy_cache 缓存配置
Nginx缓存原理及机制
Nginx实战-缓存服务proxy(1)
Nginx作为缓存服务