Погружаясь в любимую игру, кто угодно, несомненно, будет не особенно рад, если у него неожиданно выключится компьютер из-за пропавшего в доме электричества или, не дай бог, вышедшего из строя компонента. В случае с играми, требующими постоянного подключения к интернету, список угроз дополняется сетевыми проблемами. Именно об этом я и хочу поговорить, рассмотрев весь путь — от дата-центра до изображения на мониторе игрока с технической точки зрения и немного рассказав, про то, как правильно диагностировать возможные неполадки.
Принципиально всё это обычно состоит из следующих частей:
Системы хранения данных (Storage Area Network, SAN) — это тоже своего рода серверы, но предназначенные для надёжного хранения больших объёмов информации и быстрого доступа к ним. СХД обычно подключаются к серверам с помощью оптоволокна или другой высокоскоростной коммутации. На них обычно и хранятся базы данных и операционные системы с игровыми сервисами (тут возможны варианты).
Сетевое оборудование — это маршрутизаторы, свитчи, фаерволлы и прочие виды устройств, реализующие передачу данных между серверами и игроками. Видов сетевых топологий несколько, они сильно зависят от специфики конкретных инсталляций, ограничения по финансам и прочих вещей, поэтому я, с вашего позволения, расскажу только об одном частном случае, а именно — как это устроено в дата-центре, где хостится наш Eco-сервер.
Поскольку каждая минута простоя в игровой индустрии — это недовольные пользователи, а следовательно и потерянные деньги, к надёжности и отказоустойчивости там подходят со всей серьёзностью. В первом приближении это означает, что выход из строя любого узла не должен влиять на предоставление услуг совсем, либо время восстановления должно быть минимальным — секунды и минуты. Поэтому всё, что только можно на серьёзных хостингах дублируется — сетевое оборудование, серверы, системы хранения, интернет-каналы…
У нас это выглядит следующим образом — вся сетевая инфраструктура задублирована и в каждый сервер воткнуты кабели, идущие от разных сетевых устройств. Между собой эти устройства тоже подключены двумя «хвостами». Каждое хранилище данных подключено к серверам несколькими оптическими кабелями. Внутри серверов диски объединены в избыточные массивы, продолжающие работать даже в случае выхода отдельных дисков из строя, то же самое в СХД. Оперативная память в серверах не обычная, а с коррекцией ошибок, что позволяет избежать проблем в случае солнечных бурь и других электромагнитных флуктуаций. Серверы объединены в кластер, который способен быстро и без потери данных восстановить работу сервисов в случае выхода из строя одного или нескольких серверов. Звучит всё это довольно внушительно, но у крупных компаний, надо сказать, всё гораздо круче, хоть и стоит, как золотой паровоз.
Для игры через интернет нужно ровно одно — сетевая связность между сервером и клиентом. Это, максимально утрируя — способность данных пройти от вашего компьютера через домашний роутер (если он есть) к оборудованию вашего провайдера, внутри его сети до стыка с другим провайдером, обычно более высокого уровня, внутри его сети до точки обмена трафиком, затем через оборудование магистрального провайдера — по оптоволокну за границу, может быть даже по дну океана… бла-бла-бла, вот несчастные данные и приехали в дата-центр какого-нибудь Близзарда. По дороге пакеты (отдельные куски данных) проходят несколько сетевых устройств и на каждом из них с ними может случиться что-то нехорошее. Самый простой случай — они просто потеряются и не дойдут до пункта назначения. Или дойдут, но уже не те. Нужно сказать, что интернет — система довольно устойчивая к неполадкам отдельных узлов, но это отнюдь не значит, что у вас не будет тормозить.
Для того, чтобы можно было подтвердить получение пакетов собеседником, сто лет назад был придуман протокол TCP. Несмотря на всю критику, высказываемую в его адрес — своё дело он выполняет неплохо, а именно — гарантирует, что все пакеты, отправленные вами, дойдут до получателя, причём в правильной последовательности, либо вы узнаете об обратном. Расплатой за эту надёжность является его крайняя неторопливость — данные должны несколько раз пройти туда-обратно, чтобы все убедились в корректности их получения.
Полной противоположностью является протокол UDP — никакого предваряющего передачу данных установления соединения, никаких подтверждений — только поток данных. UDP широко используется в случаях, когда скорость передачи пакетов важнее гарантированной доставки, правильной последовательности данных и отсутствия дублирования. Это, например, потоковое видео, голосовые звонки и, не поверите — компьютерные игры. В самом деле — намного важнее, чтобы сервер как можно скорее получил ваше нажатие на кнопку, чем уверенность в том, что вы сделали именно три шага влево, а не два или четыре. Обычно недостатки UDP разработчики игр пытаются скомпенсировать какими-то своими методами, чтобы, например, потери пакетов не приводили к ужасным последствиям.
Так вот, возвращаясь к игровым тормозам и прочим радостям. Зайду сразу с козырей — надёжно продиагностировать сетевые проблемы пингом или трассировкой можно далеко не всегда. Дело в том, что пинг для работы использует протокол, называемый ICMP — в рамках него передаются контрольные и сервисные сообщения, в том числе о наличии/отсутствии сетевой связности. Нюанс в том, что фактически для работы сервисов он не критичен и иногда правила его обработки существенно отличаются от TCP или UDP. Проще говоря — некоторые узлы могут не отвечать на пинги вовсе или делать это по остаточному принципу, если у них нет более важных дел. Со стороны клиента это может выглядеть как недоступность узла или потеря пакетов. С трассировкой возникает схожая проблема, потому что, например, в утилите tracert ОС Windows используется тот же ICMP. Кроме того, обе этих утилиты могут демонстрировать нерелевантные данные из-за так называемой несимметричной маршрутизации. В двух словах — это ситуация, при которой туда и обратно пакеты идут существенно различающимися путями, что со стороны клиента может выглядеть как «высокий пинг» или та же потеря пакетов. Самый простой способ избавиться от первого — проводить трассировку с использованием не tracert, а traceroute, который умеет работать с TCP/UDP и в нём можно указать конкретный номер порта (идеально — использовать тот же порт, что и игра).
легион кривая архитектура сетевого взаимодействия. Рассмотрим очень животрепещущий для некоторой части ММОзговедов пример — в Eco при определённой скорости движения (а честно говоря — если вы хотя бы просто бежите по прямой) персонажа перестают успевать прогружаться текстуры под ногами и, в случае, если вы едете на автомобиле — он вместе с водителем падает непосредственно в ад, откуда его потом приходится доставать с бубном и плясками. В чём только не обвиняли наш несчастный сервер и меня лично, как его админа… а разгадка элементарна и описывается одним словом — геометрия. В самом деле, наверняка все (да, я оптимист) помнят ещё со средней школы формулу площади поверхности шара — 4πR2.
Что это означает на практике? Почти наверняка тайлы вокруг персонажа отрисовываются по концентрическим сферам, а это значит, например, что если на расстоянии 5 метров нужно отрисовать около 300 тайлов, то на расстоянии 10 — уже 1200, а на 20 — где-то 5000. Разумеется, если информацию обо всех этих тайлах передавать в реальном времени, да ещё хорошо, если не отдельно для каждого — никакой пропускной способности канала и мощности процессора не хватит. А в Эко, есть подозрения, что происходит именно так или как-то похоже. Как с этим справляются другие — вариантов много, но лично мне на ум первым приходит способ, при котором в момент захода в игровой мир пользователь сразу получает информацию обо всём или существенной части мира (с последующей фоновой подгрузкой оставшегося), а в дальнейшем от сервера к нему прилетают только изменения тайлов, коих относительно немного. Да, это сделает загрузку более долгой, но решит основную проблему.
На этой оптимистичной ноте я закругляюсь, благодарю за внимание и желаю стабильного интернета всем осилившим дочитать.
Начало пути. Хостинг
Подавляющее большинство сетевых игр, как ММО, так и однопользовательских, но требующих онлайн-аутентификации (не путать с авторизацией!), для работы используют инфраструктуру, состоящую из серверов и сетевого оборудования, расположенного в дата-центрах, которые обрабатывают запросы игроков и отправляют в ответ свои данные — например, разрешение на вход от логин-сервера или игровую информацию для уже вошедших в игру.Принципиально всё это обычно состоит из следующих частей:
- Серверы
- Системы хранения данных
- Сетевые железки
Системы хранения данных (Storage Area Network, SAN) — это тоже своего рода серверы, но предназначенные для надёжного хранения больших объёмов информации и быстрого доступа к ним. СХД обычно подключаются к серверам с помощью оптоволокна или другой высокоскоростной коммутации. На них обычно и хранятся базы данных и операционные системы с игровыми сервисами (тут возможны варианты).
Сетевое оборудование — это маршрутизаторы, свитчи, фаерволлы и прочие виды устройств, реализующие передачу данных между серверами и игроками. Видов сетевых топологий несколько, они сильно зависят от специфики конкретных инсталляций, ограничения по финансам и прочих вещей, поэтому я, с вашего позволения, расскажу только об одном частном случае, а именно — как это устроено в дата-центре, где хостится наш Eco-сервер.
Поскольку каждая минута простоя в игровой индустрии — это недовольные пользователи, а следовательно и потерянные деньги, к надёжности и отказоустойчивости там подходят со всей серьёзностью. В первом приближении это означает, что выход из строя любого узла не должен влиять на предоставление услуг совсем, либо время восстановления должно быть минимальным — секунды и минуты. Поэтому всё, что только можно на серьёзных хостингах дублируется — сетевое оборудование, серверы, системы хранения, интернет-каналы…
У нас это выглядит следующим образом — вся сетевая инфраструктура задублирована и в каждый сервер воткнуты кабели, идущие от разных сетевых устройств. Между собой эти устройства тоже подключены двумя «хвостами». Каждое хранилище данных подключено к серверам несколькими оптическими кабелями. Внутри серверов диски объединены в избыточные массивы, продолжающие работать даже в случае выхода отдельных дисков из строя, то же самое в СХД. Оперативная память в серверах не обычная, а с коррекцией ошибок, что позволяет избежать проблем в случае солнечных бурь и других электромагнитных флуктуаций. Серверы объединены в кластер, который способен быстро и без потери данных восстановить работу сервисов в случае выхода из строя одного или нескольких серверов. Звучит всё это довольно внушительно, но у крупных компаний, надо сказать, всё гораздо круче, хоть и стоит, как золотой паровоз.
Дорога домой. Глобальная сеть
Безусловно, в 2019 году компьютерная грамотность населения стала гораздо выше, чем, скажем, 20 лет назад, но я не побоюсь показаться скучным и расскажу про некоторые основы максимально популярным языком.Для игры через интернет нужно ровно одно — сетевая связность между сервером и клиентом. Это, максимально утрируя — способность данных пройти от вашего компьютера через домашний роутер (если он есть) к оборудованию вашего провайдера, внутри его сети до стыка с другим провайдером, обычно более высокого уровня, внутри его сети до точки обмена трафиком, затем через оборудование магистрального провайдера — по оптоволокну за границу, может быть даже по дну океана… бла-бла-бла, вот несчастные данные и приехали в дата-центр какого-нибудь Близзарда. По дороге пакеты (отдельные куски данных) проходят несколько сетевых устройств и на каждом из них с ними может случиться что-то нехорошее. Самый простой случай — они просто потеряются и не дойдут до пункта назначения. Или дойдут, но уже не те. Нужно сказать, что интернет — система довольно устойчивая к неполадкам отдельных узлов, но это отнюдь не значит, что у вас не будет тормозить.
Для того, чтобы можно было подтвердить получение пакетов собеседником, сто лет назад был придуман протокол TCP. Несмотря на всю критику, высказываемую в его адрес — своё дело он выполняет неплохо, а именно — гарантирует, что все пакеты, отправленные вами, дойдут до получателя, причём в правильной последовательности, либо вы узнаете об обратном. Расплатой за эту надёжность является его крайняя неторопливость — данные должны несколько раз пройти туда-обратно, чтобы все убедились в корректности их получения.
Полной противоположностью является протокол UDP — никакого предваряющего передачу данных установления соединения, никаких подтверждений — только поток данных. UDP широко используется в случаях, когда скорость передачи пакетов важнее гарантированной доставки, правильной последовательности данных и отсутствия дублирования. Это, например, потоковое видео, голосовые звонки и, не поверите — компьютерные игры. В самом деле — намного важнее, чтобы сервер как можно скорее получил ваше нажатие на кнопку, чем уверенность в том, что вы сделали именно три шага влево, а не два или четыре. Обычно недостатки UDP разработчики игр пытаются скомпенсировать какими-то своими методами, чтобы, например, потери пакетов не приводили к ужасным последствиям.
Родная гавань. Унутре
Предположим, что с сетью у нас всё хорошо и пакеты радостно курсируют до сервера и обратно. Значит ли это, что можно облегчённо выдохнуть и наконец-то спокойно поиграть? Разумеется, нет — иначе зачем бы мне писать третий параграф? Проблемы сетевого характера могут возникать при низком пинге (а точнее — RTT, говорите грамотно) и отсутствии потерь пакетов. Имя этим проблемам —Что это означает на практике? Почти наверняка тайлы вокруг персонажа отрисовываются по концентрическим сферам, а это значит, например, что если на расстоянии 5 метров нужно отрисовать около 300 тайлов, то на расстоянии 10 — уже 1200, а на 20 — где-то 5000. Разумеется, если информацию обо всех этих тайлах передавать в реальном времени, да ещё хорошо, если не отдельно для каждого — никакой пропускной способности канала и мощности процессора не хватит. А в Эко, есть подозрения, что происходит именно так или как-то похоже. Как с этим справляются другие — вариантов много, но лично мне на ум первым приходит способ, при котором в момент захода в игровой мир пользователь сразу получает информацию обо всём или существенной части мира (с последующей фоновой подгрузкой оставшегося), а в дальнейшем от сервера к нему прилетают только изменения тайлов, коих относительно немного. Да, это сделает загрузку более долгой, но решит основную проблему.
На этой оптимистичной ноте я закругляюсь, благодарю за внимание и желаю стабильного интернета всем осилившим дочитать.
15 комментариев
Мне и специальные «новости разработки ECO» регулярно приходят, только я ими с ммозговедами не делюсь по причине своего слабого тайм-менеджмента.
Всего-то 200 долларов.
Редко где в продакшене удастся найти столь же качественно исполненный код.
Другой вопрос — это что некоторые механизмы можно было бы сделать и по-другому… Так ведь сейчас, в процессе разработки игры, важнее то — что уже работает, а не насколько оно оптимально. Байты и миллисекунды экономить начнут ближе к релизу.
Система чанков в ECO все таки есть. Чанки там кубические, со стороной в 10 блоков. Блоки идентифицируются коротким словом — 2-мя байтами. Таким образом один чанк занимает ~2КБ.
Пакуется чанк без сжатия, если это воздух, то по сети отправится 2КБ воздуха — нулей.
Блоки пакуются в чанк целиком все. Поменяли один блок — да здравствует свежая пересылка всего чанка! Каких-либо масок и клеточных алгоритмов я пока не увидел, пока видно что чанк пересылается целиком при любом своем изменении.
На приведенной гифке хорошо видно подгрузку мира порциями, т.е. чанками.
В манкрафте тоже есть проблема избыточной пересылки чанов при активном изменении ландшафта множеством игроков на небольшой территории. А чанки в майнкрафте многократно больше: 16*16*256. Но майнкрафт частично решает эту проблему протоколом репликации (в видимом пространстве засылаются не чанки целиком, а только команды модификации ландшафта) и локальным хранением мира. В ECO, кажется, к этому или еще не пришли, или от этого ушли. Т.е. протокол репликации и локальное хранение мира в ECO не просматриваются.
Если посчитать количество чанков для стандартных параметров дальности отрисовки (120 тайлов), получается, что куб со стороной 240 тайлов, в центре которого находится персонаж, содержит в себе около 14000 чанков, а значит, для передачи потребуется 27 мегабайт трафика. Соответствующего радиуса сфера — 14 мегабайт. Картина не слишком-то радужная…
С другой стороны, не могу сказать, что наш сервер генерирует большой поток данных:
Имхо, тормоза отрисовки происходят не только из-за отсутствия сжатия/дедупликации. Возможно, узкое место где-то в районе формирования списка отдаваемого сервером.
В IT практически все самоучки в том плане, что академические курсы есть только по основам, а остальное настолько быстро меняется, что никакие классические учебные заведения за этим успеть не в состоянии.
Думаю, что неплохим стартом будет чтение документации циско для CCNA с параллельным изучением цикла «Сети для самых маленьких». Все незнакомые аббревиатуры гуглить на xgu.ru или в википедии (лучше англоязычной).