Рекомендации по архитектуре онлайн-игр Streamer для развертывания AWS

#amazon-web-services #aws-lambda #amazon-elastic-beanstalk

#amazon-веб-сервисы #aws-lambda #amazon-elastic-beanstalk

Вопрос:

Я работаю над простой онлайн-игрой, в которую будут играть стример и его зрители. Стример инициирует сеанс игры, создает игру, а затем предоставляет ссылку для подключения всем своим зрителям. Одна игровая сессия будет длиться ~ 10 минут.

Мой интерфейс — это SPA, который будет взаимодействовать с серверной частью с помощью REST API.

Я бы хотел развернуть его на AWS из-за их привлекательных возможностей вычислений по требованию и цен. Однако я хотел бы оптимизировать с минимальными затратами, сохраняя при этом параметры масштабируемости, используя мои предварительные знания об ожидаемом взаимодействии frontend-backend.

Предположения

  1. Иногда в игру могут играть 1000 (или даже больше) человек, в других случаях это может быть 0, с резкими колебаниями от минуты к минуте
  2. Серверная часть хранит состояние игры
  3. Стример и зрители чередуются по очереди
  4. Время принятия решения для зрителей ограничено (скажем, 10-15 секунд).
  5. В очередь зрителей каждый зритель может проголосовать за то, какие действия следует предпринять от имени зрителей
    • интерфейс просмотра позволит пользователям повторно голосовать и обновлять свой голос
    • интерфейс просмотра также будет периодически запрашивать у серверной части некоторую статистику о том, как голосуют все остальные зрители — предполагается, что эта статистика обновляется примерно раз в секунду, все сразу
  6. Каждый раз, когда стример или зрители заканчивают свой ход, состояние игры повторяется, и некоторый результат отображается на интерфейсе стримера

В течение одного игрового сеанса необходимо поддерживать следующее состояние:

  • состояние игры — содержит текущее состояние игры.
  • состояние голосования зрителей — содержит информацию о голосах всех зрителей.
  • статистика голосов зрителей — содержит моментальный снимок статистики голосов зрителей.

Архитектура

Я пытаюсь выяснить, какой может быть оптимальная архитектура для такого приложения.

Первоначально я планировал иметь сервер с одним узлом и хранить состояние в памяти, но это не масштабируемо, а также может быть дорогостоящим, когда игра не воспроизводится. Если бы я попытался развернуть это на elastic beanstalk, я полагаю, что не было бы никакого способа гарантировать, что все игроки в игровой сессии всегда будут перенаправляться на один и тот же сервер.

Итак, из того, что я собрал, оптимальным способом может быть сохранение всего состояния в DynamoDB, реализация полного REST API с использованием лямбда-функций, а затем периодический вызов лямбда-функции (например, 1 раз в секунду), который обновит статистику голосования зрителей, а также обновит состояние игры, когда будет выполнен ход.принято (эта периодическая задача, вероятно, также может быть выполнена в одном экземпляре EC2, вы бы предпочли это вместо запланированного lambda?).

Итак, мои вопросы к вам::

  1. Есть ли в этом смысл?
  2. Не могли бы вы выбрать другую архитектуру, учитывая ограничения, которые я предоставил? Если да, то почему?
  3. Обмениваю ли я простоту разработки (написание отдельного веб-сервера в node против написания большого количества лямбд) на низкую стоимость развертывания?

Комментарии:

1. * Как долго вы хотите поддерживать состояние данных и статистические данные?

2. Только в течение одной игровой сессии ~ 10-15 минут

Ответ №1:

Сервер: Rest API могут быть созданы с использованием Api Gateway Lambda вместо сервера узла на ECS / ElasticBeanStack с учетом стоимости и масштаба. Даже если вы настраиваете простой сервер узлов в ECS, состояние хранения должно быть выгружено с сервера во внешнее хранилище данных, хотя с помощью фиксированных сеансов elastic load balancer вы можете пересылать запросы от одной игры / пользователя на тот же сервер.

Хранилище данных: для хранения состояния и статистики я вижу два варианта, учитывая, что долговременное хранилище не требуется.

  • Redis: Пока число одновременных пользователей не слишком велико, мы можем масштабироваться с помощью автоматического масштабирования. Преимущества заключаются в низкой задержке, даже меньшей, чем у DynamoDB. Но масштабирование может стать проблемой, если общее количество пользователей колеблется от сверхнизкого до сверхвысокого за короткий промежуток времени без лишних затрат. Вот подробный пример.
  • DynamoDB: это наверняка работает и легко масштабируется. Вам не нужно задание, которое выполняется каждые 1 секунду, вы можете легко включить динамические потоки с помощью Lambda для обновления статистики.

В большинстве случаев решением является комбинация DynamoDB и Redis.

Комментарии:

1. Я бы добавил, что вы можете использовать транзакции в DynamoDB для записи новых голосов и добавления их к записи с общим итогом или просто использовать вызов updateItem для увеличения счетчиков для записи с общим итогом. Если все сделано правильно, нет необходимости в том, чтобы лямбда-код прослушивал поток.

2. Еще один момент, на который следует обратить внимание: по умолчанию существует ограничение в 1000 параллельных лямбда-исполнений, OP должен знать об этом, но это мягкий предел, который может быть повышен.

3. @Maurice то есть вы потенциально могли бы позволить зрителям напрямую взаимодействовать с DynamoDB? Весь их вклад в DynamoDB — это их голосование, которое либо записывается, либо обновляется (если уже записано). Безопасно ли предоставлять доступ к DynamoDB непосредственно во внешнем интерфейсе? Можно ли было бы сделать что-то подобное с Redis? Но из ответа я предполагаю, что с точки зрения масштабирования было бы безопаснее использовать DynamoDB. Кроме того, похоже, что статистика голосования пользователей может быть распространена среди пользователей, использующих сервис pub / sub, потому что afaik это идеально соответствует его варианту использования.

4. Вы могли бы использовать API-шлюз для аутентификации авторизации и использовать его для прокси-вызовов API DynamoDB, если это достаточно гибко, зависит от ваших конкретных требований. Pub / Sub — это отдельное обсуждение / вопрос, но вы можете создать что-то подобное, используя другие сервисы AWS, например, на основе websocket с API Gateway.

5. Итак, у каждого пользователя приложения будет подключенная учетная запись twitch, их идентификатор twitch — это то, что будет их идентифицировать. Итак, у меня тогда был бы лямбда-код, который генерировал бы временный токен доступа, который будет использоваться интерфейсом для запросов DynamoDB (через API Gateway)? У меня пока нет большого опыта работы с аутентификацией, поэтому я немного смущен этим. Если pub / sub не подходит, для этого может быть достаточно периодического запроса DynamoDB из интерфейса для общей статистики. Учитывая, что API Gateway, похоже, способен регулировать запросы, этого может быть достаточно.