Начиная с версии 0.8.11 в nginx появилась новая возможность для раздачи статики — использование AIO (Asyncronous Input-Output — неблокирующий ввод-вывод) для Linux и FreeBSD.
Чем это событие знаменательно? До этого момента nginx использовал неблокирующий режим только при работе с сетью — любая работа с файлами блокировала рабочий процесс. К чему это приводило? Если у вас есть много разного контента, который не весь находится в кэше ОС (фотохостинг, etc) — то рано или поздно все 50, 150, 200 процессов будут ждать дисковые операции и не смогут обслужить нового клиента — даже если нужный ему контент можно отдать из файлового кэша или запросить с бэкенда.
Как с этим боролись раньше?
Теперь появился новый способ, задействовав небольшое количество рабочих процессов, раздавать всё в неблокирующем режиме. Тестирование будет эмулировать нагрузку на файловый/картиночный хостинг — отдача большого числа относительно небольших файлов. Диск при этом упирается в скорость random seek.
Методика тестирования:
Выводы: судя по тому, что с AIO удалось добиться 300 rps, что заметно превышает seek rate для используемых дисков, ядро FreeBSD умеет внутри переупорядочивать запросы, идущие через AIO, что даёт значительный выигрыш при отсутствии «умного» raid-контроллера с большим кэшем. При использовании же традиционного метода — большое количесто рабочих процессов, если они все уйдут на диск, сказывается на производительности лишь отрицательно.
PS: несколько замечаний по методике. Скорость генерации случаных имён файлов — достаточная, добавляет <0.5мсек на запрос (точнее измерять не было необходимости, такой скорости достичь не удалось). Возможно, в тестах с aio на большом количестве потоков был достигнут потолок канала. Время проведения каждого теста — две минуты.
PPS: работа AIO на Linux не проверялась, результаты могут отличаться в любую сторону.
Чем это событие знаменательно? До этого момента nginx использовал неблокирующий режим только при работе с сетью — любая работа с файлами блокировала рабочий процесс. К чему это приводило? Если у вас есть много разного контента, который не весь находится в кэше ОС (фотохостинг, etc) — то рано или поздно все 50, 150, 200 процессов будут ждать дисковые операции и не смогут обслужить нового клиента — даже если нужный ему контент можно отдать из файлового кэша или запросить с бэкенда.
Как с этим боролись раньше?
- Первый метод — увеличивать количество рабочих процессов. Но, сколько бы их ни было, всегда есть шанс, что на диске заблокируются все.
- Второй способ — раздавать динамику и статику разными nginx'aми. Но запросы на популярную статику всё рано не будут обслуживаться так быстро, как могли бы.
- Ещё больше усложнить 2ю схему — определить понятие «популярные файлы», и раздавать их так же отдельно. Но кэш ОС всегда будет работать эффективнее, чем свой собственный список популярности (да и это, по сути, повторение логики работы кэша)
Теперь появился новый способ, задействовав небольшое количество рабочих процессов, раздавать всё в неблокирующем режиме. Тестирование будет эмулировать нагрузку на файловый/картиночный хостинг — отдача большого числа относительно небольших файлов. Диск при этом упирается в скорость random seek.
Методика тестирования:
- Тестовый сервер — OC FreeBSD 7.2 stable, 2xSATA 150GB 7200 rpm raid1, 2gb ram
- Объём памяти под файловый кэш ~1.2gb
- Объём тестовых файлов ~2.5 gb, каждый файл занимает 8-16кб, send-буфер в nginx выставлен на 16кб
- nginx версии 0.8.19
- Тестирующий сервер — подключен по сети, пропускная способность канала ~20mbit
- Нагрузка создавалась утилитой ab, для генерации случайного имени файла использовался fastcgi скрипт, отдающий X-Accel-Redirect
Выводы: судя по тому, что с AIO удалось добиться 300 rps, что заметно превышает seek rate для используемых дисков, ядро FreeBSD умеет внутри переупорядочивать запросы, идущие через AIO, что даёт значительный выигрыш при отсутствии «умного» raid-контроллера с большим кэшем. При использовании же традиционного метода — большое количесто рабочих процессов, если они все уйдут на диск, сказывается на производительности лишь отрицательно.
PS: несколько замечаний по методике. Скорость генерации случаных имён файлов — достаточная, добавляет <0.5мсек на запрос (точнее измерять не было необходимости, такой скорости достичь не удалось). Возможно, в тестах с aio на большом количестве потоков был достигнут потолок канала. Время проведения каждого теста — две минуты.
PPS: работа AIO на Linux не проверялась, результаты могут отличаться в любую сторону.