← Tilbage til koncepter

Database Sharding

Arkitektur

Teknik til at horizontalt partitionere data på tværs af multiple databaser for at opnå skalering.

Beskrivelse

Sharding er en database arkitektur pattern hvor data opdeles horisontalt på tværs af multiple selvstændige databases kaldet shards. Hver shard indeholder et subset af den totale data og fungerer som en separat database. Dette står i kontrast til vertikal skalering (større server) og tillader næsten ubegrænset skalering ved at tilføje flere shards. En shard key (f.eks. user_id, region, dato) bestemmer hvilken shard hver række tilhører. Sharding strategier inkluderer: range-based (user 1-1000 på shard1), hash-based (hash user_id mod antal shards), og geography-based (EU data i EU shard). Sharding introducerer kompleksitet: cross-shard queries er dyre, resharding ved vækst er vanskeligt, og transaktioner på tværs af shards er komplekse. Men for meget store datasæts eller høj throughput er sharding ofte den eneste vej til skalering. Mange NoSQL databaser som MongoDB og Cassandra har built-in sharding.

Problem

En enkelt database server har fysiske grænser - CPU, RAM, disk I/O. På et tidspunkt kan selv den kraftigste server ikke håndtere load. Vertikal skalering (bigger server) er dyrt og rammer loft. Hvordan skalerer man ud over én maskines kapacitet?

Løsning

Sharding distribuerer data på tværs af mange maskiner. I stedet for én database med 1 milliard rows, har du 10 shards med hver 100 million rows. Load og storage fordeles, og systemet kan skalere ved at tilføje flere shards.

Eksempel

-- Original single database (scaling problem)
CREATE TABLE users (
  user_id INT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(100),
  country VARCHAR(50)
);
-- Problem: 100 million users, én server kan ikke håndtere load

-----------------------------------------------------

-- Sharding Strategy 1: Range-based
-- Shard 1: user_id 1 - 25,000,000
-- Shard 2: user_id 25,000,001 - 50,000,000  
-- Shard 3: user_id 50,000,001 - 75,000,000
-- Shard 4: user_id 75,000,001 - 100,000,000

-- Query routing logic
function getShardForUser(user_id) {
  if (user_id <= 25000000) return 'shard1';
  if (user_id <= 50000000) return 'shard2';
  if (user_id <= 75000000) return 'shard3';
  return 'shard4';
}

-- Problem med range: Uneven distribution hvis
-- user_id ikke er uniformt fordelt

-----------------------------------------------------

-- Sharding Strategy 2: Hash-based
-- Shard = hash(user_id) % num_shards

function getShardForUser(user_id) {
  const shardNum = hashFunction(user_id) % 4;
  return `shard${shardNum + 1}`;
}
-- Fordel: Jævn distribution
-- Ulempe: Range queries spans alle shards

-----------------------------------------------------

-- Sharding Strategy 3: Geography-based
-- Shard 1: country = 'DK', 'SE', 'NO' (Nordic)
-- Shard 2: country = 'DE', 'FR', 'UK' (Central EU)
-- Shard 3: country = 'US', 'CA' (North America)
-- Shard 4: country = 'JP', 'CN', 'IN' (Asia)

function getShardForUser(country) {
  const regionMap = {
    'DK': 'shard1', 'SE': 'shard1', 'NO': 'shard1',
    'DE': 'shard2', 'FR': 'shard2', 'UK': 'shard2',
    'US': 'shard3', 'CA': 'shard3',
    'JP': 'shard4', 'CN': 'shard4', 'IN': 'shard4'
  };
  return regionMap[country] || 'shard1';
}
-- Fordel: Data locality, GDPR compliance
-- Ulempe: Kan være unbalanced

Fordele

  • Næsten ubegrænset horizontal skalering
  • Distribueret load og bedre performance
  • Isoleret failures (én shard down != helt system down)
  • Geografisk data placement for latency
  • Cost-effective (mange small servers vs. én huge)

Udfordringer

  • Meget høj implementerings kompleksitet
  • Cross-shard queries er dyre og komplekse
  • Resharding ved growth er svært
  • No joins på tværs af shards
  • Distributed transactions er komplekse

Anvendelsesområder

  • Multi-tenant SaaS (shard per tenant)
  • Social media platforme (shard per region/user bucket)
  • E-commerce med millioner af produkter
  • IoT data collection ved massive skala
  • Gaming platforme med millioner af spillere

Eksempler fra den virkelige verden

  • Instagram: Sharding af billeder og users (1000+ shards)
  • Uber: Geography-based sharding for trip data
  • Discord: Sharding af guilds/servers på user ranges
  • Shopify: Shard per merchant/shop
  • Twitter: User timeline sharding på user_id