У меня есть веб-сервер с высоким трафиком (до ~ 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;
Может ли все это письмо быть написано для этого? Вроде довольно много.
Что мне не хватает? Это нормальное количество операций ввода-вывода (предположительно, запись в сокеты) для активного веб-сервера?