Database Scaling
Distributed Systems & Scalability
Chapter 4 · Database Scaling
A database can scale reads by copying itself (replication) or scale everything by splitting itself (sharding). Both genuinely work — and both cost something specific and measurable, not just "some consistency" in the abstract.
Read Replicas: Real Load Relief, and a Real Staleness Window
{'price': 100} to the primary makes it immediately available from primary.data. Reading the identical key from the replica before replicate_to() runs returns None — genuinely missing, not just slow. Only after replicate_to() actually runs does the replica correctly return {'price': 100}.
Sharding: Splitting Data, and What a Bad Key Does to It
user_id % 4 produced exactly 250 records per shard — a spread of 0 between the busiest and quietest shard.
0 on each of the remaining two. One shard alone carried 86.3% of all data. With only 4 distinct country values feeding the hash function, two of the four available shards never received a single record at all — sharding infrastructure was fully deployed, but most of it was doing nothing.
The Cost Sharding Adds: Cross-Shard Queries
100,000, matching a manual check (1,000 × $100) exactly. A question that was one query against an unsharded database becomes N queries plus a combine step, where N is however many shards exist.
Where This Connects
| This chapter's finding | What it connects to |
|---|---|
| A verified replica staleness window | Chapter 3's own cache-invalidation bug and Software Architecture Fundamentals Chapter 6's own eventual-consistency finding — the identical shape of risk, at the database layer this time |
| A dramatic, realistic sharding hotspot (86.3% of data on one shard) | Chapter 2's own Round Robin finding — an "equal treatment" rule (hash the key, mod by shard count) producing a badly uneven outcome |
| Cross-shard queries costing N shard-touches instead of 1 | Chapter 5's own CAP Theorem chapter — sharding is a concrete instance of trading single-query simplicity for horizontal capacity |
Hands-On Exercises
Using this chapter's own PrimaryDatabase/ReadReplica, write TWO keys to the primary before calling replicate_to(). Verify both are missing from the replica beforehand, and both are correctly present afterward.
Using this chapter's own sharding setup, try shard_by_country with a LESS skewed distribution — say, 30/25/25/20 percent across the same 4 countries instead of 80/7/7/6. Verify whether the hotspot shrinks, and report the new spread compared to this chapter's own 726-record spread.
Using this chapter's own two verified findings (replica staleness and the sharding hotspot), explain why "add read replicas" and "shard the database" solve genuinely different scaling problems — which one would have helped Chapter 1's own O(n) duplicate-check bottleneck, and why?
📄 View solutionChapter 4 Quick Reference
- Read replicas: verified reducing per-server load 3× (30 reads → 10 per server across 3 replicas) with zero change to any single query's own speed, at the cost of a real, verified staleness window before replication runs
- Sharding, verified: a good key (user_id) spread 1,000 records perfectly evenly; a plausible but poor key (signup country) put 86.3% of records on one shard and left two of four shards completely empty
- Cross-shard queries, verified: an aggregate across all data cost 4× the shard-touches of a single-shard query
- Next chapter: The CAP Theorem & Consistency Models — formalizing the exact tradeoffs this chapter and Chapter 3 both verified concretely