我编写了一个快速的 Python 服务器来提供重新采样的图像。例如,URL 可能类似于http://images.domain.com/resample/100x100/9f362e1994264321.jpg
。由于重新采样图像的成本很高,因此需要缓存层。似乎 nginx 反向代理是一个不错的选择,并且这里和这里似乎是个不错的起点。
但是,有一个问题。图像有数百万张,因此如果将其存储http://images.domain.com/resample/100x100/9f362e1994264321.jpg
在文件系统中/home/nginx/cache/resample/100x100/9f362e1994264321.jpg
(或类似的东西),最终cache/resample/100x100/
将包含数百万个文件,这将使文件查找非常低效。
我在存储原始图像时通过将图像分布在许多子目录中来解决这个问题,例如9f/36/9f362e1994264321.jpg
。但是,我不确定如何使用 nginx 做同样的事情。我可以更改 URL 来做同样的事情,如果这是唯一的解决方案,我会这样做,但我宁愿让 URL 尽可能漂亮。
我可以用 nginx 来做这个吗?如果不行,我可以用其他东西来做吗,比如 varnish?
答案1
你绝对应该阅读有关ngx_http_proxy_模块.html。
Directiveproxy_cache
正是您所需要的。配置应该类似于以下内容。
http {
# ...
proxy_cache_path /var/www/cache levels=1:2 keys_zone=imgcache:10m max_size=1000m inactive=720m;
proxy_temp_path /var/www/cache/tmp;
# ...
server {
# ...
location /resample {
proxy_pass http://bla.bla.my.backend;
proxy_cache imgcache;
#proxy_cache_key $scheme$proxy_host$request_uri;
#proxy_cache_valid 200 302 60m;
#proxy_cache_valid 404 10m
}
# ...
}
}
在/var/www/cache
文件夹中将创建两级目录结构。并缓存响应http://mysite.com/resample/dir/file.jpg将保存为proxy_cache_key
值的 md5。例如,如果您取消#proxy_cache_key $scheme$proxy_host$request_uri;
上面的注释,响应将缓存到文件 /var/www/cache/f/08/8db24849a311cc3314955992686d308f
因为
MD5 ("http://bla.bla.my.backend/resample/dir/file.jpg") = 8db24849a311cc3314955992686d308f
and level=1:2 转换为 dir 结构,从最后一个字符开始计数,...08f --> f/08/md5value
答案2
这将使得文件查找非常低效。
这听起来像是过早的优化。
您没有提供任何有关此操作系统的信息。既然您提到了 Varnish,我猜想这是某种 Unix。假设它是 Linux(尽管其中大部分也适用于其他操作系统)....
您是否真的测量过并将其与路径重写方法进行比较?如果您看到性能下降,则可能是您运行的文件系统非常老旧(或已通过部分修补升级)。使用 ext4 或 BTRFS,我预计不会看到可测量的差异。
但这不是重点。反向代理知道它们可能缓存大量文件 - 并且不一定会将 URL 路径直接映射到文件系统路径。
您将遇到由缓存管理大量文件的问题 - 但这些问题与 VFS/方法有关。降低 vfs_cache_pressure 应该会有所帮助。