System Design Foundation

Database Replication

By Ayush Arora••7 min read

Database replication

From Wikipedia: "Database replication can be used in many database management systems, usually with a master/slave relationship between the original (master) and the copies (slaves)."

Note: The industry has largely moved to the terms primary/replica for the same idea, but the roles are identical, so this post keeps the master/slave wording from the source.

The split of responsibilities:

Most applications read far more than they write, so a system typically has one master and several slaves. Reads, being the bulk of the traffic, get spread across many machines; writes stay on the one.

Replication is usually asynchronous: the master commits a write and returns to the client immediately, then ships the change to the slaves after the fact. So a slave can trail the master by a small window, from milliseconds under light load to seconds when it is catching up, and a read issued right after a write may not see that write yet.

Web serversDBMaster DBDBSlave DB1DBSlave DB2DBSlave DB3writesreadsreadsreadsDB replicationDB replicationDB replication

Why replicate

Reading right after a write

The lag from asynchronous replication creates a visible bug: a user updates their profile, the page reloads, and the old value is still there because the read landed on a slave that has not received the change yet. This is the read-after-write consistency problem. Two ways to deal with it.

Route that user's reads to the master for a short window.

After a user issues a write, send that same user's reads to the master instead of a slave, for a few seconds, long enough for the slaves to catch up. Everyone else keeps reading from slaves the whole time.

Pin the user to the master for the whole session.

Coarser and simpler: once a user performs any write, mark the session as "sticky to master" and serve all of that session's reads from the master until the session ends.

In practice sites lean on the first approach for follow-up reads, and often avoid the problem entirely for the immediate response by rendering it from the data the app already has in hand rather than issuing a fresh read at all.

What if a database goes offline?

We asked this about the load balancer; we ask it again here. Replication handles it.

A slave goes offline.

The master goes offline.

Which slave gets promoted?

If there are several slaves, they are not all equally good candidates. The system (or the failover tool running it) looks at a few things before picking one.

In systems that use a voting mechanism (a quorum), the replicas vote and the one that a majority agrees is the most up to date wins.

In real systems, promoting a master is still messier than it sounds. Even the best candidate may not have every write the old master had at the moment it died, so the missing data has to be reconciled with recovery scripts. Other schemes like multi-master and circular replication exist, but they add their own complexity and are outside the scope here.

The design so far

Putting the load balancer and database replication together:

DNSUserWeb browserMobile appwww.mysite.comIP addresswww.mysite.comapi.mysite.comLoad balancerWeb tierServer 1Server 2WriteWriteReadReadData tierDBMaster DBDBSlave DBReplicate

A request now flows like this:

  1. The user gets the load balancer's IP address from DNS.
  2. The user connects to the load balancer at that IP.
  3. The load balancer routes the HTTP request to Server 1 or Server 2.
  4. That web server reads user data from a slave database.
  5. That web server sends any write, update, or delete to the master database.

The web tier and the data tier are both solid now. The next step is improving load and response time, by adding a cache layer and pushing static content (JavaScript, CSS, images, video) onto a content delivery network (CDN).