Database

Database Sharding dengan Vitess

Tutorial komprehensif Vitess — database clustering system untuk horizontal scaling MySQL. Pelajari VSchema, shards, reparenting, VTGate routing, resharding online, dan deployment production-grade

1. Pengenalan Vitess

Vitess adalah database clustering system open-source yang dikembangkan oleh YouTube (Google) untuk melakukan horizontal scaling pada MySQL. Vitess awalnya dibuat untuk menangani miliaran query per hari di YouTube, dan sekarang digunakan oleh Slack, Square, GitHub, dan banyak perusahaan besar lainnya.

Vitess memecahkan masalah fundamental MySQL: keterbatasan vertical scaling. Dengan Vitess, Anda bisa membagi (shard) database MySQL ke banyak server, sambil tetap menggunakan SQL standar. Vitess bertindak sebagai middleware antara aplikasi dan MySQL — menangani routing query, connection pooling, dan resharding secara transparan.

Arsitektur Vitess
📱
Application
MySQL client library
tanpa perubahan kode
→ MySQL Protocol →
🔀
VTGate
Query routing,
planning, aggregation
📊
VTTablet
MySQL proxy,
connection pooling
💾
MySQL
Per-shard MySQL
instances

1.1 Keunggulan Vitess

1.2 Vitess vs Alternatif

AspekVitessProxySQLMySQL Cluster
ShardingOtomatis, online reshardingManual routingAuto-partitioning
FailoverOtomatis reparentingPerlu tool tambahanBuilt-in
Online DDLYa (gh-ost integration)TidakTidak
ComplexitySedang-tinggiRendahTinggi
MySQL CompatibleYa (wire protocol)YaSebagian

2. Arsitektur Komponen

2.1 Komponen Utama

KomponenFungsiPort Default
VTGateQuery router — menerima SQL dari aplikasi, merutekan ke shard yang tepat15991 (MySQL), 15001 (gRPC)
VTTabletProxy untuk setiap MySQL instance — connection pooling, backup, replication15002 (gRPC)
VTctldControl plane — mengelola topology, shards, dan operasi cluster15000 (Web UI)
Topology ServicePenyimpanan metadata cluster (etcd, ZooKeeper, Consul)Bervariasi
VTOrcMonitoring dan automatic reparenting-

2.2 Keyspace & Shard

Di Vitess, database dikelompokkan dalam keyspace (analog dengan database logical). Setiap keyspace bisa dipecah menjadi beberapa shard. Setiap shard adalah MySQL instance terpisah yang menyimpan subset data.

💡 Unsharded vs Sharded Keyspace

Anda bisa mulai dengan unsharded keyspace (satu shard, semua data) dan melakukan resharding nanti ketika data sudah besar. Ini memungkinkan Anda memulai dengan Vitess tanpa langsung memikirkan sharding strategy.

3. Setup & Instalasi

Terminal — Setup Vitess Local
# Download Vitess binary
VERSION="19.0.0"
wget https://github.com/vitessio/vitess/releases/download/v${VERSION}/vitess-${VERSION}-linux-amd64.tar.gz
tar xzf vitess-${VERSION}-linux-amd64.tar.gz
export PATH="$(pwd)/vitess-${VERSION}/bin:$PATH"

# Verifikasi
vtgate --version
vtctldclient --version

# Setup dengan Docker (recomendado untuk testing)
docker pull vitess/lite:v19.0.0

# Atau menggunakan local examples
git clone https://github.com/vitessio/vitess.git
cd vitess/examples/local

# Mulai cluster 2-shard
./101_initial_cluster.sh

# Ini akan membuat:
# - etcd (topology service)
# - 2 shards (each with 1 primary + 1 replica)
# - vtgate (query router)
# - vtctld (control plane)

# Verifikasi cluster
vtctldclient GetTablets

# Koneksi ke vtgate (port 15991)
mysql -h 127.0.0.1 -P 15991 -u root

# Buat keyspace dan tabel
# (melalui vtgate, otomatis di-propagate ke semua shard)

3.1 Kubernetes Deployment

YAML — Vitess Operator for Kubernetes
# Install Vitess Operator
kubectl apply -f https://github.com/vitessio/vitess/releases/download/v19.0.0/operator.yaml

# VitessCluster CRD
# vitess-cluster.yaml
apiVersion: planetscale.com/v2
kind: VitessCluster
metadata:
  name: my-vitess
