[Nginx, Системное администрирование] Оптимизация: Настройка веб-сервера Nginx для улучшения показателей RPS в HTTP API (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Перед горизонтальным и вертикальным масштабированием инфраструктуры первым делом необходимо убедиться, что ресурсы используются правильно, а конфигурация приложения не создает узких мест для его производительности. Главная цель команды инженеров — обеспечить постоянную, бесперебойную работу любой спроектированной и развернутой системы с помощью минимальных ресурсов.
Мы столкнулись с указанной выше проблемой, когда наша развернутая система ежедневно использовалась миллионом пользователей, которые подключались всплесками время от времени. Это значит, что развертывание нескольких серверов или их масштабирование не будет в данной ситуации оптимальным решением.
Эта статья посвящена настройке Nginx для повышения производительности, то есть для увеличения показателей RPS (Requests Per Second) в HTTP API. Я постарался рассказать об оптимизации, которую мы применили в развернутой системе, чтобы обрабатывать десятки тысяч запросов в секунду без траты огромного количества ресурсов.
План действий: необходимо запустить HTTP API (написанный на Python с использованием flask), проксированный с помощью Nginx; требуется высокая пропускная способность. Содержимое API будет меняться с интервалом в один день.
оптимизация
имя существительное
процесс достижения наилучшего результата; наиболее эффективное использование ситуации или ресурса.
Мы использовали супервизор для запуска WSGI Server со следующими конфигурациями:
- Gunicorn с рабочими Meinheld
- Количество рабочих: количество ЦП * 2 + 1
- Привязать сокет к Unix-адресу вместо IP, это немного увеличит скорость.
Команда для супервизора выглядит так:
gunicorn api:app --workers=5 --worker-
class=meinheld.gmeinheld.MeinheldWorker --bind=unix:api.sock
Мы попробовали оптимизировать конфигурацию Nginx и проверили, что лучше всего сработает для нас.
Для оценки производительности API мы использовали wrk с помощью следующей команды:
wrk -t20 -c200 -d20s http://api.endpoint/resource
Конфигурация по умолчанию
Сначала мы выполнили нагрузочное тестирование API без каких-либо изменений и получили следующую статистику:
Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 192.48ms 274.78ms 1.97s 87.18%
Req/Sec 85.57 29.20 202.00 72.83%
33329 requests in 20.03s, 29.59MB read
Socket errors: connect 0, read 0, write 0, timeout 85
Requests/sec: 1663.71
Transfer/sec: 1.48MB
Обновление конфигурации по умолчанию
Давайте обновим стандартную конфигурацию Nginx, то есть nginx.conf в /etc/nginx/nginx.conf
worker_processes auto;
#or should be equal to the CPU core, you can use `grep processor /proc/cpuinfo | wc -l` to find; auto does it implicitly.
worker_connections 1024;
# default is 768; find optimum value for your server by `ulimit -n`
access_log off;
# to boost I/O on HDD we can disable access logs
# this prevent nginx from logging every action in a log file named `access.log`.
keepalive_timeout 15;
# default is 65;
# server will close connection after this time (in seconds)
gzip_vary on;
gzip_proxied any;
gzip_comp_level 2;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# reduces the data that needs to be sent over the network
nginx.conf (/etc/nginx/nginx.conf)
После изменений мы запускаем проверку конфигурации:
sudo nginx -t
Если проверка прошла успешно, можно перезапустить Nginx, чтобы отобразить изменения:
sudo service nginx restart
С такой конфигурацией мы провели нагрузочное тестирование API и получили следующий результат:
Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 145.80ms 237.97ms 1.95s 89.51%
Req/Sec 107.99 41.34 202.00 66.09%
42898 requests in 20.03s, 39.03MB read
Socket errors: connect 0, read 0, write 0, timeout 46
Non-2xx or 3xx responses: 2
Requests/sec: 2141.48
Transfer/sec: 1.95MB
Эти конфигурации сократили тайм-ауты и увеличили показатели RPS (количество запросов в секунду), но ненамного.
Добавление кеша Nginx
Поскольку в нашем случае содержимое конечной точки будет обновляться с интервалом в один день, это создает подходящие условия для кеширования ответов API.
Но добавление кеша приводит к его недействительности… это одна из двух трудностей здесь.
В информатике (компьютерных науках) есть только две сложности: инвалидация кеша и именование вещей (придумывание названий). — Фил Карлтон
Мы выбираем простое решение очистки каталога кеша с помощью cronjob после обновления содержимого в нижестоящей системе.
Далее всю тяжелую работу будет выполнять Nginx, но теперь мы должны быть уверены, что Nginx готов на 100%!
Чтобы добавить кеширование в Nginx, нужно прописать несколько директив в файл конфигурации Nginx.
Перед этим нам нужно создать каталог для хранения данных кеша:
sudo mkdir -p /data/nginx/cache
Изменения в конфигурации Nginx:
proxy_cache_path /data/nginx/cache keys_zone=my_zone:10m inactive=1d;
server {
...
location /api-endpoint/ {
proxy_cache my_zone;
proxy_cache_key "$host$request_uri$http_authorization";
proxy_cache_valid 404 302 1m;
proxy_cache_valid 200 1d;
add_header X-Cache-Status $upstream_cache_status;
}
...
}
Кеширование проксируемых запросов (конфигурация Nginx)
После этого изменения в конфигурации мы провели нагрузочное тестирование API и получили следующий результат:
Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.88ms 5.44ms 88.91ms 81.36%
Req/Sec 1.59k 500.04 2.95k 62.50%
634405 requests in 20.06s, 589.86MB read
Requests/sec: 31624.93
Transfer/sec: 29.40MB
Таким образом, мы получили почти 19-кратное увеличение производительности за счет добавления кеширования.
Примечание от эксперта Timeweb:
Требуется помнить, что кеширование запросов, приводящих к записи в базу данных, приведет к тому, что будет отдаваться закешированный ответ, но запись в базу данных производиться не будет.
Кеш Nginx в RAM (Random Access Memory)
Давайте сделаем еще один шаг вперед! В настоящее время данные нашего кеша хранятся на диске. А если мы сохраним эти данные в RAM? В нашем случае данные ответа ограничены и не имеют большого размера.
Итак, сначала нужно создать каталог, куда будет монтироваться кеш оперативной памяти:
sudo mkdir -p /data/nginx/ramcache
Чтобы смонтировать созданный каталог в RAM с помощью tmpfs, используйте команду:
sudo mount -t tmpfs -o size=256M tmpfs /data/nginx/ramcache
Это монтирует /data/nginx/ramcache в RAM, выделяя 256 МБ.
Если вы считаете, что хотите отключить RAM-кеш, просто выполните команду:
sudo umount /data/nginx/ramcache
Чтобы автоматически пересоздать каталог кеша в RAM после перезагрузки, нам нужно обновить файл /etc/fstab. Добавьте в него следующую строку:
tmpfs /data/nginx/ramcache tmpfs defaults,size=256M 0 0
Примечание: Также мы должны прописать значение proxy_cache_path с указанием пути до ramcache (/data/nginx/ramcache).
После обновления конфигурации мы снова провели нагрузочное тестирование API и получили следующий результат:
Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.57ms 5.69ms 277.76ms 92.94%
Req/Sec 1.98k 403.94 4.55k 71.77%
789306 requests in 20.04s, 733.89MB read
Requests/sec: 39387.13
Transfer/sec: 36.62MB
Хранение кеша в оперативной памяти привело к значительному улучшению почти в 23 раза.
Журнал буферизованного доступа
Мы храним журнал доступа к проксированным приложениям, но можно сначала сохранить журнал в буфере и только потом записать на диск:
- если следующая строка лога не помещается в буфер
- если данные в буфере старше, чем указано в параметре flush.
Эта процедура уменьшит частоту записи, выполняемую с каждым запросом. Для этого нам просто нужно добавить параметры buffer и flush с соответствующим значением в директиве access_log:
location / {
...
access_log /var/log/nginx/fast_api.log combined buffer=256k flush=10s;
error_log /var/log/nginx/fast_api.err.log;
}
Буферный журнал перед записью на диск
Таким образом, согласно приведенной выше конфигурации, изначально журналы доступа будут записываться в буфер и сохраняться на диск только тогда, когда размер буфера достигнет 256 КБ или буферизованные данные станут старше 10 секунд.
Примечание: Здесь объединено имя log_format.
После повторного нагрузочного тестирования мы получили следующий результат:
Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.21ms 3.19ms 84.83ms 83.84%
Req/Sec 2.53k 379.87 6.02k 77.05%
1009771 requests in 20.03s, 849.31MB read
Requests/sec: 50413.44
Transfer/sec: 42.40MB
Такая конфигурация значительно увеличила количество запросов в секунду, примерно в 30 раз по сравнению с начальным этапом.
Вывод
В этой статье мы обсудили процесс оптимизации конфигурации Nginx для улучшения показателей RPS. Показатели RPS были увеличены с 1663 до ~ 50413 (увеличение примерно в 30 раз), это обеспечивает высокую пропускную способность. Благодаря настройке стандартных параметров можно улучшить производительность системы.
Закончим статью цитатой:
Сначала сделай так, чтобы работало. Потом сделай правильно. Затем оптимизируй. — Кент Бек
Источники
- docs.nginx.com/nginx/admin-guide
- www.nginx.com/blog/tuning-nginx
- github.com/wg/wrk/wiki/installing-wrk-on-linux
- kb.virtubox.net/knowledgebase/improve-nginx-cache-performance-with-tmpfs
===========
Источник:
habr.com
===========
===========
Автор оригинала: Rohit Gupta
===========Похожие новости:
- [DevOps, Kubernetes, Серверное администрирование, Системное администрирование] АйТиБалаган! #3: Зачем DevOps-инженеру программирование и что такое виртуализация
- [Информационная безопасность, Сетевые технологии, Системное администрирование] OSINT или как посмотреть на свою сеть глазами хакера
- [DevOps, Kubernetes, Серверное администрирование, Системное администрирование] «Обзор возможностей Kubespray»: Отличие оригинальной версии и нашего форка
- [DevOps, Системное администрирование] Двадцать интервью за две недели. Краткие выводы длинным текстом
- [Системное администрирование, Серверное администрирование, DevOps, Kubernetes] Бесплатный вебинар «Обзор возможностей Kubespray»
- [IT-инфраструктура, Open source, Конференции, Системное администрирование] Онлайн митап Zabbix и сессия вопросов/ответов с Алексеем Владышевым
- [JavaScript, Node.JS, ReactJS, Клиентская оптимизация] Перфоманс фронтенда как современное искусство: графики, код, кулстори
- [Open source, Системное администрирование, Виртуализация, Разработка под Linux] Разработка и тестирование Ansible-ролей с использованием Molecule и Podman
- [Системное администрирование] IPSec туннель между Strongswan за NAT и VMWare NSX Edge
- [Open source, Финансы в IT, IT-компании, Разработка игр] Wargaming выдвинула новое обвинение добавив технодемо 2017 года
Теги для поиска: #_nginx, #_sistemnoe_administrirovanie (Системное администрирование), #_nginx, #_optimizatsija (оптимизация), #_blog_kompanii_timeweb (
Блог компании Timeweb
), #_nginx, #_sistemnoe_administrirovanie (
Системное администрирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:55
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Перед горизонтальным и вертикальным масштабированием инфраструктуры первым делом необходимо убедиться, что ресурсы используются правильно, а конфигурация приложения не создает узких мест для его производительности. Главная цель команды инженеров — обеспечить постоянную, бесперебойную работу любой спроектированной и развернутой системы с помощью минимальных ресурсов. Мы столкнулись с указанной выше проблемой, когда наша развернутая система ежедневно использовалась миллионом пользователей, которые подключались всплесками время от времени. Это значит, что развертывание нескольких серверов или их масштабирование не будет в данной ситуации оптимальным решением. Эта статья посвящена настройке Nginx для повышения производительности, то есть для увеличения показателей RPS (Requests Per Second) в HTTP API. Я постарался рассказать об оптимизации, которую мы применили в развернутой системе, чтобы обрабатывать десятки тысяч запросов в секунду без траты огромного количества ресурсов. План действий: необходимо запустить HTTP API (написанный на Python с использованием flask), проксированный с помощью Nginx; требуется высокая пропускная способность. Содержимое API будет меняться с интервалом в один день. оптимизация
имя существительное процесс достижения наилучшего результата; наиболее эффективное использование ситуации или ресурса. Мы использовали супервизор для запуска WSGI Server со следующими конфигурациями:
Команда для супервизора выглядит так: gunicorn api:app --workers=5 --worker-
class=meinheld.gmeinheld.MeinheldWorker --bind=unix:api.sock Мы попробовали оптимизировать конфигурацию Nginx и проверили, что лучше всего сработает для нас. Для оценки производительности API мы использовали wrk с помощью следующей команды: wrk -t20 -c200 -d20s http://api.endpoint/resource
Конфигурация по умолчанию Сначала мы выполнили нагрузочное тестирование API без каких-либо изменений и получили следующую статистику: Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 192.48ms 274.78ms 1.97s 87.18% Req/Sec 85.57 29.20 202.00 72.83% 33329 requests in 20.03s, 29.59MB read Socket errors: connect 0, read 0, write 0, timeout 85 Requests/sec: 1663.71 Transfer/sec: 1.48MB Обновление конфигурации по умолчанию Давайте обновим стандартную конфигурацию Nginx, то есть nginx.conf в /etc/nginx/nginx.conf worker_processes auto;
#or should be equal to the CPU core, you can use `grep processor /proc/cpuinfo | wc -l` to find; auto does it implicitly. worker_connections 1024; # default is 768; find optimum value for your server by `ulimit -n` access_log off; # to boost I/O on HDD we can disable access logs # this prevent nginx from logging every action in a log file named `access.log`. keepalive_timeout 15; # default is 65; # server will close connection after this time (in seconds) gzip_vary on; gzip_proxied any; gzip_comp_level 2; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 256; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; # reduces the data that needs to be sent over the network После изменений мы запускаем проверку конфигурации: sudo nginx -t
Если проверка прошла успешно, можно перезапустить Nginx, чтобы отобразить изменения: sudo service nginx restart
С такой конфигурацией мы провели нагрузочное тестирование API и получили следующий результат: Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 145.80ms 237.97ms 1.95s 89.51% Req/Sec 107.99 41.34 202.00 66.09% 42898 requests in 20.03s, 39.03MB read Socket errors: connect 0, read 0, write 0, timeout 46 Non-2xx or 3xx responses: 2 Requests/sec: 2141.48 Transfer/sec: 1.95MB Эти конфигурации сократили тайм-ауты и увеличили показатели RPS (количество запросов в секунду), но ненамного. Добавление кеша Nginx Поскольку в нашем случае содержимое конечной точки будет обновляться с интервалом в один день, это создает подходящие условия для кеширования ответов API. Но добавление кеша приводит к его недействительности… это одна из двух трудностей здесь. В информатике (компьютерных науках) есть только две сложности: инвалидация кеша и именование вещей (придумывание названий). — Фил Карлтон
Мы выбираем простое решение очистки каталога кеша с помощью cronjob после обновления содержимого в нижестоящей системе. Далее всю тяжелую работу будет выполнять Nginx, но теперь мы должны быть уверены, что Nginx готов на 100%! Чтобы добавить кеширование в Nginx, нужно прописать несколько директив в файл конфигурации Nginx. Перед этим нам нужно создать каталог для хранения данных кеша: sudo mkdir -p /data/nginx/cache
Изменения в конфигурации Nginx: proxy_cache_path /data/nginx/cache keys_zone=my_zone:10m inactive=1d;
server { ... location /api-endpoint/ { proxy_cache my_zone; proxy_cache_key "$host$request_uri$http_authorization"; proxy_cache_valid 404 302 1m; proxy_cache_valid 200 1d; add_header X-Cache-Status $upstream_cache_status; } ... } После этого изменения в конфигурации мы провели нагрузочное тестирование API и получили следующий результат: Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 6.88ms 5.44ms 88.91ms 81.36% Req/Sec 1.59k 500.04 2.95k 62.50% 634405 requests in 20.06s, 589.86MB read Requests/sec: 31624.93 Transfer/sec: 29.40MB Таким образом, мы получили почти 19-кратное увеличение производительности за счет добавления кеширования. Примечание от эксперта Timeweb:
Требуется помнить, что кеширование запросов, приводящих к записи в базу данных, приведет к тому, что будет отдаваться закешированный ответ, но запись в базу данных производиться не будет. Кеш Nginx в RAM (Random Access Memory) Давайте сделаем еще один шаг вперед! В настоящее время данные нашего кеша хранятся на диске. А если мы сохраним эти данные в RAM? В нашем случае данные ответа ограничены и не имеют большого размера. Итак, сначала нужно создать каталог, куда будет монтироваться кеш оперативной памяти: sudo mkdir -p /data/nginx/ramcache
Чтобы смонтировать созданный каталог в RAM с помощью tmpfs, используйте команду: sudo mount -t tmpfs -o size=256M tmpfs /data/nginx/ramcache
Это монтирует /data/nginx/ramcache в RAM, выделяя 256 МБ. Если вы считаете, что хотите отключить RAM-кеш, просто выполните команду: sudo umount /data/nginx/ramcache
Чтобы автоматически пересоздать каталог кеша в RAM после перезагрузки, нам нужно обновить файл /etc/fstab. Добавьте в него следующую строку: tmpfs /data/nginx/ramcache tmpfs defaults,size=256M 0 0
Примечание: Также мы должны прописать значение proxy_cache_path с указанием пути до ramcache (/data/nginx/ramcache). После обновления конфигурации мы снова провели нагрузочное тестирование API и получили следующий результат: Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 5.57ms 5.69ms 277.76ms 92.94% Req/Sec 1.98k 403.94 4.55k 71.77% 789306 requests in 20.04s, 733.89MB read Requests/sec: 39387.13 Transfer/sec: 36.62MB Хранение кеша в оперативной памяти привело к значительному улучшению почти в 23 раза. Журнал буферизованного доступа Мы храним журнал доступа к проксированным приложениям, но можно сначала сохранить журнал в буфере и только потом записать на диск:
Эта процедура уменьшит частоту записи, выполняемую с каждым запросом. Для этого нам просто нужно добавить параметры buffer и flush с соответствующим значением в директиве access_log: location / {
... access_log /var/log/nginx/fast_api.log combined buffer=256k flush=10s; error_log /var/log/nginx/fast_api.err.log; } Таким образом, согласно приведенной выше конфигурации, изначально журналы доступа будут записываться в буфер и сохраняться на диск только тогда, когда размер буфера достигнет 256 КБ или буферизованные данные станут старше 10 секунд. Примечание: Здесь объединено имя log_format. После повторного нагрузочного тестирования мы получили следующий результат: Running 20s test @ http://api.endpoint/resource
20 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.21ms 3.19ms 84.83ms 83.84% Req/Sec 2.53k 379.87 6.02k 77.05% 1009771 requests in 20.03s, 849.31MB read Requests/sec: 50413.44 Transfer/sec: 42.40MB Такая конфигурация значительно увеличила количество запросов в секунду, примерно в 30 раз по сравнению с начальным этапом. Вывод В этой статье мы обсудили процесс оптимизации конфигурации Nginx для улучшения показателей RPS. Показатели RPS были увеличены с 1663 до ~ 50413 (увеличение примерно в 30 раз), это обеспечивает высокую пропускную способность. Благодаря настройке стандартных параметров можно улучшить производительность системы. Закончим статью цитатой: Сначала сделай так, чтобы работало. Потом сделай правильно. Затем оптимизируй. — Кент Бек
Источники
=========== Источник: habr.com =========== =========== Автор оригинала: Rohit Gupta ===========Похожие новости:
Блог компании Timeweb ), #_nginx, #_sistemnoe_administrirovanie ( Системное администрирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:55
Часовой пояс: UTC + 5