Database Sharding

แบ่ง data ไปหลาย DB instances (คนละ server) — ระดับถัดไปจาก Database Partitioning ที่แบ่งใน DB เดียว

Database PartitioningSharding
ขอบเขต1 DB instanceหลาย DB instances
เห็นจาก app1 ตารางหลาย databases — app ต้องรู้ว่า query ไป server ไหน

Consistent Hashing

ใช้ hash function บน sharding key (เช่น user_id) → ผลลัพธ์ → modulo จำนวน shards → ได้ shard target

shard_id = hash(user_id) % num_shards

Pitfall: ใช้ hash % N ตรง ๆ → เพิ่ม shard ใหม่ → N เปลี่ยน → key ส่วนใหญ่ rehash ใหม่หมด!
ทางแก้: Consistent Hashing แบบ ring (Cassandra, DynamoDB ใช้) — เพิ่ม shard rehash แค่ส่วนน้อย

Pros

  • Scalability: data + memory + CPU กระจายไปหลาย server
  • Security: user ถูกจำกัดให้เห็นแค่ shard ของตัวเอง (multi-tenant)
  • Index ขนาดเล็ก: แต่ละ shard มี index ของตัวเอง → fit memory → query เร็ว

Cons (และเป็นเรื่องใหญ่!)

  • Complex client — app ต้องรู้ logic ของ sharding
  • Cross-shard transactions ยาก — ต้อง 2-phase commit หรือ Saga pattern
  • Rollback ข้าม shard — shard 1 commit แต่ shard 2 fail → จัดการยาก
  • Schema changes — ต้อง migrate ทุก shard พร้อมกัน
  • Joins ข้าม shard — แทบทำไม่ได้ → app ต้อง fetch แล้ว join เอง
  • ต้องมี sharding key ใน query — ไม่มี key → scatter-gather ทุก shard

Demo: Sharding ด้วย Postgres 3 instances

docker run -d --name pg1 -e POSTGRES_PASSWORD=pw -p 5432:5432 postgres
docker run -d --name pg2 -e POSTGRES_PASSWORD=pw -p 5433:5432 postgres
docker run -d --name pg3 -e POSTGRES_PASSWORD=pw -p 5434:5432 postgres
import hashlib
def get_shard(key):
    h = int(hashlib.md5(key.encode()).hexdigest(), 16)
    return h % 3  # 0, 1, 2 → ports 5432, 5433, 5434

Modern Alternatives

  • Vitess — สำหรับ MySQL, sharding layer ที่ app มอง 1 logical table
  • Citus — extension สำหรับ PostgreSQL, distributed sharding
  • CockroachDB — distributed SQL ที่จัดการ sharding ให้อัตโนมัติ

Pitfall ใหญ่สุด

Shard ก่อนวัด — ส่วนใหญ่ DB เดียวพอ → sharding เพิ่มความซับซ้อนมหาศาลโดยไม่จำเป็น

Rule of thumb: ถ้ายัง vertical scale ได้ (instance ใหญ่กว่า + read replicas) → ยังไม่ต้อง shard

Key Points

  • Sharding = แบ่ง data ไปคนละ server — ต่างจาก partitioning ที่อยู่ DB เดียว
  • Consistent Hashing แบบ ring ป้องกันการ rehash ทั้งหมดเมื่อเพิ่ม shard
  • Cross-shard transactions/joins ยากมาก — ข้อเสียหลัก
  • อย่า shard ก่อนเวลา — vertical scale + replicas ก่อน
  • Modern tools (Vitess, Citus, CockroachDB) ช่วยซ่อนความซับซ้อน