← 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 et databasearkitekturmønster hvor data opdeles horisontalt på tværs af flere selvstændige databaser kaldet shards. Hver shard indeholder en delmængde 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-nøgle (f.eks. user_id, region, dato) bestemmer hvilken shard hver række tilhører. Shardingstrategier inkluderer: intervalbaseret (bruger 1-1000 på shard1), hashbaseret (hash user_id mod antal shards) og geografibaseret (EU-data i EU-shard). Sharding introducerer kompleksitet: forespørgsler på tværs af shards er dyre, resharding ved vækst er vanskeligt, og transaktioner på tværs af shards er komplekse. Men for meget store datasæt eller høj gennemstrømning er sharding ofte den eneste vej til skalering. Mange NoSQL-databaser som MongoDB og Cassandra har indbygget 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 horisontal skalering
  • Distribueret belastning og bedre ydeevne
  • Isolerede fejl (én shard nede != hele systemet nede)
  • Geografisk dataplacering for latenstid
  • Omkostningseffektivt (mange små servere vs. én kæmpe)

Udfordringer

  • Meget høj implementeringskompleksitet
  • Forespørgsler på tværs af shards er dyre og komplekse
  • Resharding ved vækst er svært
  • Ingen joins på tværs af shards
  • Distribuerede transaktioner er komplekse

Anvendelsesområder

  • Multi-tenant SaaS (shard per lejer)
  • Sociale medieplatforme (shard per region/brugerbucket)
  • E-handel med millioner af produkter
  • IoT-dataindsamling ved massiv skala
  • Gamingplatforme med millioner af spillere

Eksempler fra den virkelige verden

  • Instagram: Sharding af billeder og brugere (1000+ shards)
  • Uber: Geografibaseret sharding for turdata
  • Discord: Sharding af guilds/servere på brugerintervaller
  • Shopify: Shard per forhandler/butik
  • Twitter: Bruger-tidslinje sharding på bruger-ID