OKyHb 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 Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
s.lobanov Posted May 23, 2016 А perf top что говорит? На что ресурсы идут? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
shicoy Posted May 23, 2016 А нужен именно hls? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
OKyHb Posted May 23, 2016 hls - так вроде удобнее абонентам, меньше проблем с android девайсами. perf top - затупил, не собрал :( Прийдётся уже вечерней нагрузки ждать. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
s.lobanov Posted May 23, 2016 perf top - затупил, не собрал :( Прийдётся уже вечерней нагрузки ждать. Да можно и сейчас, суть от этого сильно не изменится, скорее всего Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Ivan_83 Posted May 23, 2016 Гипертрединг в топку. Включить sendfile в nginx и класть чанки в tmpfs. Убедится что на сетевухе TSO, GSO и прочие оффлоадинги ВКЛЮЧЕНЫ (это не роутер/нат чтобы их выключать). Касательно удобства - обычный хттп стриминг софтиной что у меня в подписи вполне жрётся андройдами и любыми девайсами на которых написано UPnP/DLNA - те почти всем что есть. За яблоки не скажу, не интересовался, думаю там тоже как то вышли из положения. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
zhenya` Posted May 23, 2016 Без hls батарейка быстро будет умирать. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
OKyHb 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 Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Ivan_83 Posted May 30, 2016 swapper - надеюсь что своп отключён и это не он. В остальном лучше ядреного кота спрашивать и нитро, они линуксойды. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
s.lobanov Posted May 30, 2016 OKyHb Судя по тому, что у вас всё уходит в прерывания, вам пора начать пользовать nginx-dpdk https://github.com/opendp/dpdk-nginx , i40e поддерживается. Когда запустите и получите профит по производительности, не забудьте сказать спасибо Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
OKyHb Posted May 30, 2016 Да, памяти на сервере - 64GB, почти вся свободна (при "vm.swappiness=1" использование swap стабильно нулевое). dpdk-nginx - фигасе, не знал, что такое есть. Будем пробовать, реально интересно. Спасибо :) Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
s.lobanov Posted May 30, 2016 swapper не имеет отношения к свопу ram<->disk, не переживайте об этом. у вас второй сервер хоть есть, чтоб nginx-dpdk попробовать? если что не будет получаться - пишите Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
st_re Posted May 30, 2016 А не странное ли соотношение 1:2 по пакетам ? мне кажется на чанках по 2 мб должно получаться меньше входящих пакетов ? там буферов и размеры окон (ну и вообще кипалав в нгинксе) в норме ? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
OKyHb 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 Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
s.lobanov Posted May 31, 2016 Из-за того, что закончились идеи, уже даже думали взять на тест новый сервер (двухпроцессорный с E5-2620 v4). Но не хочется заморачиваться с NUMA. На это есть такой паттерн: запускаете 2 инстанса, каждый из которых привязан к своим ресурсам - cpu, ram, net, ну т.е. как бы делите сервер на 2 А вообще, что вам мешает тупо поставить 2ой сервер и разбалансить нагрузку между ними? Дорого или интересно выжать максимум из то, что есть? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
OKyHb Posted May 31, 2016 Второй сервер - можно. Но мне все утверждают, что nginx легко выдаёт 20Gbps статики на десктопном Core i7. А тут серверный Xeon - и CPU в полке при 25Gbps. То есть, что-то неправильно настроил. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
s.lobanov Posted May 31, 2016 OKyHb ну смотрите, это же зависит от RX/TX, чем больше RX, тем больше прерываний, а у вас их много и они вам нужны. если тупо передавать огромный файл и лишь изредка слать tcp-ack, то будет быстрее. а вот чтобы побороть прерывания - используйте dpdk и тогда уже будете заниматься тюнингом самого nginx вообщем слова типа "20Гбпс на i7" это ни о чём, оно не описывает реальных условий Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
OKyHb Posted May 31, 2016 Упс, про 12 пакетов на m3u8 - это я погорячился. Такая фигня только при присмотре через VLC. Если смотреть через браузер, то keepalive работает, все запросы в пределах одного tcp connection. Но за консультации реально спасибо, теперь больше понимания :) Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
vitalvas Posted June 3, 2016 Попробуйте сделать так на nginx keepalive_timeout 300; keepalive_requests 10000; Как по мне - сервис авторизации много ресурсов кушает. Попробуйте переписать на другой язык (например на go) или сильно оптимизировать Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
st_re 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 Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
vitalvas Posted June 3, 2016 300 - потому-что есть куча нюансов по работе из сетью. Это число было экспериментально подобрано на cdn сети за несколько лет. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
st_re Posted June 3, 2016 именно на чанках по 10 сек ? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
OKyHb Posted June 3, 2016 Как по мне - сервис авторизации много ресурсов кушает. Попробуйте переписать на другой язык (например на go) или сильно оптимизировать Переписать на go - заманчиво, но некому и некогда. Проще сервер купить :) Блин, а у keepalive_requests дефолтное значение 100 - реально надо было поднимать. Провтык. 10 секунд на чанки - нам почему-то так показалось оптимальным. Ну и чтобы каналы у клиентов включались быстрее. Да и когда на популярной передаче начинается реклама - чтобы поменьше трафика вытягивали при переключении каналов. /mnt/live - да, tmpfs. proxy_temp - сегодня как раз обратил внимание, когда систему перенёс на флешку. По остальным параметрам - буду проверять, спасибо :) Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Ivan_83 Posted June 3, 2016 HLS в клиентах это вообще сплошной багодром. Более-менее адекватная реализация была у самсунга, у длинка и элтекса в каждой модели свои глюки, не говоря о том, что они вообще даже минимум по спекам не сделали, а натяпляпили минимум чтобы оно хоть как то играло. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
vitalvas 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 Ответить с цитированием Share this post Link to post Share on other sites More sharing options...