У меня много свободной оперативной памяти, но мой IO всегда 100 %util или очень близок к этому. Какими способами я могу уменьшить IO, используя больше оперативной памяти? Мой iotop показывает рабочие процессы nginx с самой высокой скоростью io. Это файловый сервер, обслуживающий файлы размером от 1 МБ до 2 ГБ. Вот мой 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. Добавьте больше оперативной памяти.
Нет ничего лучше кэша Linux VFS.
решение2
Пожалуйста, не принимайте этот ответ, так как это всего лишь одно наблюдение. Но вы используете прямой ввод-вывод для файлов размером более 4 МБ и позволяете nginx только 1,5 МБ буфера памяти для файлов.
directio 4m;
output_buffers 3 512k;
Если я правильно помню, то прямой ввод-вывод в основном обходит кэш ввода-вывода файловой системы, чтобы читать напрямую с жесткого диска. Таким образом, для файлов размером более 4 МБ вы не используете память для буферизации файла, а для файлов размером менее 4 МБ вы используете только 1,5 МБ памяти.
решение3
Похоже, что вы хотите обслуживать некоторые запросы напрямую из памяти, что по сути равносильно кэшированию этих запросов. В своей базовой форме вы обрабатываете запрос, сохраняете копию в кэше на основе памяти и обслуживаете последующие запросы на тот же ресурс из памяти (до тех пор, пока вы не сделаете кэшированную копию недействительной/не истечет срок ее действия).
Реализация этого будет зависеть от характера вашего сайта (например, если вы обслуживаете очень большие файлы, это будет не так практично, если ваш контент очень динамичен, он не принесет такой пользы и т. д.), но для «среднего» сайта, где большая часть ввода-вывода страницы приходится на статические ресурсы (особенно изображения), это сократит объем ввода-вывода на диске (и должно ускорить работу).
Если вы проксируете на бэкенд-сервер, вы можете использовать директиву proxy_cache nginx для кэширования страниц. Однако кэш обычно располагается на диске (что может ускорить работу, но не сэкономить на дисковом вводе/выводе) — вы можете обойти это, создав tmpfs, сопоставленный с памятью (т. е. ramdisk), в котором будет храниться ваш кэш. Аналогично, если вы используете FastCGI, вы можете использовать fastcgi_cache.
Другой, похожий вариант (например, если вы не используете nginx в качестве прокси и не используете FastCGI) — хранить страницы в MemCached. Nginx поставляется с модулем memcached, который позволит вам настроить собственный механизм кэширования.
В качестве альтернативы вы можете просто добавить кэширующий прокси перед Nginx (например, Varnish) — который будет получать запросы и либо обслуживать их напрямую, либо передавать запрос в Nginx. Varnish можно настроить для хранения кэша в памяти (или файле — хотя это не поможет вашему вводу-выводу) и будет обслуживать попадания в кэш с минимальным вводом-выводом на диске.
решение4
worker_processes 32;
— вы все еще гадаете почему?
У меня много свободной оперативной памяти, но
Я также хотел бы услышать аргументы по поводу наличия sendfile off;
и использования directio
— я единственный (конечно, нет¹), кто знает, что Directio (по определению) запрещает кэширование FS?
__ ¹ — Мартин Ф., по крайней мере, помнит и это:Уменьшение IO, вызванного nginx