我有很多可用 RAM,但我的 IO 始终是 100%util 或非常接近。我可以通过哪些方式通过使用更多 RAM 来减少 IO?我的 iotop 显示 nginx 工作进程具有最高的 IO 速率。这是一个文件服务器,提供从 1mb 到 2gb 的文件。这是我的 nginx.conf
#user nobody;
worker_processes 32;
worker_rlimit_nofile 10240;
worker_rlimit_sigpending 32768;
error_log logs/error.log crit;
#pid logs/nginx.pid;
events {
worker_connections 51200;
}
http {
include mime.types;
default_type application/octet-stream;
access_log off;
limit_conn_log_level info;
log_format xfs '$arg_id|$arg_usr|$remote_addr|$body_bytes_sent|$status';
sendfile off;
tcp_nopush off;
tcp_nodelay on;
directio 4m;
output_buffers 3 512k;
reset_timedout_connection on;
open_file_cache max=5000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
client_body_buffer_size 32k;
server_tokens off;
autoindex off;
keepalive_timeout 0;
#keepalive_timeout 65;
答案1
打开 sendfile。保留 output_buffers 的默认值。关闭 directio。添加更多 RAM。
没有什么比 linux VFS 缓存更好的了。
答案2
请不要接受这个答案,因为这只是一种观察。但是您对超过 4M 的文件使用直接 IO,并且仅允许 nginx 为文件提供 1.5MB 的内存缓冲区。
directio 4m;
output_buffers 3 512k;
如果我没记错的话,直接 IO 基本上绕过了文件系统 IO 缓存,直接从 HDD 读取。因此,对于超过 4M 的文件,您无需使用内存来缓冲文件,而对于小于 4M 的文件,您仅使用 1.5M 内存。
答案3
看起来您想直接从内存中处理某些请求 - 这实际上相当于缓存这些请求。在其基本形式中,您将处理请求,将副本存储在基于内存的缓存中,并从内存中处理对同一资源的后续请求(直到您使缓存的副本无效/过期为止)。
其实施方式将根据您网站的性质而有所不同(例如,如果您提供非常大的文件,它将不那么实用 - 如果您的内容高度动态,它将不会提供太多好处等) - 但对于“普通”网站 - 由于大多数页面的 i/o 来自静态资源(尤其是图像),它将减少磁盘 i/o(并且也应该加快速度)。
如果您代理后端服务器,则可以使用 nginx 的 proxy_cache 指令来缓存页面。但是,缓存位置通常位于磁盘上(这可能会加快速度,但可能不会节省磁盘 i/o)- 您可以通过创建映射到内存(即 ramdisk)的 tmpfs 来存储缓存,从而解决这个问题。同样,如果您使用 FastCGI,则可以使用 fastcgi_cache。
另一个类似的选项(例如,如果您不使用 nginx 作为代理,也不使用 FastCGI)是将页面存储在 MemCached 中。Nginx 附带一个 memcached 模块,它允许您设置自己的缓存机制。
或者,您可以简单地在 Nginx 前面添加一个缓存代理(例如 Varnish) - 它将接收请求,并直接提供服务或将请求传递给 Nginx。Varnish 可以配置为将其缓存存储在内存中(或文件 - 虽然这对您的 i/o 没有帮助),并将以最少的磁盘 i/o 提供缓存命中。
答案4
worker_processes 32;
— 你还在猜测为什么吗?
我有很多可用内存,但是
我还想听听关于拥有sendfile off;
和使用的理由directio
——我是唯一一个(肯定不是¹)知道 directio(根据定义)禁止 FS 缓存的人吗?
__ ¹ — Martin F,至少还记得这一点:减少 nginx 引起的 IO