Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Денис Дубовицкий — Как раздавать большие файлы ...

Ozon Tech
December 12, 2022

Денис Дубовицкий — Как раздавать большие файлы без бутылочных горлышек

Ozon Tech

December 12, 2022
Tweet

More Decks by Ozon Tech

Other Decks in Technology

Transcript

  1. Ozon Tech 2022 Как раздавать большие файлы без бутылочных горлышек

    Денис Дубовицкий, старший разработчик информационных систем
  2. 2

  3. Схема работы поиска 3 Индексатор товаров Хранилище файлов Инстанс поиска

    Инстанс поиска Инстанс поиска Балансировщик API Сервис с товарами Пользователь
  4. Большие файлы и связанные с ними проблемы Примеры: поисковый индекс,

    ML-модели 4 • сетевой канал не безлимитный • мешаем другим приложениям в кластере • много раз скачиваем одно и то же • при масштабировании растет нагрузка на сеть и хранилище Проблемы:
  5. Цифры (случай команды поиска) 5 Реплики Файл индекса 210 GB

    в сжатом состоянии 320-350 GB в разжатом состоянии Трафик 100 GB/s в пике 331 инстанс
  6. Текущая схема 6 Индексатор товаров Хранилище файлов Инстанс поиска Инстанс

    поиска Инстанс поиска Балансировщик API Сервис с товарами Пользователь Кеширующий слой
  7. Peer To Peer 7 • Позволит не скачивать несколько раз

    то, что уже скачано из источника • Снижение нагрузки на кеширующий слой • Меньше ресурсов на кеширующий слой • Возможность дальнейшего масштабирования • Скорее всего, мы не первые, кто об этом задумывается Инстанс поиска Инстанс поиска Инстанс поиска Инстанс поиска
  8. Критерии решения 8 • P2P-раздача • Равномерное распределение нагрузки •

    Декларативное задание состояния • Ретеншн • При падении должно раздавать уже частично скачанные файлы • Использование кеша при операции с файлами • Минимум точек отказа • Локализация трафика • Ограничение скорости в байтах в секунду • Сжатие трафика между пирами • Использование существующих CDN • Возможность делиться данными непосредственно на файловой системе ноды • Скачивание должно как можно меньше влиять на остальной трафик
  9. Способы решения 9 1. BitTorrent? 2. Решение на коленке: K8S

    API, ServiceAccount, ClusterRole, ClusterRoleBinding и вот это вот все… 3. Собственное решение под конкретную задачу Исследование похожих инструментов 4. Исследование похожих инструментов: • github.com/dragon fl yoss/Dragon fl y2 — решение для распределенной загрузки файлов и Docker- образов (Alibaba) • github.com/uber/kraken — решение, преймущественно созданное для ускорения загрузки Docker образов (Uber)
  10. Dragonfly (Alibaba) & Kraken (Uber) 10 • Написаны на Go

    • Интерфейс в виде HTTP-прокси на нодах • Помимо файлов работает с Docker-образами • Официальные helm-чарты • Веб-интерфейс • Оба решения написаны преимущественно для репликации Docker-образов • Много «движущихся частей» • Много точек отказа • Зависимость от MySQL • Много лишнего функционала • Огромный набор настроек • Нет экспертизы – +
  11. Собственное решение 11 – + • Инструмент под конкретную задачу

    • Использование платформенных инструментов • Полностью контролируемое решение • Контроль над локализацией трафика • Разработка займет много времени • Много времени на отладку и допиливание • Простого решения не получается
  12. Протокол BitTorrent 12 + • Знакомое всем словечко • Устоявшаяся

    спецификация • Целостность скаченных файлов • Спецификация webseed позволяет скачивать файлы по HTTP • Дискавери-фичи • Нет единой точки отказа • Нет внешних зависимостей • Есть библиотеки на Go
  13. Файл метаданных (.torrent) 13 Список URL-трекеров Список URL-узлов Идентификатор —

    хеш-сумма от поля информации Информация: • длина сегментов • список сегментов • файлы (длина в байтах, название, индексы и хеш- суммы сегментов)
  14. Библиотеки 14 – + github.com/anacrolix/torrent • 4.6K+ звезд • 260+

    изменений • Активное сообщество • Де-факто основная библиотека для работы с протоколом • Достаточно расширяемая • Автор старается покрывать все тестами • Используется большинством torrent- проектов на Go • Очень много кода, часто ближайшие теги не совместимы • У автора свое мнение на то, как писать большие проекты • Документация: код и тикеты на гитхабе
  15. Библиотеки 15 – + github.com/cenkalti/rain • 700+ звезд • 45

    изменений • Хороший, структурированный код • Тесты • Нет активного сообщества, документации • Не выглядит библиотекой на все случаи жизни • Сложно расширяется • Весь основной функционал в internal
  16. Трекер: координация клиентов 17 Координирует клиентов Не участвует в раздаче

    Не знает про состав раздачи Запрос клиента (анонс): • Infohash (ID раздачи) • Прослушиваемый порт клиента • Количество данных, которыми клиент успел обменяться Ответ сервера: • Список пиров, участвующих в раздаче
  17. DHT & WebSeed 19 • Ищет других участников • Вписывается

    в инфраструктуру Ozon • Часть стандарта протокола • Поддерживается Go-библиотеками • Обычный HTTP URL как источник • Вписывается в инфраструктуру Ozon DHT • Пир выступает в роли DHT-узла • Маленькие сообщения по UDP WebSeed
  18. Бестрекерные раздачи 20 Пир DHT Пир DHT Пир DHT 1.

    Исключают сторонние компоненты 2. Меньше точек отказа 3. Снижают сложность системы 4. DHT заменяет собой трекер 5. Функционал встроен в библиотеку 6. DHT + Warden = <3
  19. Myriad 21 Википедия: • В русском языке слово «мириада» устарело

    и используется только в поэтическом контексте как обозначение очень большого количества чего-либо • В Древней Греции число 10 000 носило название «мириа́да» (др.-греч. μῡριάς, род.п. μῡριάδος), и было самым большим числом, имевшим название Google: 1 мириад — 2 985 984
  20. Схема решения в Ozon 22 Сервис отправляет запрос со ссылкой

    на файл 1. Сервис получает идентификатор задачи 2. Myriad ищет рядом с файлом файл метаданных 3. Происходит рандомная приоритизация сегментов 4. По мере скачивания, Myriad делится с другими участниками 5. Поиск Myriad K8S Pod Поиск Myriad K8S Pod Поиск Myriad K8S Pod Кеш (webseed) S3 Warden (discovery)
  21. Создание закачки 23 { "files": [ { "url": "http://host-1.ru/bucket/file-1.bin", "destination_path":

    "downloads/file-1.bin" }, { "url": "http://host-2.ru/bucket/file-2.bin", "destination_path": "downloads/file-2.bin" } ] } {"state_id": "478a9244-6d0a-4cf8-a863- eb2117063ccc" } Запрос: Ответ:
  22. Проверка статуса 24 Запрос: Ответ: {"state_id": "478a9244-6d0a-4cf8-a863-eb2117063ccc" } { "id":

    "478a9244-6d0a-4cf8-a863-eb2117063ccc" , "is_complete": false , "files": [ { "url": "http://cdn-1.o3.ru:7480/bucket/file-1.bin" , "destination_path": "downloads/file-1.bin" , "stats": { "progress": 45.0 , "peer_connections_count": 3 , "total_peers_count": 5 , "active_peers_count": 5 , "connected_seeders_count": 0 } } , … ] }
  23. Как начать работать с Myriad 25 myriadSidecar : # Включаем

    сайдкар enabled: "yes" # Включить/выключить трафик между датацентрами. crossDatacenterTrafficEnabled: "false " # Указываем источники файлов webSeeds : - "http://cdn-1.o3.ru:7480" - "http://cdn-2.o3.ru:7480"
  24. Что в итоге получили 26 - Решение в виде сайдкара

    - gRPC и HTTP интерфейс управления - Отсутствие внешних зависимостей - Локализация трафика в пределах датацентра - Ограничение скорости трафика - Сжатие трафика между пирами с помощью zstd - Автоматическое удаление файлов - Декларативный примитивный API - Автообнаружение соседей - Дашборд с метриками по каждому пиру - Передача данных между пирами с помощью TCP или uTP (поверх UDP)
  25. Что пока не получили 29 - Не удалось локализовать трафик

    в пределах стоек и нод - Не получилось шарить файловую систему ноды — инфрамены решили, что это небезопасно
  26. С какими проблемами столкнулись 30 • Библиотека больше похожа на

    фреймворк (что является как плюсом, так и минусом) • Чтобы понять причины возникающих проблем, необходимо было потратить много времени, распутывая код библиотеки пошагово, иногда даже при помощи дебаггеров и вспомогательных метрик • Помимо библиотеки, часто приходилось вникать в особенности протокола, что тоже отнимало много времени • Две недели потратили на то, чтобы понять, почему качаем со скоростью 15 Mb/s
  27. С какими проблемами столкнулись 31 • Утонули в профилях и

    трейсах pprof • Ради метрик и оптимизаций пришлось форкнуть библиотеку и дорабатывать ее под наши нужды в оперативном порядке • Метрики в библиотеке сделаны в виде логов и expvar