spec:
  images:
    vtctld: vitess/lite:v19.0.0
    vtgate: vitess/lite:v19.0.0
    vttablet: vitess/lite:v19.0.0
    vtorc: vitess/lite:v19.0.0
  cells:
    - name: zone1
  globalLockserver:
    external:
      etcd:
        hosts:
          - etcd-client:2379
  keyspaces:
    - name: myapp
      partitionings:
        - equal:
            parts: 2  # 2 shards
            shardTemplate:
              databaseInitScriptSecret:
                name: init-script
              tabletPools:
                - cell: zone1
                  type: replica
                  replicas: 2
                  mysqld: {}
                  dataVolumeClaimSpec:
                    accessModes: ["ReadWriteOnce"]
                    resources:
                      requests:
                        storage: 10Gi
  vitessDashboard:
    cells:
      - zone1

# Apply
kubectl apply -f vitess-cluster.yaml

4. VSchema — Virtual Schema

VSchema (Virtual Schema) adalah konfigurasi yang memberi tahu Vitess bagaimana data didistribusikan ke shard. VSchema mendefinisikan sharding key, vindex (virtual index), dan routing rules.

4.1 Sharding Key & Vindex

JSON — VSchema untuk Sharded Keyspace
{
  "sharded": true,
  "vindexes": {
    "hash_user_id": {
      "type": "hash"
    },
    "binary_md5_category": {
      "type": "binary_md5"
    },
    "lookup_email": {
      "type": "consistent_lookup",
      "params": {
        "table": "user_email_idx",
        "from": "email",
        "to": "user_id"
      },
      "owner": "users"
    }
  },
  "tables": {
    "users": {
      "column_vindexes": [
        {
          "column": "user_id",
          "name": "hash_user_id"
        },
        {
          "column": "email",
          "name": "lookup_email"
        }
      ],
      "auto_increment": {
        "column": "user_id",
        "column_sequence": "user_seq"
      }
    },
    "orders": {
      "column_vindexes": [
        {
          "column": "user_id",
          "name": "hash_user_id"
        }
      ]
    },
    "products": {
      "column_vindexes": [
        {
          "column": "category",
          "name": "binary_md5_category"
        }
      ]
    }
  }
}

4.2 Jenis Vindex

Vindex TypeFungsiCocok Untuk
hashDistribusi merata berdasarkan hashSharding key utama (user_id)
binary_md5Distribusi merata berdasarkan MD5String sharding key
consistent_lookupLookup table untuk kolom non-shardingUnique secondary index (email)
lookupNon-unique lookupMany-to-one mapping
numericDistribusi berdasarkan range numerikTime-based sharding
region_experimentalGeo-based shardingMulti-region deployment
SQL — Mengapply VSchema
# Apply VSchema menggunakan vtctldclient
vtctldclient ApplyVSchema --vschema-file vschema.json myapp

# Atau dari MySQL shell (vtgate)
mysql> SHOW VSCHEMA TABLES;
mysql> SHOW VSCHEMA VINDEXES;

# Membuat tabel melalui vtgate (otomatis di-propagate ke semua shard)
mysql -h 127.0.0.1 -P 15991 -u root myapp <<EOF
CREATE TABLE users (
    user_id BIGINT NOT NULL AUTO_INCREMENT,
    email VARCHAR(255) NOT NULL,
    name VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id),
    UNIQUE KEY idx_email (email)
) ENGINE=InnoDB;

CREATE TABLE orders (
    order_id BIGINT NOT NULL AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    total DECIMAL(10,2),
    status VARCHAR(20) DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (order_id),
    KEY idx_user_id (user_id)
) ENGINE=InnoDB;
EOF

# Vitess akan otomatis menjalankan DDL di semua shard
⚠️ Cross-Shard Queries

Query yang membutuhkan data dari multiple shard (cross-shard join) jauh lebih lambat dari single-shard query. Vitess akan mengirimkan query ke semua shard dan mengagregasi hasilnya. Pastikan query utama Anda bisa di-route ke satu shard berdasarkan sharding key.

5. VTGate — Query Routing

VTGate adalah komponen yang menerima koneksi MySQL dari aplikasi dan merutekan query ke shard yang tepat. VTGate mendukung hampir semua sintaks MySQL dan bisa mengoptimalkan query untuk sharded environment.

