Всем привет!
Около двух лет назад мой коллега Максим (max_posedon) опубликовал статью Wargaming Platform: Hello World, в которой «попробовал» (как он сам обозначил) объяснить, что же такое Платформа Wargaming. Мы с коллегами хотим продолжить делиться информацией и на этот раз копнём немного вглубь — как следует из названия статьи, в дистрибуцию.
С цифровой дистрибуцией знакомы все, пользуемся мы ею регулярно, видели всякое за 20 лет её существования, поэтому теорию и примеры рынка я обойду стороной, а рассказывать буду больше о конкретной имплементации и опыте.
Обобщённая схема дистрибуции Wargaming
Начнём сразу с рисунка: на нём можно увидеть и основные компоненты Wargaming Distribution System (WDS), и Data Flow контента.
Рисунок 1
Процесс кратко можно описать так: игровая студия (Game Studio) загружает очередную сборку игры на сервер WDS, который после необходимой обработки (об этом подробнее в разделе «Под капотом») через каналы дистрибуции (компоненты, обозначенные синим) распространяет их на клиентские приложения WGC.
WGC (Wargaming Game Center) — это клиентское desktop-приложение, средство взаимодействия пользователя с Wargaming Platform, в частности с системой дистрибуции. WGC загружает обновления на пользовательскую машину из доступных на текущий момент источников.
У WDS есть три основных канала дистрибуции:
- CDN — Content Delivery Network. Можно подключать любое количество провайдеров CDN для распространения конкретной игры.
- Static Seeds — BitTorrent-клиенты, запущенные на выделенных машинах и раздающие актуальный набор данных.
- p2p exchange — каждый клиент WGC может отдавать имеющиеся у него обновления другим клиентам во время их скачивания (опционально).
Да-да, в основе доставки обновлений лежит BitTorrent-технология. Сразу скажу, что p2p-обмен данными между клиентами — это в абсолютных цифрах минимальный по объёму трафика канал. Основная его функция — ускорение загрузки в локальных сетях с большим количеством клиентов WGC (к примеру, интернет-кафе) и уменьшение нагрузки на внешний сетевой интерфейс. Также использование BitTorrent позволяет легко организовать точку присутствия в любом нужном месте.
Канал дистрибуции Static Seeds интересен в историческом разрезе. Взгляните на гистограмму ниже: она показывает динамику минимальной стоимости трафика с CDN для самых крупных потребителей (т. е. оптовой, самой минимальной цены).
Рисунок 2
В 2010 году, на заре World of Tanks, гигабайт трафика обходился приблизительно в 0,2 $ при заказе от 10 ПБ. При регулярных обновлениях AAA-игр с миллионными аудиториями стоимость трафика получается весьма внушительной. Возможность легко добавить свою ноду в любую точку (с точки зрения географии/провайдеров) позволяет оттянуть на неё ощутимые объёмы трафика. В зависимости от присутствия CDN в той или иной точке, нагрузки на систему при релизах, объёмов релизов конкретной игры такой инструмент имеет хороший экономический эффект даже на сегодняшний день.
Чтобы базовая схема дистрибуции стала полностью понятной, стоит ещё сказать пару слов о компоненте, который на рисунке 1 обозначен как Wargaming Distribution System backend. Основные задачи компонента:
- подготавливать обновления, обеспечивая минимальное количество скачиваемого и устанавливаемого клиентом контента;
- распространять обновления по каналам дистрибуции;
- предоставлять клиенту информацию для обновлений.
Теперь давайте кратко пройдёмся по возможностям дистрибуции.
Функциональность
Технология BitTorrent, и в частности реализация libtorrent (спасибо Arvid Norberg), «из коробки» позволяет с минимальными затратами реализовать:
- локальный retracker и сиды — актуально как для групп пользователей, так и для игровых студий;
- подключение нескольких CDN — горизонтальная масштабируемость;
- весовые коэффициенты для разных CDN — балансировка, «запасные» CDN;
- проверку и восстановление целостности — файлы игры могут повреждаться по неосторожности, приложениями-клинерами, антивирусами, проблемами с драйверами или физическим носителем.
Независимо от libtorrent, но тоже о загрузках:
- Предзагрузка обновлений. Игровая студия может опубликовать обновления только для загрузки (без установки): в момент релиза новой версии они применятся, пользователи начнут играть в новую версию раньше.
- Балансировка предзагрузки. При больших объёмах обновлений можно равномерно «размазать» предварительное получение обновлений, чтобы снизить нагрузку на узлы раздачи и сгладить пик.
Установка/обновление игр:
- Патчи. Пользователь качает только недостающие части игры, хорошо сжатые.
- DLC. Часть контента может загружаться опционально по выбору пользователя или в зависимости от логики игры.
- Типы клиента. Игра может дать пользователю выбор, какой «тип клиента» скачивать (на примере World of Tanks: есть выбор между стандартными текстурами (SD) и текстурами высокого разрешения (HD), что позволяет не качать лишнее пользователям, у которых система не поддерживает максимальные настройки графики).
- Mini client. Возможность играть до полной установки, игровая студия имеет возможность определить минимально необходимый набор файлов для начала игры.
Прочее:
- Установка redistributables.
- Запуск произвольных установщиков во время процессов установки/удаления.
Под капотом
Parts & Patches
Игра может быть разделена на части (parts), которые задают определённую последовательность установки. Это даёт возможность игровой студии:
- доставлять пользователю контент только для выбранного языка игры;
- реализовать минимально необходимую часть геймплея для начала игры и доставлять её в первую очередь;
- обозначить некоторые части как DLC и дать возможность игре/пользователю дозапрашивать их отдельно.
Чтобы установить part, необходимо доставить и применить один или более patches. По своей сути патч — это 7z-архив с кодеком LZMA2. Уровень компрессии можно изменять в зависимости от типа контента игры. Для установки игры с нуля патч должен содержать весь контент определённой части игры. Если же это обновление, то патч содержит только необходимую разницу. Эта разница вычисляется пофайлово с помощью следующих алгоритмов:
Первый из алгоритмов блочный, а второй предоставляет возможность копирования частей произвольной длины и повторения. В зависимости от характера изменений (вставка, удаление, замена), места в файле, где они произведены (начало, конец, середина), их объёма, избыточности файлов один из алгоритмов может очень сильно выиграть у другого либо по объёму результирующего diff-файла, либо по скорости его применения на машине пользователя. WDS выбирает оптимальный для конкретного случая алгоритм получения бинарной разницы.
Torrent
Для загрузки патчей подготавливаются торрент-файлы по версиям, клиент WGC получает необходимую информацию с WDS backend и стартует торрент-сессию с нужными торрентами.
Сидами выступают, как уже косвенно упоминалось, CDN'ы (webseeds), Static Seeds (специально подготовленные машины с libtorrent-based клиентами), сами по себе клиенты WGC, ну и любые торрент-клиенты с необходимыми торрентами. Получает эти сиды торрент-сессия из следующих источников:
Некоторые провайдеры блокируют либо сам протокол BitTorrent, либо загрузку *.torrent-файла. Так как скачивание с webseeds происходит по HTTP, а сам *.torrent-файл качается по HTTPS, то такие блокировки для нас не критичны, игра всё равно будет доставлена. В худшем случае пропадёт трафик от Static Seeds и p2p. Бывали случаи в США, когда провайдер требовал установки своих сертификатов и фильтровал в том числе HTTPS-трафик (не очень красиво), находил там торрент-файл и блокировал его. Но внезапно изменение расширения торрент-файла позволяло его скачать, т. е. фильтры были только на уровне content name.
На данный момент WGC устанавливает до 50 соединений с каналами дистрибуции. На один и тот же CDN может быть установлено несколько соединений, что позволяет эффективнее утилизировать канал между его нодой и клиентом. Вдобавок к этому на основном CDN используется BBR-алгоритм контроля перегрузки, который считается жадным и утилизирует канал достаточно хорошо. Такая конфигурация обеспечивает максимально высокую утилизацию канала для быстрой доставки игры, но, конечно же, может страдать комфорт использования интернет-соединения для других приложений во время обновлений. Сейчас проходит серия тестирования альтернативных конфигураций, и в ближайшее время можно ожидать снижение количества соединений на постоянной основе с увеличением комфорта, но без ощутимого влияния на скорость доставки.
На всякий случай здесь хочется ещё раз подчеркнуть, что любая сетевая активность может влиять на качество трафика для клиента игры, для которого он критичен. Именно поэтому во время запущенной игры WGC не производит никаких сетевых операций без явной необходимости со стороны клиента игры (например, операцию авторизации).
Установка обновлений
Процессы скачивания и распаковки патчей у нас организованы параллельно, и выглядит это так:
- Старт загрузки патча, изменение приоритета скачивания на часть с заголовком архива.
- После получения полного заголовка архива стартует процесс распаковки и полученные из сети данные сразу же распаковываются.
- Распакованные данные сохраняются на диск.
- Загруженный патч также сохраняется на диск, так как не все фрагменты нужны для распаковки в момент их получения, и плюс для раздачи другим.
- После обработки файл патча может быть либо оставлен на диске, либо сразу же удалён в зависимости от конфигурации, заданной игровой студией.
Процессы распаковки и применения бинарных разниц происходят в отдельном процессе, что позволяет контролировать его системный и I/O-приоритет средствами ОС. Поверх этой функциональности существует пользовательская настройка «турборежима», которая ускорит процесс установки, но при этом будет сильно конкурировать с другими приложениями за ресурсы. По умолчанию WGC работает в режиме низкого потребления ресурсов, делая ставку на комфорт, но при первой установке WGC объясняет пользователю, что у него есть выбор.
Производительность
Объёмы обновлений
Минимизация объёма загружаемых данных — одна из основных задач нашей системы. В отличие от Steam-подхода, в котором дискретность обрабатываемых данных клиента игры равна 1 МБ, мы при построении бинарных разниц зачастую оперируем байтами. К тому же блоки этих байтов могут как добавляться в любую часть файла, так и удаляться из неё. В результате плановые версионные обновления World of Tanks и World of Warships обычно имеют объём 1–2 ГБ, в то время как те же самые версии игр, загруженные в Steam, приводят к необходимости загружать около 5 ГБ. World of Warships распространяется через Steam, поэтому эти данные получаются регулярно, а для World of Tanks данные взяты из специальных тестовых загрузок.
Требуемый объём места на диске пользователя
За минимальные объёмы скачиваемых данных и p2p приходится платить дисковым пространством, необходимым для операций по установке и обновлению клиента. На данный момент пользователю необходимо больше места, чем занимает клиент игры: такой буфер может составлять до половины размера клиента. Мы работаем над уменьшением этого значения, и есть возможность в ближайшее время сделать его фиксированным и не превышающим 2 ГБ, что при размерах современных игр становится вполне приемлемым. Но есть ещё одна важная особенность: для обновления игры (что в современном мире является регулярной активностью) также достаточно относительно небольшого буфера, который уже сейчас составляет около 4 ГБ для большинства игровых патчей. В то же время некоторые подобные решения требуют в два раза больше дискового пространства, чем занимает клиент игры.
Общая скорость установки обновлений
Мы проводили серию замеров на предмет сравнения скорости установки клиента World of Warships в WGC и Steam при равных скоростях сетевого канала. При использовании стандартного режима установки WGC обе системы показывают практически идентичный результат (насколько это возможно зафиксировать в подобных экспериментах, даже с учётом максимально чистых систем, регулярных перезагрузок и т. д.). При использовании «турборежима» средний по палате выигрыш WGC находится в рамках 5–7 процентов от времени полной установки. Надо учесть ещё тот факт, что пропускную способность сетевого интерфейса приходилось занижать для обеих систем, чтобы получить одинаковые условия и более-менее стабильную пропускную способность. С учётом того, что WGC утилизирует сетевой канал сильнее (см. раздел Torrent), без дополнительных ограничений на пользовательской машине скорость первичной установки игры становится ощутимо выше.
Заключительное слово, или чего здесь не было
Платформа Wargaming, и в частности система дистрибуции Wargaming, — это большие программные системы с десятилетней историей и десятками различных технологий и языков программирования. В статье мы познакомились лишь с высокоуровневой схемой дистрибуции и основными её характеристиками. Архитектура системы, бо?льшая часть технологий, процессы разработки, релизов, оперирования, географические нюансы дистрибуции, само приложение WGC со всей его функциональностью, не связанной с дистрибуцией, и многое другое осталось за скобками из-за «нерезиновости» статьи. Это означает лишь то, что я жду вопросы по статье и особенно о том, что в неё не вошло, в комментариях. Хорошего кода, всем удачи!
gban
В последнем обновлении WoT у вас ошибка какая-то была, после загрузки в циклическую переиндексацию ушло, пришлось удалять и заново 70 gb качать, модов нет, собственно установка "как бэ ванильная". А так схема красивая. но не работает.
artempetr0v Автор
Жаль это слышать. «Циклическая переиндексация» — это достаточно редкий случай, который может быть связан с ОС/hardware и вызван тем, что записывается один контент на диск, а во время чтения по тем же адресам считывается измененный («битый»). Но это только предположение. Конечно, чтобы подобраться ближе к истине, надо увидеть реальные симптомы — хотя бы из логов. Здесь наверное неподходящее место чтобы разбирать конкретный случай, но нам бы очень помог отчет об ошибке. Его можно сгенерировать в меню WGC и прикрепить к заявке в службу поддержки. Спасибо за комментарий!
gban
Ну до этого то все обновления нормально накатывались. Отчет об ошибке сделать наверное сделать не смогу, т.к. пришлось все удалить, это проще и быстрее, чем доставать службу поддержки.