Назад | Перейти на главную страницу

Что могло заставить Nginx писать столько операций ввода-вывода?

У меня есть веб-сервер с высоким трафиком (до ~ 50 загрузок страниц в секунду), на котором запущен nginx, который передает HTML-запросы в бэкэнд PHP-FPM и напрямую обслуживает статические ресурсы.

Под этой нагрузкой я получаю необычно большой объем дискового ввода-вывода от рабочих процессов nginx. Мои страницы обслуживают множество статических изображений, которые меняются каждые несколько часов, поэтому ожидается много операций чтения с диска, но на самом деле я вижу больше записи, чем чтения, с постоянной скоростью записи порядка 10 МБ / с процессами nginx. (как указано iotop).

Когда мои контейнеры докеров активны в течение 12 дней, я получаю эту историю ввода-вывода для одного из процессов nginx:

$ cat /proc/nginx-pid/io
rchar: 34537119315778
wchar: 27295224195419
syscr: 2217567839
syscw: 2285538495
read_bytes: 1499124252672
write_bytes: 7338930909184
cancelled_write_bytes: 141058945024

Это 1,5 ТБ, прочитанное за 12 дней, что имеет смысл, учитывая мои статические ресурсы и трафик, но 7,3 ТБ, записанные на диск с помощью nginx, кажутся мне безумием.

Вот результат time strace -p $nginx_pid -c в течение 60 секунд:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 33.05    0.840451           5    178693      2446 write
 16.52    0.420117           4    104554           pread64
 10.09    0.256603           6     39772         1 readv
  9.24    0.234970          11     20994           pwritev
  6.60    0.167708          16     10700       188 open
  4.92    0.125204           3     37249           epoll_wait
  4.47    0.113708           3     41601     20572 read
  3.70    0.094091          23      4154      4154 connect
  3.16    0.080408           5     15515           close
  1.77    0.045090          11      4260           writev
  1.42    0.036188           9      4139           rename
  0.92    0.023423           6      4139           chmod
  0.68    0.017227           2     10515           fstat
  0.57    0.014555           3      5131           epoll_ctl
  0.53    0.013573           3      4154           socket
  0.53    0.013569           3      4903           recvfrom
  0.35    0.008942           2      5892           getpid
  0.31    0.007828           2      4156           getsockopt
  0.28    0.007092           2      3725           getsockname
  0.28    0.007003           2      4154           ioctl
  0.24    0.006143           5      1258         1 stat
  0.19    0.004889           4      1324       670 accept4
  0.12    0.003023           4       690           pwrite64
  0.04    0.001125           2       631           setsockopt
------ ----------- ----------- --------- --------- ----------------
100.00    2.542930                512303     28032 total
2.55user 7.57system 1:00.56elapsed 16%CPU (0avgtext+0avgdata 840maxresident)k
0inputs+0outputs (0major+273minor)pagefaults 0swaps

Некоторая соответствующая конфигурация nginx:

worker_processes  8;
worker_rlimit_nofile 20000;
worker_connections  5000;
multi_accept on;
use epoll;
access_log off;
sendfile    on;
tcp_nopush  on;
tcp_nodelay on;
open_file_cache max=10000 inactive=60s;
open_file_cache_valid 5s;
open_file_cache_min_uses 6;
fastcgi_buffers 8 16k;

Я не понимаю, почему я должен ожидать, что процесс nginx будет писать так много, особенно с отключенным журналом доступа. Бег lsof -p nginx-pid показывает, что большинство файлов, открытых процессом, являются обслуживаемыми сокетами и изображениями. Только сокеты открыты с разрешениями на запись, поэтому я предполагаю, что вся эта запись должна происходить через них?

Мои диски смонтированы с relatime вариант, поэтому я не ожидаю записи на диск при каждом чтении этих изображений. Размер буфера FastCGI должен быть в состоянии обрабатывать ответы страницы размером 128 КБ, и этого должно быть достаточно для моих целей. Предупреждений об использовании временных файлов в журнале нет.

У меня есть настройка кеша FastCGI:

fastcgi_cache_path /shm/nginx/fastcgi levels=1:2 keys_zone=microcache:10m max_size=10m inactive=1m;
fastcgi_cache_key $scheme$request_method$host$request_uri;
fastcgi_cache microcache;
fastcgi_cache_valid 200 5s;
fastcgi_cache_lock on;
fastcgi_cache_lock_timeout 5s;
fastcgi_cache_lock_age 5s;

Может ли все это письмо быть написано для этого? Вроде довольно много.

Что мне не хватает? Это нормальное количество операций ввода-вывода (предположительно, запись в сокеты) для активного веб-сервера?