SQL — Query Routing di Vitess
-- Single-shard query (SANGAT DIREKOMENDASIKAN)
-- user_id = 1234 di-hash dan di-route ke shard yang tepat
SELECT * FROM users WHERE user_id = 1234;

-- Query dengan sharding key
SELECT * FROM orders WHERE user_id = 1234;
-- Route ke shard yang sama karena user_id adalah sharding key

-- Cross-shard query (Vitess kirim ke SEMUA shard lalu aggregate)
SELECT COUNT(*) FROM users;
-- Mengirim COUNT(*) ke semua shard, lalu sum hasilnya

-- Cross-shard join (lambat!)
SELECT u.name, o.total
FROM users u JOIN orders o ON u.id = o.user_id
WHERE u.user_id = 1234;
-- Route ke satu shard (karena ada filter user_id)

-- TANPA filter sharding key:
SELECT u.name, o.total
FROM users u JOIN orders o ON u.id = o.user_id;
-- SCATTER query: dikirim ke semua shard (LEMBAT!)

-- Transaction dalam satu shard
BEGIN;
UPDATE users SET name = 'Budi Updated' WHERE user_id = 1234;
UPDATE orders SET status = 'completed' WHERE user_id = 1234 AND order_id = 5678;
COMMIT;

-- Cross-shard transaction (2PC, lebih lambat)
BEGIN;
UPDATE users SET name = 'Budi' WHERE user_id = 1234;
UPDATE orders SET status = 'completed' WHERE user_id = 9999 AND order_id = 5678;
COMMIT;

5.1 Query Planner yang Didukung

SQL — EXPLAIN di Vitess
-- Vitess mendukung EXPLAIN untuk melihat query routing
EXPLAIN SELECT * FROM users WHERE user_id = 1234;

-- Output akan menunjukkan:
-- 1. Apakah query single-shard atau scatter
-- 2. Shard mana yang dituju
-- 3. Estimasi rows

-- Membatasi query berbahaya
-- Vitess otomatis membatasi:
-- - FULL SCAN tanpa LIMIT
-- - CROSS JOIN yang sangat besar
-- - Query yang terlalu lama (query timeout)

6. Reparenting & High Availability

Reparenting adalah proses mengubah replica menjadi primary saat primary node mati. Vitess mendukung reparenting otomatis (via VTOrc) dan manual (via PlannedReparentTablet).

Terminal — Reparenting Operations
# Melihat tablet status
vtctldclient GetTablets --keyspace myapp --shard "0"

# Planned Reparenting (graceful, zero downtime)
# Saat maintenance window
vtctldclient PlannedReparentShard myapp/0 --new-primary zone1-100

# Emergency Reparenting (primary sudah mati)
vtctldclient EmergencyReparentShard myapp/0 --new-primary zone1-200

# VTOrc: automatic failover
# VTOrc terus memantau kesehatan primary
# Jika primary mati > threshold, otomatis reparent ke replica terbaik

# Konfigurasi VTOrc
# --prevent-cross-cell-failover=true
# --wait-replicas-timeout=30s
# --topo-global-server-address=etcd:2379

# Monitoring replication lag
vtctldclient GetReplicationStatus zone1-100
💡 VTOrc vs Orchestrator

VTOrc adalah Vitess-native tool untuk automatic failover (menggantikan Orchestrator). VTOrc lebih terintegrasi dengan topology service dan melakukan reparenting yang lebih aman karena aware terhadap VSchema dan shard routing.

7. Online Resharding

Online resharding adalah fitur killer Vitess — Anda bisa memecah (split) atau menggabungkan (merge) shard tanpa downtime aplikasi. Proses ini berjalan secara background, dan Vitess menangani routing perubahan secara otomatis.

Terminal — Resharding dari 2 ke 4 Shards
# Saat ini: 2 shards (00-80, 80-FF)
# Target: 4 shards (00-40, 40-80, 80-C0, C0-FF)

# Step 1: Buat shard baru
vtctldclient CreateKeyspace --keyspace-type=SHARDED myapp
vtctldclient CreateShard myapp "00-40"
vtctldclient CreateShard myapp "40-80"
vtctldclient CreateShard myapp "80-C0"
vtctldclient CreateShard myapp "C0-FF"

