OKyHb Posted May 23, 2016 Posted May 23, 2016 Приветствую. Интересует опыт и мнение коллег по настройке линуксового сервера с nginx. Отказываемся от мультикаста, переводим абонентов на OTT. Для этого используется nginx, который раздаёт hls-видео чанки по 10 секунд/2MB. Железо сервера: один процессор Xeon E3-1270 (с hyper-threading - 8 ядер) сетевая - intel X710 (4x10G) По сетевой: на каждой сетевой по 8 очередей - прибиты set_irq_affinity на отдельные cpu rx/tx ring (-G) - по 4096 rx-usecs/tx-usecs (-C) - 1000, adaptive off ntuple, flow-director - отключены Запущено 8 воркеров nginx, крутили sysctl... Но всё равно при 1Mpps входящего + 2Mpps исходящего получается загрузка CPU в ~100% (~25Gbps трафика к абонентам). Собственно, вопрос - нормально ли это? Насколько больше можно выжать из такого железа? Вставить ник Quote
s.lobanov Posted May 23, 2016 Posted May 23, 2016 А perf top что говорит? На что ресурсы идут? Вставить ник Quote
OKyHb Posted May 23, 2016 Author Posted May 23, 2016 hls - так вроде удобнее абонентам, меньше проблем с android девайсами. perf top - затупил, не собрал :( Прийдётся уже вечерней нагрузки ждать. Вставить ник Quote
s.lobanov Posted May 23, 2016 Posted May 23, 2016 perf top - затупил, не собрал :( Прийдётся уже вечерней нагрузки ждать. Да можно и сейчас, суть от этого сильно не изменится, скорее всего Вставить ник Quote
Ivan_83 Posted May 23, 2016 Posted May 23, 2016 Гипертрединг в топку. Включить sendfile в nginx и класть чанки в tmpfs. Убедится что на сетевухе TSO, GSO и прочие оффлоадинги ВКЛЮЧЕНЫ (это не роутер/нат чтобы их выключать). Касательно удобства - обычный хттп стриминг софтиной что у меня в подписи вполне жрётся андройдами и любыми девайсами на которых написано UPnP/DLNA - те почти всем что есть. За яблоки не скажу, не интересовался, думаю там тоже как то вышли из положения. Вставить ник Quote
zhenya` Posted May 23, 2016 Posted May 23, 2016 Без hls батарейка быстро будет умирать. Вставить ник Quote
OKyHb Posted May 30, 2016 Author Posted May 30, 2016 По Hyper-threading - попробуем. sendfile, tmpfs - есть. TSO, GSO - используем. Единственное, что выключено - это RPS/RFS и ntuple filters. Результаты "perf record -a -g sleep 10" и "perf report" - под спойлером. Samples: 281K of event 'cycles', Event count (approx.): 199978971761 Children Self Command Shared Object Symbol + 30.63% 0.02% swapper [kernel.kallsyms] [k] cpu_startup_entry + 29.96% 0.00% swapper [kernel.kallsyms] [k] arch_cpu_idle + 29.94% 0.02% swapper [kernel.kallsyms] [k] cpuidle_idle_call + 29.19% 0.00% swapper [kernel.kallsyms] [k] ret_from_intr + 29.18% 0.01% swapper [kernel.kallsyms] [k] do_IRQ + 29.10% 0.02% swapper [kernel.kallsyms] [k] irq_exit + 29.03% 0.01% swapper [kernel.kallsyms] [k] do_softirq + 29.02% 0.00% swapper [kernel.kallsyms] [k] call_softirq + 29.00% 0.02% swapper [kernel.kallsyms] [k] __do_softirq + 27.72% 0.02% swapper [kernel.kallsyms] [k] net_rx_action + 27.45% 0.19% swapper [kernel.kallsyms] [k] i40e_napi_poll + 27.08% 0.00% swapper [kernel.kallsyms] [k] start_secondary + 25.63% 0.40% swapper [kernel.kallsyms] [k] i40e_clean_rx_irq + 24.80% 0.02% swapper [kernel.kallsyms] [k] napi_gro_receive + 24.53% 0.05% swapper [kernel.kallsyms] [k] netif_receive_skb + 24.24% 0.01% swapper [kernel.kallsyms] [k] __netif_receive_skb + 24.22% 0.24% swapper [kernel.kallsyms] [k] __netif_receive_skb_core + 23.83% 0.23% swapper [kernel.kallsyms] [k] ip_rcv + 23.51% 0.00% nginx [kernel.kallsyms] [k] do_softirq + 23.51% 0.00% nginx [kernel.kallsyms] [k] call_softirq + 23.50% 0.02% nginx [kernel.kallsyms] [k] __do_softirq + 22.34% 0.00% nginx [kernel.kallsyms] [k] irq_exit + 22.28% 0.00% nginx [kernel.kallsyms] [k] ret_from_intr + 22.28% 0.01% nginx [kernel.kallsyms] [k] do_IRQ + 21.95% 0.01% nginx [kernel.kallsyms] [k] net_rx_action + 21.75% 0.14% nginx [kernel.kallsyms] [k] i40e_napi_poll + 20.51% 0.09% swapper [kernel.kallsyms] [k] ip_rcv_finish + 20.29% 0.32% nginx [kernel.kallsyms] [k] i40e_clean_rx_irq + 19.90% 0.00% Server thread libc-2.17.so [.] __libc_start_main + 19.89% 0.01% Server thread node [.] node::Start + 19.79% 0.01% Server thread node [.] uv_run + 19.61% 0.02% nginx [kernel.kallsyms] [k] napi_gro_receive + 19.36% 0.05% nginx [kernel.kallsyms] [k] netif_receive_skb + 19.31% 0.03% swapper [kernel.kallsyms] [k] ip_local_deliver + 19.18% 0.01% nginx [kernel.kallsyms] [k] __netif_receive_skb + 19.16% 0.03% Server thread node [.] uv__io_poll + 19.15% 0.19% nginx [kernel.kallsyms] [k] __netif_receive_skb_core + 18.88% 0.19% nginx [kernel.kallsyms] [k] ip_rcv + 18.74% 0.01% nginx [kernel.kallsyms] [k] system_call_fastpath + 18.61% 0.06% swapper [kernel.kallsyms] [k] ip_local_deliver_finish + 18.12% 0.21% swapper [kernel.kallsyms] [k] tcp_v4_rcv + 17.56% 0.04% swapper [kernel.kallsyms] [k] tcp_v4_do_rcv + 16.61% 0.23% swapper [kernel.kallsyms] [k] tcp_rcv_established + 16.28% 0.00% Server thread node [.] 0x00000000001f3836 + 16.27% 0.00% nginx [unknown] [.] 0000000000000000 + 16.23% 0.07% nginx [kernel.kallsyms] [k] ip_rcv_finish + 16.17% 0.01% Server thread node [.] v8::Function::Call + 16.12% 0.01% Server thread node [.] v8::Function::Call + 16.03% 0.01% Server thread node [.] v8::internal::Execution::Call + 15.24% 0.03% nginx [kernel.kallsyms] [k] ip_local_deliver + 14.72% 0.04% nginx [kernel.kallsyms] [k] ip_local_deliver_finish + 14.29% 0.16% nginx [kernel.kallsyms] [k] tcp_v4_rcv + 13.84% 0.03% nginx [kernel.kallsyms] [k] tcp_v4_do_rcv + 13.00% 0.00% Server thread node [.] 0x00000000006be1a3 + 12.97% 0.19% nginx [kernel.kallsyms] [k] tcp_rcv_established + 12.73% 0.00% Server thread node [.] 0x00000000006bd9f7 + 12.72% 0.00% Server thread node [.] node::StreamWrap::OnReadCommon + 12.44% 0.00% Server thread [kernel.kallsyms] [k] do_softirq + 12.43% 0.00% Server thread [kernel.kallsyms] [k] call_softirq + 12.43% 0.01% Server thread [kernel.kallsyms] [k] __do_softirq + 12.35% 0.00% Server thread [kernel.kallsyms] [k] irq_exit + 12.29% 0.00% Server thread [kernel.kallsyms] [k] ret_from_intr + 12.29% 0.01% Server thread [kernel.kallsyms] [k] do_IRQ + 12.18% 0.01% Server thread node [.] node::Parser::OnReadImpl + 11.53% 0.01% Server thread [kernel.kallsyms] [k] net_rx_action + 11.47% 0.08% Server thread [kernel.kallsyms] [k] i40e_napi_poll + 10.67% 0.16% Server thread [kernel.kallsyms] [k] i40e_clean_rx_irq + 10.30% 0.01% Server thread [kernel.kallsyms] [k] napi_gro_receive + 10.15% 0.02% Server thread [kernel.kallsyms] [k] netif_receive_skb + 10.04% 0.00% Server thread [kernel.kallsyms] [k] __netif_receive_skb + 10.03% 0.11% Server thread [kernel.kallsyms] [k] __netif_receive_skb_core "Server thread" - это авторизация/ограничение доступа на nodejs (вызывается через proxy_pass в nginx). Привёл только первый экран. Можно по нему делать какие-то выводы? Вставить ник Quote
Ivan_83 Posted May 30, 2016 Posted May 30, 2016 swapper - надеюсь что своп отключён и это не он. В остальном лучше ядреного кота спрашивать и нитро, они линуксойды. Вставить ник Quote
s.lobanov Posted May 30, 2016 Posted May 30, 2016 OKyHb Судя по тому, что у вас всё уходит в прерывания, вам пора начать пользовать nginx-dpdk https://github.com/opendp/dpdk-nginx , i40e поддерживается. Когда запустите и получите профит по производительности, не забудьте сказать спасибо Вставить ник Quote
OKyHb Posted May 30, 2016 Author Posted May 30, 2016 Да, памяти на сервере - 64GB, почти вся свободна (при "vm.swappiness=1" использование swap стабильно нулевое). dpdk-nginx - фигасе, не знал, что такое есть. Будем пробовать, реально интересно. Спасибо :) Вставить ник Quote
s.lobanov Posted May 30, 2016 Posted May 30, 2016 swapper не имеет отношения к свопу ram<->disk, не переживайте об этом. у вас второй сервер хоть есть, чтоб nginx-dpdk попробовать? если что не будет получаться - пишите Вставить ник Quote
st_re Posted May 30, 2016 Posted May 30, 2016 А не странное ли соотношение 1:2 по пакетам ? мне кажется на чанках по 2 мб должно получаться меньше входящих пакетов ? там буферов и размеры окон (ну и вообще кипалав в нгинксе) в норме ? Вставить ник Quote
OKyHb Posted May 31, 2016 Author Posted May 31, 2016 Да, сервер для экспериментов есть, это не проблема. Из-за того, что закончились идеи, уже даже думали взять на тест новый сервер (двухпроцессорный с E5-2620 v4). Но не хочется заморачиваться с NUMA. По соотношению пакетов - чёрт его знает, может что-то и не так. Но тут есть дополнительные факторы: 1. для части клиентов трафик отдаётся по https 2. кроме видео чанка каждые 10 секунд запрашивается мелкий плейлист (*.m3u8 файл). Смотрел wireshark'ом со своего компьютера, во время проигрывания видео получение одного m3u8 файла по http - это 6 пакетов от клиента + 6 пакетов от сервера. На всякий случай сделал ещё один график: И вот используемые настройки: - sysctl net.core.netdev_max_backlog = 65535 net.core.netdev_budget = 600 net.core.optmem_max = 16777216 net.core.rmem_default = 16777216 net.core.rmem_max = 16777216 net.core.rps_sock_flow_entries = 32768 net.core.somaxconn = 65535 net.core.wmem_default = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 12 net.ipv4.tcp_keepalive_probes = 5 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.tcp_mem = 8388608 8388608 8388608 net.ipv4.tcp_rmem = 8388608 8388608 8388608 net.ipv4.tcp_slow_start_after_idle = 0 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_wmem = 8388608 8388608 8388608 net.netfilter.nf_conntrack_expect_max = 4096 net.netfilter.nf_conntrack_max = 262144 net.netfilter.nf_conntrack_tcp_timeout_established = 900 net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10 net.netfilter.nf_conntrack_tcp_loose = 0 net.ipv4.tcp_congestion_control = htcp net.ipv4.tcp_fastopen = 3 vm.swappiness = 1 - nginx user nginx; worker_processes 8; error_log /dev/null emerg; pid /var/run/nginx.pid; events { use epoll; multi_accept on; worker_connections 32768; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log off; keepalive_timeout 65; sendfile on; tcp_nopush on; tcp_nodelay on; server_tokens off; log_format stream "$status:$bytes_sent $uri"; ssl_certificate_key ***.key; ssl_certificate ***.crt; ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; proxy_cache_key $host$uri; proxy_store_access user:rw group:rw all:rw; proxy_cache_path /mnt/live levels=1:2 keys_zone=live:16m inactive=1m; upstream backend_live { server unix:/run/api_live_01.sock; server unix:/run/api_live_02.sock; server unix:/run/api_live_03.sock; server unix:/run/api_live_04.sock; server unix:/run/api_live_05.sock; server unix:/run/api_live_06.sock; server unix:/run/api_live_07.sock; server unix:/run/api_live_08.sock; } server { listen 80 default fastopen=256; listen 443 ssl default fastopen=256; charset utf8; server_name ***; error_page 403 404 500 502 /status.txt; location ~ "^/tv/(\d{4})\.m3u8" { proxy_http_version 1.1; proxy_pass_request_body off; proxy_pass_request_headers off; expires -1; add_header Content-Type "application/x-mpegURL"; proxy_pass http://backend_live; } location ~ "^/tv/(.*)\.ts$" { sendfile on; proxy_http_version 1.1; proxy_cache live; proxy_cache_lock on; proxy_cache_valid any 60s; proxy_cache_lock_timeout 60s; proxy_pass http://10.100.60.2:8080/$1.ts; access_log syslog:server=127.0.0.1:8123 stream; } } } Буду признателен за конструктивную критику :) Вставить ник Quote
s.lobanov Posted May 31, 2016 Posted May 31, 2016 Из-за того, что закончились идеи, уже даже думали взять на тест новый сервер (двухпроцессорный с E5-2620 v4). Но не хочется заморачиваться с NUMA. На это есть такой паттерн: запускаете 2 инстанса, каждый из которых привязан к своим ресурсам - cpu, ram, net, ну т.е. как бы делите сервер на 2 А вообще, что вам мешает тупо поставить 2ой сервер и разбалансить нагрузку между ними? Дорого или интересно выжать максимум из то, что есть? Вставить ник Quote
OKyHb Posted May 31, 2016 Author Posted May 31, 2016 Второй сервер - можно. Но мне все утверждают, что nginx легко выдаёт 20Gbps статики на десктопном Core i7. А тут серверный Xeon - и CPU в полке при 25Gbps. То есть, что-то неправильно настроил. Вставить ник Quote
s.lobanov Posted May 31, 2016 Posted May 31, 2016 OKyHb ну смотрите, это же зависит от RX/TX, чем больше RX, тем больше прерываний, а у вас их много и они вам нужны. если тупо передавать огромный файл и лишь изредка слать tcp-ack, то будет быстрее. а вот чтобы побороть прерывания - используйте dpdk и тогда уже будете заниматься тюнингом самого nginx вообщем слова типа "20Гбпс на i7" это ни о чём, оно не описывает реальных условий Вставить ник Quote
OKyHb Posted May 31, 2016 Author Posted May 31, 2016 Упс, про 12 пакетов на m3u8 - это я погорячился. Такая фигня только при присмотре через VLC. Если смотреть через браузер, то keepalive работает, все запросы в пределах одного tcp connection. Но за консультации реально спасибо, теперь больше понимания :) Вставить ник Quote
vitalvas Posted June 3, 2016 Posted June 3, 2016 Попробуйте сделать так на nginx keepalive_timeout 300; keepalive_requests 10000; Как по мне - сервис авторизации много ресурсов кушает. Попробуйте переписать на другой язык (например на go) или сильно оптимизировать Вставить ник Quote
st_re Posted June 3, 2016 Posted June 3, 2016 300 то зачем ? при нарубке по 10 секунд. Все, что выше 30, на положение вещей влиять не будет. клиент будет приходить за следующей дозой чаще. Кстати. а нарубить по длинее не пробовали ? (хотя тут уже может упираться во время получения от нарезчика и складирование в кеш. надо найти, наверное оптимальный размер чтобы кешилось быстро, а длина не слишком короткая, чтобы запрашивало пореже) зы /mnt/live я надеюсь в памяти ? 8-* еще proxy_temp укажите на том же разделе что и /mnt/live, чтобы, если ему приспичит создавать темф файл, оно его не копировало, а мувнуло в кеш и поиграть с proxy_buffers/proxy_buffer_size чтобы на стандартном файле ему темп бы не хотелось бы. (и рахзмер кеша, 1:2 сколько там файлов лежит? 1:1 это 256 каталогов. Вам точно надо 4к каталогов? тогда еще посмотрите чтобы open_file_cache/open_file_cache_valid были адекватны положению дел.) и я бы описание 10.100.60.2:8080 снес бы в upstream и указал заголовки в локешне proxy_http_version 1.1; proxy_set_header Connection ''; proxy_set_header Accept-Encoding ''; (если конечно 10.100.60.2 умеет 1.1) Вставить ник Quote
vitalvas Posted June 3, 2016 Posted June 3, 2016 300 - потому-что есть куча нюансов по работе из сетью. Это число было экспериментально подобрано на cdn сети за несколько лет. Вставить ник Quote
OKyHb Posted June 3, 2016 Author Posted June 3, 2016 Как по мне - сервис авторизации много ресурсов кушает. Попробуйте переписать на другой язык (например на go) или сильно оптимизировать Переписать на go - заманчиво, но некому и некогда. Проще сервер купить :) Блин, а у keepalive_requests дефолтное значение 100 - реально надо было поднимать. Провтык. 10 секунд на чанки - нам почему-то так показалось оптимальным. Ну и чтобы каналы у клиентов включались быстрее. Да и когда на популярной передаче начинается реклама - чтобы поменьше трафика вытягивали при переключении каналов. /mnt/live - да, tmpfs. proxy_temp - сегодня как раз обратил внимание, когда систему перенёс на флешку. По остальным параметрам - буду проверять, спасибо :) Вставить ник Quote
Ivan_83 Posted June 3, 2016 Posted June 3, 2016 HLS в клиентах это вообще сплошной багодром. Более-менее адекватная реализация была у самсунга, у длинка и элтекса в каждой модели свои глюки, не говоря о том, что они вообще даже минимум по спекам не сделали, а натяпляпили минимум чтобы оно хоть как то играло. Вставить ник Quote
vitalvas Posted June 5, 2016 Posted June 5, 2016 (edited) именно на чанках по 10 сек ? на файлах от 32кб до 4гб можно еще попробовать все proxy_pass вынести в upstream и выставить там keepalive (см доку). не знаю, будет ли unix-socket ускорять(не проверял), но с http запросами уберет часть tcp handshake можно еще попробовать закешировать m3u8 файлы на несколько секунд а лучше nginx собрать с модулем "nginx-module-vts" и посмотреть на сколько корректно отрабатывает по конфигу Edited June 5, 2016 by vitalvas Вставить ник Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.