[Python, Обработка изображений, Машинное обучение, Облачные сервисы, Kubernetes] Архитектура облачного волейбольного сервиса
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Не так давно я писал про волейбольный сервис, теперь пришло время описать его с технической точки зрения.
Возможно, общественное сознание найдет изъяны в архитектуре и подтолкнет к лучшим решениям.
Краткое описание функциональности:
- пользователь загружает видео с записью волейбольной игры
- один хитрый алгоритм распознает мяч на кадрах
- другой хитрый алгоритм выделяет розыгрыши
- розыгрыши компонуются в отдельные видеофайлы
- файлы с розыгрышами собираются в дайджест всей игры
- все видео заливается в облако
- пользователи смотрят/качают/шарят клипы с самыми классными розыгрышами
Например, такими:
Теперь, как это все работает.
Технологии
Все написано на python, веб-сервис — Django/Gunicorn.
Интенсивно используются OpenCV и FFMpeg.
База данных — Postgres.
Кэш и очередь — Redis.
Альфа
В самой первой версии было 3 компонента:
- Front — Веб сервис (Django), с которым взаимодействуют конечные пользователи
- Videoproc (Vproc) — Ядро алгоритма, python + opencv, которое содержит все алгоритмы треккинга мяча и логику нарезки на розыгрыши
- Clipper — Сервис генерации видео на основе выхлопа Vproc, используя ffmpeg
Разработка велась локально, я поставил на домашний десктоп Ubuntu, а на нее microk8s и получил маленький Кубернетес-кластер.
Здесь я столкнулся с тем, что кадры, которые видит opencv не очень совпадают с временем, которое видит ffmpeg из-за особенностей кодеков, поэтому высчитать время в оригинальном файле из номера кадра оказалаось невозможно.
Из-за этого пришлось сохранять кадры, что сильно замедлило процесс и потребовало дальнейших архитектурных изменений.
Параллельная обработка
Как уже упоминалось, время обработки в 3 раза превышает время игры. Профайлер показал, что, большая часть времени тратится при записи кадров на диск, сам же разбор кадров примерно в два раза быстрее.
Логично распараллелить эти две работы.
По начальной задумке пока vproc разбирает кадры через opencv, ffmpeg параллельно записывает все на диск, а clipper собирает из них видео.
Но с ffmpeg нашлись две проблемы:
- Кадры из ffmpeg не идентичны кадрам из opencv (это не всегда так, зависит от кодека видеофайла)
- Количество кадров в записи может быть слишком большим — например час видео при хорошем fps — это порядка 200K файлов, что многовато для одного каталога, даже если это ext4. Городить разбиение на поддиректории и потом склеивать при компоновке видео — не хотелось усложнять
В итоге вместо ffmpeg появился пятый элемент компонент — Framer. Он запускается из vproc, и листает кадры в том же видеофайле, ожидая пока vproc найдет розыгрыши. Как только они появились — framer выкладывает нужные кадры в отдельную директорию.
Из дополнительных плюсов — ни одного лишнего кадра не эспортируется.
Мелочь, но все таки.
По производительности (на 10-минутном тестовом видео):
Было:
Completed file id=73, for game=test, frames=36718, fps=50, duration=600 in 1677 sec
Стало:
Completed file id=83, for game=test, frames=36718, fps=50, duration=600 in 523 sec + framer time 303
Выигрыш в два раза, очень хорошо. Если писать в несколько потоков, то наверное можно выжать еще чуть. Если хранить кадры в памяти и генерить из них видео через API, то скорее всего можно ускориться значительно.
Digital Ocean
Дальше я стал выбирать хостинг. Понятно, что основные варианты — GKE, AWS, Azure, но многие авторы мелких проектов жалуются на непрозрачное ценообразование и, как следствие, немаленькие счета.
Основная засада здесь — цена за исходящий трафик, она составляет порядка $100/Tb, а поскольку речь идет о раздаче видео, вероятность серьезно попасть очень неиллюзорна.
Тогда я решил глянуть второй эшелон — Digital Ocean, Linode, Heroku. На самом деле Kubernetes-as-service уже не такая редкая вещь, но многие варианты не выглядят user-friendly.
Больше всего понравился Digital Ocean, потому что:
- Managed Kubernetes
- Managed Postgres
- S3 хранилище с бесплатным(!) CDN + 1 TB/месяц
- Закрытый docker registry
- Все операции можно делать через API
- Датацентры по всему миру
При наличии CDN веб-серверу уже не было надобности раздавать видео, однако кто-то должен был это видео опубликовать.
Так в архитектуре появился четвертый компонент — Pusher.
Однако серьезным недостатком оказалась невозможность смонтировать один и тот же диск на несколько машин одновременно.
Сам DO предлагает в таких случаях использовать NFS через выделенный контейнер, но пока решил не заморачиваться, ибо, как упоминалось выше, назревает специальное решение для видео кадров, и если уже городить отдельный контейнер, то для него.
Тем не менее, отсутствие общего диска серьезно повлияло на архитектуру.
Если с передачей загружаемого файла, можно было выкрутиться через S3, то гонять туда-сюда сотни тысяч кадров не выглядело блестящим вариантом.
В итоге, пришлось привязать все стадии обработки конкретной видео к одной ноде, что конечно уменьшило общую масштабируемость системы.
Логи и метрики
Запустив кластер в облаке, я стал искать решение для сбора логов и метрик. Самостоятельно возиться с хостингом этого добра не хотелось, поэтому целью был free-tier в каком-нибудь облаке.
Такое есть не у всех: Модная Grafana хочет $50 в месяц, выходящий из моды Elastic — $16, Splunk даже прямо не говорит.
Зато внезапно оказалось что New Relic, также известный своими негуманными ценами, теперь предоставляет первые 100G в месяц бесплатно.
Видео
Вполне ествественным решением виделось разделить кластер на два node-pool'а:
- front — на котором крутятся веб-сервера
- vproc — где обрабатывается видео
Фронтовой пул, понятно, всегда онлайн, а вот процессинговый не так прост.
Во-первых, обработка видео требует серьезных ресурсов (= денег), а во-вторых, обрабатывать приходится нечасто (особенно в стадии зарождения проекта).
Поэтому хочется включать процессинг только, чтобы обработать видео (время обработки — 3x от продолжительности действа).
Кубернетес формально поддерживает autoscale 0, но как именно это реализуется — я не нашел, зато нашлась такая дискуссия на Stack Overflow.
В итоге пришлось нагородить еще один под во фронтовом пуле, единственной задачей которого является посматривать в постгрес иногда и включать/выключать процессинговый пул в зависимости от того, что в базе оказалось.
У DigitalOcean есть неофициальный клиент для питона, но он уже давно не обновлялся, а Kubernetes API там не присутствует в принципе.
Я сделал на коленке клиент для себя, он покрывает процентов десять возможностей, но вдруг кому пригодится для старта.
В итоге диаграмм разрослась вот так:
DevOps
Несмотря на великое множество CI/CD инструментов, в разработке не нашлось ничего удобнее Jenkins.
А для управления DigitalOcean'ом идеально подошли Github Actions.
Ссылки
- Сервис, про который эта статья
- DigitalOcean Kubernetes
- DigitalOcean API для управления кластером
- New Relic free tier
===========
Источник:
habr.com
===========
Похожие новости:
- [Open source, Облачные сервисы, Финансы в IT, Звук] Обсуждение: почему индустрия подкастов все больше походит на стриминг сериалов и фильмов
- [Java, DevOps, Kubernetes] Пример развертывания Spring Boot-приложения в Kubernetes (перевод)
- [Python, Программирование] Метаклассы в Python (перевод)
- [IT-инфраструктура, Облачные сервисы, Научно-популярное, Kubernetes] Детям о Кубернете, или приключения Фиппи в космосе
- [Тестирование мобильных приложений, Машинное обучение, Аналитика мобильных приложений, Научно-популярное] Кто сказал «мяу»: бывший разработчик из Amazon создал переводчик с кошачьего
- [Обработка изображений, Машинное обучение] 5 подходов к разметке данных для проектов машинного обучения (перевод)
- [Python, Разработка под Android, Разработка под MacOS, Разработка под Linux, Разработка под Windows] Дополнительные компоненты для кроссплатформеннной библиотеки материального дизайна KivyMD
- [Машинное обучение] Как научить бабушку писать мемуары на самоизоляции с помощью VOSK-API. «Речь в текст» спешит на помощь
- [Работа с видео, Обработка изображений, Браузеры, Машинное обучение, Видеоконференцсвязь] Размытие фона в Google Meet с расчётом ML в браузере (перевод)
- [Разработка под e-commerce, Интернет-маркетинг, Облачные сервисы] Топ 10 лучших сервисов для мониторинга цен конкурентов
Теги для поиска: #_python, #_obrabotka_izobrazhenij (Обработка изображений), #_mashinnoe_obuchenie (Машинное обучение), #_oblachnye_servisy (Облачные сервисы), #_kubernetes, #_digital_ocean, #_django, #_opencv, #_kubernetes, #_python, #_python, #_obrabotka_izobrazhenij (
Обработка изображений
), #_mashinnoe_obuchenie (
Машинное обучение
), #_oblachnye_servisy (
Облачные сервисы
), #_kubernetes
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 23:59
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Не так давно я писал про волейбольный сервис, теперь пришло время описать его с технической точки зрения. Возможно, общественное сознание найдет изъяны в архитектуре и подтолкнет к лучшим решениям. Краткое описание функциональности:
Например, такими: Теперь, как это все работает. Технологии Все написано на python, веб-сервис — Django/Gunicorn. Интенсивно используются OpenCV и FFMpeg. База данных — Postgres. Кэш и очередь — Redis. Альфа В самой первой версии было 3 компонента:
Разработка велась локально, я поставил на домашний десктоп Ubuntu, а на нее microk8s и получил маленький Кубернетес-кластер. Здесь я столкнулся с тем, что кадры, которые видит opencv не очень совпадают с временем, которое видит ffmpeg из-за особенностей кодеков, поэтому высчитать время в оригинальном файле из номера кадра оказалаось невозможно. Из-за этого пришлось сохранять кадры, что сильно замедлило процесс и потребовало дальнейших архитектурных изменений. Параллельная обработка Как уже упоминалось, время обработки в 3 раза превышает время игры. Профайлер показал, что, большая часть времени тратится при записи кадров на диск, сам же разбор кадров примерно в два раза быстрее. Логично распараллелить эти две работы. По начальной задумке пока vproc разбирает кадры через opencv, ffmpeg параллельно записывает все на диск, а clipper собирает из них видео. Но с ffmpeg нашлись две проблемы:
В итоге вместо ffmpeg появился пятый элемент компонент — Framer. Он запускается из vproc, и листает кадры в том же видеофайле, ожидая пока vproc найдет розыгрыши. Как только они появились — framer выкладывает нужные кадры в отдельную директорию. Из дополнительных плюсов — ни одного лишнего кадра не эспортируется. Мелочь, но все таки. По производительности (на 10-минутном тестовом видео): Было: Completed file id=73, for game=test, frames=36718, fps=50, duration=600 in 1677 sec
Стало: Completed file id=83, for game=test, frames=36718, fps=50, duration=600 in 523 sec + framer time 303
Выигрыш в два раза, очень хорошо. Если писать в несколько потоков, то наверное можно выжать еще чуть. Если хранить кадры в памяти и генерить из них видео через API, то скорее всего можно ускориться значительно. Digital Ocean Дальше я стал выбирать хостинг. Понятно, что основные варианты — GKE, AWS, Azure, но многие авторы мелких проектов жалуются на непрозрачное ценообразование и, как следствие, немаленькие счета. Основная засада здесь — цена за исходящий трафик, она составляет порядка $100/Tb, а поскольку речь идет о раздаче видео, вероятность серьезно попасть очень неиллюзорна. Тогда я решил глянуть второй эшелон — Digital Ocean, Linode, Heroku. На самом деле Kubernetes-as-service уже не такая редкая вещь, но многие варианты не выглядят user-friendly. Больше всего понравился Digital Ocean, потому что:
При наличии CDN веб-серверу уже не было надобности раздавать видео, однако кто-то должен был это видео опубликовать. Так в архитектуре появился четвертый компонент — Pusher. Однако серьезным недостатком оказалась невозможность смонтировать один и тот же диск на несколько машин одновременно. Сам DO предлагает в таких случаях использовать NFS через выделенный контейнер, но пока решил не заморачиваться, ибо, как упоминалось выше, назревает специальное решение для видео кадров, и если уже городить отдельный контейнер, то для него. Тем не менее, отсутствие общего диска серьезно повлияло на архитектуру. Если с передачей загружаемого файла, можно было выкрутиться через S3, то гонять туда-сюда сотни тысяч кадров не выглядело блестящим вариантом. В итоге, пришлось привязать все стадии обработки конкретной видео к одной ноде, что конечно уменьшило общую масштабируемость системы. Логи и метрики Запустив кластер в облаке, я стал искать решение для сбора логов и метрик. Самостоятельно возиться с хостингом этого добра не хотелось, поэтому целью был free-tier в каком-нибудь облаке. Такое есть не у всех: Модная Grafana хочет $50 в месяц, выходящий из моды Elastic — $16, Splunk даже прямо не говорит. Зато внезапно оказалось что New Relic, также известный своими негуманными ценами, теперь предоставляет первые 100G в месяц бесплатно. Видео Вполне ествественным решением виделось разделить кластер на два node-pool'а:
Фронтовой пул, понятно, всегда онлайн, а вот процессинговый не так прост. Во-первых, обработка видео требует серьезных ресурсов (= денег), а во-вторых, обрабатывать приходится нечасто (особенно в стадии зарождения проекта). Поэтому хочется включать процессинг только, чтобы обработать видео (время обработки — 3x от продолжительности действа). Кубернетес формально поддерживает autoscale 0, но как именно это реализуется — я не нашел, зато нашлась такая дискуссия на Stack Overflow. В итоге пришлось нагородить еще один под во фронтовом пуле, единственной задачей которого является посматривать в постгрес иногда и включать/выключать процессинговый пул в зависимости от того, что в базе оказалось. У DigitalOcean есть неофициальный клиент для питона, но он уже давно не обновлялся, а Kubernetes API там не присутствует в принципе. Я сделал на коленке клиент для себя, он покрывает процентов десять возможностей, но вдруг кому пригодится для старта. В итоге диаграмм разрослась вот так: DevOps Несмотря на великое множество CI/CD инструментов, в разработке не нашлось ничего удобнее Jenkins. А для управления DigitalOcean'ом идеально подошли Github Actions. Ссылки
=========== Источник: habr.com =========== Похожие новости:
Обработка изображений ), #_mashinnoe_obuchenie ( Машинное обучение ), #_oblachnye_servisy ( Облачные сервисы ), #_kubernetes |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 23:59
Часовой пояс: UTC + 5