# Step 2: Copy data dari shard lama ke shard baru (vtworker)
# (Automated via Reshard command)
vtctldclient Reshard --source-shards="0" --target-shards="-40,40-80,80-c0,c0-" myapp

# Step 3: Verify data konsisten
vtctldclient VDiff myapp myapp

# Step 4: Cutover (switch traffic ke shard baru)
# Vitess akan meng-update routing rules secara atomik
vtctldclient SwitchTraffic --tablet-type=replica myapp "0"
vtctldclient SwitchTraffic --tablet-type=primary myapp "0"

# Step 5: Cleanup shard lama (setelah yakin)
vtctldclient DeleteShard myapp "00-80"

# Monitoring selama resharding
vtctldclient Workflow --keyspace myapp list

7.1 Merge Shards (Penggabungan)

Terminal — Merge 4 Shards ke 2
# Merge 4 shards ke 2 shards
# Dari: 00-40, 40-80, 80-C0, C0-FF
# Ke: 00-80, 80-FF

# Prosesnya sama seperti split, tapi terbalik:
vtctldclient Reshard --source-shards="-40,40-80,80-c0,c0-" --target-shards="0,80-" myapp
vtctldclient VDiff myapp myapp
vtctldclient SwitchTraffic --tablet-type=primary myapp "-40,40-80,80-c0,c0-"
vtctldclient DeleteShard myapp "00-40"
vtctldclient DeleteShard myapp "40-80"
vtctldclient DeleteShard myapp "80-C0"
vtctldclient DeleteShard myapp "C0-FF"

8. Best Practices & Monitoring

8.1 Sharding Key Selection

CriteriaRekomendasi
Distribusi merataPilih kolom dengan cardinality tinggi (user_id, order_id)
Akses patternSharding key harus ada di WHERE clause query utama
Data co-locationRelasi yang sering di-join harus di shard yang sama (sama sharding key)
Tidak berubahHindari kolom yang sering di-update sebagai sharding key
Tidak monotonikHindari auto-increment (tidak merata). Gunakan hash

8.2 Monitoring

Terminal — Monitoring Vitess
# Status semua tablet
vtctldclient GetTablets

# Replication lag per shard
vtctldclient GetReplicationStatus zone1-100

# Vitess Dashboard (vtctld web UI)
# http://localhost:15000

# Metrics endpoint (Prometheus format)
curl http://localhost:15002/metrics  # vtctld
curl http://localhost:15991/debug/vars  # vtgate

# Key metrics:
# - vtgate_*: query routing stats, error rates, latencies
# - vttablet_*: replication lag, query times, tablet state
# - MySQL metrics: connections, buffer pool hit rate

# Grafana dashboard
# Vitess menyediakan Grafana dashboard template di:
# https://github.com/vitessio/vitess/tree/main/tools/monitoring

8.3 Checklist Production

9. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut:

Pertanyaan 1: Apa fungsi utama VTGate di Vitess?

a) Menyimpan data MySQL
b) Merutekan query dari aplikasi ke shard yang tepat
c) Mengelola backup database
d) Monitoring replication lag

Pertanyaan 2: Apa itu VSchema?

a) Virtual database yang menyimpan cache
b) Konfigurasi yang mendefinisikan bagaimana data didistribusikan ke shard
c) Schema untuk NoSQL database
d) Template untuk membuat tabel baru

Pertanyaan 3: Mengapa cross-shard queries lebih lambat?

a) Karena data terenkripsi
b) Karena query dikirim ke semua shard dan hasilnya diagregasi
c) Karena Vitess memblokir cross-shard queries
d) Karena MySQL tidak mendukung cross-shard

Pertanyaan 4: Apa itu reparenting di Vitess?

a) Mengubah parent-child relationship dalam tabel
b) Mengubah replica menjadi primary saat primary mati atau untuk maintenance
c) Menambah shard baru
d) Menggabungkan beberapa shard

Pertanyaan 5: Apa keunggulan utama online resharding di Vitess?

a) Menghapus shard lama secara otomatis
b) Bisa menambah atau mengurangi shard tanpa downtime aplikasi
c) Mengkompresi data otomatis
d) Mengubah MySQL ke PostgreSQL
← Sebelumnya Supabase Realtime Features Selanjutnya → CockroachDB: Distributed SQL
🔍 Zoom
100%
🎨 Tema