Streamer online game architecture considerations for AWS deployment

Viewed 38

I'm working on a simple online game, that will be played between a streamer and their viewers. A game session will be initiated by the streamer, they create the game and then share a link for all their viewers to connect. One game session will last ~10 minutes.

My frontend is an SPA which will talk with the backend using a REST API.

I'd like to deploy it on AWS due to their attractive on-demand compute options and pricing. However I would like to optimize for a low cost, while maintaining scalability options, using my prior knowledge about the expected interaction of frontend-backend.

Assumptions

  1. Sometimes the game might be played by 1000s (or even more) of people, other times it might be 0, with wild fluctuations from minute to minute
  2. The backend holds the state of the game
  3. The streamer and viewers take alternating turns
  4. The decision time for viewers is limited (let's say 10-15 seconds)
  5. On the viewers turn, each viewer can submit a vote on what action should be taken on behalf of the viewers
    • the viewer frontend will allow users vote repeatedly and update their vote
    • the viewer frontend will also periodically ask the backend for some statistics about how are all the other viewers voting - these statistics are supposed to be updated approx. once a second, all at once
  6. Each time a streamer or the viewers finish their turn, the game state is iterated and some result is displayed on the streamer's frontend

The following state needs to be maintained over the course of a single game session:

  • game state - contains the current state of the game
  • viewer vote state - contains information about votes of all the viewers
  • viewer vote statistics - contains a snapshot of the statistics of the viewer votes

Architecture

I'm trying to figure out what might be the optimal architecture for such an application.

Originally I planned to have a single node server and hold the state in memory, but this is not scalable, also might be expensive when the game is not played. If I tried deploying this on elastic beanstalk, I believe there would be no way to guarantee that all the players in the game session would be always routed to the same server.

So from what I've gathered, the optimal way might be to store all the state in DynamoDB, have the full REST API realized using lambda functions and then have a periodic lambda function call (e.g. 1 per second) that would update the viewer vote statistics and also update the game state when a turn was taken (this periodic task could also probably be handled on a single EC2 instance, would you prefer that over scheduled lambda?).

So my questions to you is are:

  1. Does this make sense?
  2. Would you choose a different architecture, given the constraints I provided? If so why?
  3. Am I trading ease of development (writing a singular web server in node vs writing a lot of lambdas) for low cost of deployment?
1 Answers

Server: Rest APIs can be build with Api Gateway + Lambda instead of a node server on ECS/ElasticBeanStack keeping in mind of cost and scale. Even if you setup a simple node server in ECS, storing state must be offloaded from the server to an external datastore, though with elastic load balancer sticky sessions you can forward requests from one game/user to same server.

Datastore: For storing state and statistics, I can see two options considering there is no long term storage needed.

  • Redis: As long as concurrent users doesn't go too high, we can scale with auto scaling. Advantages are low latency even lesser than DynamoDb. But scaling might be a problem if total users fluctuate from super low to super high in short interval without incurring unnecessary cost. Here is a detailed example.
  • DynamoDb: This for sure works and scale seamlessly. You don't need a job that runs every 1 second, you can easily enable Dynamo Streams with Lambda to update statistics.

Most of the times solution is combination of DynamoDb and Redis.

Related