• Advertisement
Sign in to follow this  

Keeping track of a persistent online world in the DB

This topic is 3736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In game like an MMO, it's very important to keep the DB up to date with the state of the world and the players. But I assume a game would not work directly with the DB, but keep an in-memory representation of the world, for performance reasons? So how can a DB be kept in synch with the game in a way that allows requests made to the server to return very quickly, without waiting for DB calls to be made? I thought perhaps all DB updates might be queued for a separate thread to take care of - when a request comes in the in-memory version is updated and a query queued to update the DB accordingly. This must be a standard problem all MMOs and many online applications face - is there a standard obvious solution I just didn't see yet? Or perhaps it is a complicated problem and there are some articles on it I might read?

Share this post


Link to post
Share on other sites
Advertisement
It's the same problem as maintaining consistency with a cache/memory or memory/disk...look up the principles and you can basically just apply them.

Share this post


Link to post
Share on other sites
Quote:
Original post by d000hg
In game like an MMO, it's very important to keep the DB up to date with the state of the world and the players. But I assume a game would not work directly with the DB, but keep an in-memory representation of the world, for performance reasons? So how can a DB be kept in synch with the game in a way that allows requests made to the server to return very quickly, without waiting for DB calls to be made?


There's no easy solution. We discussed something similar on the Multiplayer forum recently - look for a thread I started about Load Balancing, a month or so ago I think. But basically the options are like these:

1) Just use a cache in the traditional manner, as yahastu says. Great for reads, great for updates if you have a reliable system (including a backup power source!) You may find that you hit the DB infrequently enough that it's not a problem, or that judicious query optimisation and indexing helps enough. Caches are not so great if you're distributed, because you may need to keep multiple servers or databases in sync, and worry about race conditions while doing so. Technologies like memcached and MySQL replication already address some of these issues.

2) Separate state into that you need to keep consistent and that you don't. eg. Trade transactions will read from the DB directly because it's imperative that they're done accurately, whereas player movement can just be read from a cache. It doesn't matter if the database isn't kept up to date with the cache at all times because player position is not a critical factor. You can just update it in a background thread. If enough of your requests just hit the 'inconsistent' cache, you can probably afford for the critical requests to take a while.

3) Stop expecting requests to the server to return very quickly. :) There's network latency anyway, so what's a few extra milliseconds? Run any request that hits the DB in a background thread or a coroutine, and let it return when it's ready. As long as you're able to switch to something else, and are never wasting CPU time doing nothing but waiting for the DB, it's all good. It's just awkward to program such a model in C++, generally. Note also that you may need to check for dependencies between requests so that actions on a single entity are effectively pipelined and state is kept consistent.

Quote:
I thought perhaps all DB updates might be queued for a separate thread to take care of - when a request comes in the in-memory version is updated and a query queued to update the DB accordingly.


Works great, except when the DB update is some thing like "deduct adventurer's last 1000 gold", and the adventurer quickly clicks the "buy something for 1000 gold" button that resolves first, because reading gold from the cache is quicker. That's why you need something to examine the requests as they come in and manage them.

Quote:
This must be a standard problem all MMOs and many online applications face - is there a standard obvious solution I just didn't see yet? Or perhaps it is a complicated problem and there are some articles on it I might read?


Yeah, it's a standard problem, no, there's no standard obvious solution, and yeah, it's complicated. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement