Отдача файлов c помощью Nginx

sendfile

526f26eae4b74f1b5b8d5eaa0ecb9d62.png

Nginx часто используется для только для отдачи файлов. Например, файловый хостинг. На что следует обратить внимание для оптимальной настройки Nginx под отдачу крупных файлов?

Чуть подробнее о характеристиках нашей задачи:

  • Нужно параллельно отдавать много файлов
  • Большинство файлов крупные (более 5 Мб)
  • Мы отдаем потоковое видео и нам необходимо обеспечить комфортный просмотр
  • Мы отдаем звуковые файлы и необходимо обеспечить комфортное прослушивание

Что следует настроить?

sendfile

Как обычно работает Web сервер, при передаче файла:

  1. открывается исходный файл (на диске)
  2. открывается файл назначения (сетевое соединение)
  3. читается блок данных, копируется в буфер и передается по назначению, пока не достигнут конец файла
  4. закрываются оба файла

Это означает, что происходит дополнительное копирование, которое вынужден делать Web сервер. В этом случае сервер делает системные вызовы read и write. Системный вызов sendfile служит как раз для того, чтобы избежать излишнего копирования и обеспечить прямую передачу файла. Включайте эту опцию (всегда): sendfile on;

tcp_nopush

Директива разрешает или запрещает использовать опции TCP_NOPUSH во FreeBSD или TCP_CORK в Linux. “tcp_nopush on” полезно для sendfile(), nginx в этом случае выводит данные полными пакетами. После того, как весь запрос обработан, TCP_CORK/TCP_NOPUSH выключается, что приводит в сбросу последнего неполного пакета. tcp_nopush on;

tcp_nodelay

Директива разрешает или запрещает использовать опцию TCP_NODELAY (при переходе соединения в состояние keep-alive). Перед переходом соединения в keepalive nginx выводит данные вызовами writev() достаточно большими порциями для заполнения пакета (“postpone_output 1460”), поэтому данные должны уходить без задержек и TCP_NODELAY не нужен. А вот с последним неполным пакетом может случится небольшая задержка, если соединение не закрывается. Для этого и нужно включить TCP_NODELAY: tcp_nodelay on;

directio

Эта опция позволяет включить прямое чтение без обращение в кеш операционной системы. Это полезно для больших файлов, поскольку операционный кеш для них малоэффективен. Опция позволяет задать минимальный размер для включения режима прямого чтения: directio 10m;

Файлы более 10Мб Nginx будет читать с диска минуя операционный кеш

expires

Поскольку мы имеем дело со статическими файлами, и есть вероятность того, что один и тот же пользователь сможет несколько раз запросить один и тот же файл, следует включить клиентское кеширование. Это достигается установкой опции “expires max”, которая отправит браузеру нужные заголовки: expires max;

limit_rate

Это достаточно важная опция. Она позволяет ограничить скорость отдачи файлов. В том случае, если Вы отдаете потоковое видео, либо музыку, Вам следует установить ограничения на скорость отдачи. Это позволит сэкономить канал и обслужить больше клиентов: limit_rate 196K;

Ограничиваем скорость отдачи до 196Кб/с

Эта опция работает только в рамках одного запроса, а не клиента. Если Вы хотите поставить ограничение на клиента, следует использовать переменную: set $limit_rate 196K;

В Nginx также есть возможность установить порог отдачи, после которой ограничение войдет в силу. Также имеет смысл для потокового медиа (в этом случае первая указанная часть будет отдаваться без ограничений): limit_rate_after 1m;

Ограничение скорости отдачи будет накладываться после 1Мб

Файлы, которые запрашиваются очень часто имеет смысл кешировать в памяти.

Самое важное

Небольшая настройка Nginx специально для отдачи файлов позволит лучше использовать ресурсы каждого сервера.

Источник: