megahertz0 Posted May 19, 2017 Posted May 19, 2017 Потихоньку заводим у себя на сети HLS. Как известно, юникаст поедает довольно много трафика. Поэтому есть желание сделать несколько стримеров по сети чтобы отправлять туда ближайших пользователей. А на стримеры медиапотоки с центрального узла загонять мультикастом. И вот тут есть затык. Мы используем Stalker middleware и одноразовые ссылки. В теории можно смотреть на адрес клиента и отправлять его на ближайший стример. В Сталкере есть балансировка по GeoIP и количеству клиентов на стример. Но балансировки просто на основе адресе клиента нет. Можно, конечно, переделать код Сталкера, но очень не хочется этого делать т.к. во все следующие версии придется этот код портировать. В общем, вариант на крайний случай. И тут родилась идея с http-редиректом. Ставим nginx и вот такой конструкцией: geo $redir_user { default 0; 10.0.100.0/24 1; } server { listen 80; server_name localhost; if ($redir_user) { rewrite ^ $scheme://10.20.1.67:8888$request_uri break; } } при помощи модуля geo смотрим на адрес клиента и затем через rewrite перенаправляем клиента на нужный стример. Собрал демку, попробовал - в VLC и на приставках вполне работает. Есть еще вариант с HAProxy. Он тоже умеет HTTP Redirect и кроме балансировки может определять живой стример или нет и таким образом обеспечивать отказоустойчивость. Пока не тестил, но думаю, что тоже будет работать. Так что вопрос к публике - а кто решал подобного рода задачи? Какие подводные камни? И в верном ли направлении я двигаюсь? Вставить ник Quote
Blaar Posted May 20, 2017 Posted May 20, 2017 Если вы используете HLS - может проще сделать кеширующий прокси? плейлисты не кешируете, ts кешируете. Как отправлять абонентов на тот или иной кеш зависи от сети и уже можно пофантазировать. Вставить ник Quote
megahertz0 Posted May 20, 2017 Author Posted May 20, 2017 О прокси я как-то не думал если честно. Можно тот же nginx приспособить. Думаю должно взлететь. Есть еще идей с dns view. Вставить ник Quote
maxlapshin Posted May 20, 2017 Posted May 20, 2017 в flussonic один из вариантов — это именно такая балансировка с редиректом. Работает. Вставить ник Quote
Blaar Posted May 20, 2017 Posted May 20, 2017 nginx легко выдаст 30 Гбит на сервак. Главное проц получше Вставить ник Quote
Ivan_83 Posted May 21, 2017 Posted May 21, 2017 Смотря что и как отдавать. Главное сетевуха, дальше если раздавать из tmpfs используя sendfile() то будет шустро и маложруче. Вставить ник Quote
megahertz0 Posted May 22, 2017 Author Posted May 22, 2017 в flussonic один из вариантов — это именно такая балансировка с редиректом. Работает. Максим, а вы не могли бы подробнее описать механизм кластеризации во Флуссонике? У вас на сайте это описано как-то неочевидно. Вставить ник Quote
megahertz0 Posted May 22, 2017 Author Posted May 22, 2017 nginx легко выдаст 30 Гбит на сервак. Главное проц получше Тут есть еще один момент. Я бы хотел резервировать сами стримеры т.к. это обеспечивает отказоустойчивость. В случае же кеширующего прокси отказ стримера убивает все вещание... Вставить ник Quote
Blaar Posted May 22, 2017 Posted May 22, 2017 Резервировать стримеры безусловно надо. Однако что будет когда у вас еще трафика прибавится? А когда еще? Будете добавлять каждый раз новый стример. С кешерами вам достаточно иметь 1+1 на стримерах и мощности увеличивать только на уровне кешей. Резервирование origin на них же. Но опять же, я не утверждаю, что так надо делать. Все зависит от потребностей, возможностей и тд Вставить ник Quote
Sonne Posted May 25, 2017 Posted May 25, 2017 Ставите 2-3 стримера, которые только выдают HLS потоки. Ставите N прокси nginx, которые со стримеров берут потоки. И вот эти N-прокси и записываете в Сталкер как сервера для абонентов. В настройке nginx есть некоторые ньюансы, когда доберетесь до этого - пишите тут вопросы. Лично я в nginx настроил кеширование в ramdisk. Если захочется писать кеш на диск, то обязательно ставить отдельный SSD, но для меня это бессмысленно. Кеш никакой ценности не имеет и в любой момент может быть прогрет с нуля. И, да, никакого мультикаста вам тут в принципе не нужно. Nginx будет забирать поток с апстрима только если есть клиенты, которые его тянут. HLS специально создан для такой конфигурации сети. Вставить ник Quote
megahertz0 Posted May 29, 2017 Author Posted May 29, 2017 Sonne, спасибо за комментарии. Есть сразу ряд вопросов. 1. Я так понимаю, что на nginx можно реализовать вполне рабочий on demand? 2. Какой именно ramdisk вы используете? ramdisk, ramfs, tmpfs? 3. Через прокси получилось завести одноразовые ссылки для авторизации просмотра? Вставить ник Quote
Blaar Posted May 29, 2017 Posted May 29, 2017 Рабочий основной конфиг. tmpfs 7.0G 3.0G 4.1G 42% /var/cache/nginx/ram cat /etc/nginx/nginx.conf user nginx; worker_processes auto; worker_rlimit_nofile 65535; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; proxy_cache_path /var/cache/nginx/ram keys_zone=ram:10m inactive=1m max_size=6656m; include /etc/nginx/conf.d/*.conf; Вставить ник Quote
megahertz0 Posted May 30, 2017 Author Posted May 30, 2017 Итак, завел nginx в режиме прокси. Настройки сервера (кэша) от Blaar. Настройки виртуального хоста: server { listen 80; server_name localhost; location / { proxy_pass http://10.20.1.67:8888; proxy_cache ram; } } Запускаем два экземпляра vlc и открываем там один и тот же hls url. В логе nginx вижу, что клиенты запрашивают одинаковые чанки (имя и размер). 10.0.100.100 - - [30/May/2017:12:29:44 +0300] "GET /pervii_kanal/36143069.m3u8 HTTP/1.1" 200 152 "-" "VLC/2.2.4 LibVLC/2.2.4" 10.0.100.100 - - [30/May/2017:12:29:44 +0300] "GET /pervii_kanal/138.ts HTTP/1.1" 200 3778612 "-" "VLC/2.2.4 LibVLC/2.2.4" 10.0.100.100 - - [30/May/2017:12:29:44 +0300] "GET /pervii_kanal/139.ts HTTP/1.1" 200 3780116 "-" "VLC/2.2.4 LibVLC/2.2.4" 10.0.100.100 - - [30/May/2017:12:29:45 +0300] "GET /pervii_kanal/140.ts HTTP/1.1" 200 3786132 "-" "VLC/2.2.4 LibVLC/2.2.4" 10.0.100.100 - - [30/May/2017:12:29:47 +0300] "GET /pervii_kanal/62454622.m3u8 HTTP/1.1" 200 152 "-" "VLC/2.2.4 LibVLC/2.2.4" 10.0.100.100 - - [30/May/2017:12:29:48 +0300] "GET /pervii_kanal/139.ts HTTP/1.1" 200 3780116 "-" "VLC/2.2.4 LibVLC/2.2.4" 10.0.100.100 - - [30/May/2017:12:29:48 +0300] "GET /pervii_kanal/140.ts HTTP/1.1" 200 3786132 "-" "VLC/2.2.4 LibVLC/2.2.4" 10.0.100.100 - - [30/May/2017:12:29:48 +0300] "GET /pervii_kanal/141.ts HTTP/1.1" 200 3771656 "-" "VLC/2.2.4 LibVLC/2.2.4" Однако судя по логам Астры, с которой nginx забирает чанки, nginx ничего не кеширует и просто дважды запрашивает одно и то же. На Астре поправил механизм именования чанков, теперь они именуются по sequence, а не хэшем. Не помогло. Что я делаю не так? Вставить ник Quote
megahertz0 Posted May 30, 2017 Author Posted May 30, 2017 Сам себе и отвечаю. Нужно было включить игнорирование no-cache в запросах клиента. Это приводит к тому, что m3u8 тоже кешируется. Поэтому надо *.m3u8 пропустить мимо кэша. В итоге nginx.conf: user www-data; worker_processes auto; worker_rlimit_nofile 65535; pid /run/nginx.pid; events { worker_connections 1024; # multi_accept on; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; log_format cache '$remote_addr - $upstream_cache_status [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; access_log /var/log/nginx/access.log; access_log /var/log/nginx/access.cache.log cache; error_log /var/log/nginx/error.log; proxy_cache_path /var/cache/nginx/ram levels=1:2 keys_zone=ram:10m inactive=1m max_size=1024m; proxy_cache_min_uses 1; proxy_ignore_headers X-Accel-Expires; proxy_ignore_headers Expires; proxy_ignore_headers Cache-Control; gzip off; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } В настройках хоста: server { listen 80; server_name localhost; location / { proxy_pass http://10.20.1.67:8888; proxy_cache ram; proxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 2m; } location ~* \.(m3u8)$ { proxy_cache off; expires -1; proxy_pass http://10.20.1.67:8888; } } На коленке все вроде работает, но скорее всего придется тюнить конфиг. Пока неизвестно как разные hls-клиенты себя ведут. Вставить ник Quote
Blaar Posted May 30, 2017 Posted May 30, 2017 да, все верно. Я в одном из сообщений выше писал, что плейлисты кешировать не нужно. Результат кеширования будет зависит от того, по какому ключу вы и кешируете. У нас это $host$uri; на live контент hit ratio под 90% Конфиг тюнится в зависимости уже от нужд. Еще про тюнинг OS не забывайте. Например можно (даже нужно) поставить proxy_cache_lock on; proxy_cache_lock_timeout 60; proxy_temp_path - должно находиться в одной fs где и кеш для быстроты. Ну и worker уже добавлять, когда станет мало. на 4х ядрах и 1024 воркерах - рабочая нагурзка около 8 Гб/с Вставить ник Quote
graysilver Posted December 6, 2018 Posted December 6, 2018 Подниму тему. Коллеги, подскажите пожалуйста с настройкой прокси. У меня урлы каналов следующего вида http://server:port/channel/video.m3u8?id=password Как правильно изменить настройки хоста в nginx, чтобы не кешировал плейлист? location ~* \.(m3u8)$ { proxy_cache off; expires -1; proxy_pass http://server:port/channel/video.m3u8?id=password; } Вставить ник 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.