空き RAM はたくさんあるのですが、IO は常に 100 % 使用かそれに近い状態です。RAM を増やして IO を減らすにはどうしたらいいでしょうか? iotop には、IO レートが最も高い nginx ワーカー プロセスが表示されています。これは、1 MB から 2 GB のファイルを提供するファイル サーバーです。これが私の 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
これは単なる 1 つの観察なので、この回答を受け入れないでください。ただし、4 MB を超えるファイルには直接 IO を使用し、ファイルに対して nginx に 1.5 MB のメモリ バッファーのみを許可します。
directio 4m;
output_buffers 3 512k;
私の記憶が正しければ、ダイレクト IO は基本的にファイル システム IO キャッシュをバイパスして HDD から直接読み取ります。したがって、4 MB を超えるファイルの場合はファイルをバッファリングするためにメモリは使用されず、4 MB 未満のファイルの場合は 1.5 MB のメモリのみが使用されます。
答え3
いくつかのリクエストをメモリから直接処理したいようですが、これは本質的にはそれらのリクエストをキャッシュすることになります。基本的な形式では、リクエストを処理し、そのコピーをメモリベースのキャッシュに保存し、同じリソースに対する後続のリクエストをメモリから処理します (キャッシュされたコピーを無効化/期限切れにするまで)。
この実装は、サイトの性質によって異なります (つまり、非常に大きなファイルを提供する場合はそれほど実用的ではありません。コンテンツが非常に動的な場合はそれほどメリットがありません)。ただし、「平均的な」サイトでは、ページの I/O のほとんどが静的リソース (特に画像) から発生するため、ディスク I/O が削減されます (また、速度も向上します)。
バックエンド サーバーにプロキシしている場合は、nginx の proxy_cache ディレクティブを使用してページをキャッシュできます。ただし、キャッシュの場所は通常ディスク上にあります (これにより速度は向上しますが、ディスク I/O は節約されない可能性があります)。この問題を回避するには、キャッシュを保存するためのメモリ (つまり、ramdisk) にマップされた tmpfs を作成します。同様に、FastCGI を使用している場合は fastcgi_cache を使用できます。
もう 1 つの同様のオプション (たとえば、nginx をプロキシとして使用しておらず、FastCGI も使用していない場合) は、ページを MemCached に保存することです。Nginx には memcached モジュールが付属しており、これを使用して独自のキャッシュ メカニズムを設定できます。
あるいは、Nginx の前にキャッシュ プロキシ (Varnish など) を追加するだけで、リクエストを受信して直接処理するか、リクエストを Nginx に渡すことができます。Varnish は、キャッシュをメモリ (またはファイル - ただし、I/O には役立ちません) に保存するように構成でき、最小限のディスク I/O でキャッシュ ヒットを処理します。
答え4
worker_processes 32;
— まだ理由を推測していますか?
空きRAMはたくさんあるのですが
sendfile off;
また、所有および使用の理由も聞きたいのですdirectio
が、directio が (定義上) FS キャッシュを禁止していることを知っているのは私だけでしょうか (そうではないはずです¹)?
__ ¹ — Martin F、少なくともこれも覚えておいてください:nginxによるIOの削減