Storage Performance #

Storage performance adalah salah satu variabel yang paling sering diabaikan saat merancang workload Kubernetes, tapi dampaknya terasa langsung di level aplikasi — database yang lambat, API yang timeout, job yang tidak selesai tepat waktu. Perbedaan antara storage yang tepat dan yang salah bisa berarti perbedaan 10x dalam performa aplikasi. Artikel ini membahas metrik yang penting, cara mengukurnya, dan cara memilih storage yang sesuai dengan kebutuhan workload.

Tiga Metrik Storage yang Penting #

IOPS (Input/Output Operations Per Second):
  → Berapa banyak operasi baca/tulis bisa dilakukan per detik
  → Kritikal untuk workload dengan banyak operasi kecil-kecil
  → Contoh: database OLTP, Redis, Elasticsearch

Throughput (MB/s):
  → Berapa banyak data yang bisa ditransfer per detik
  → Kritikal untuk workload yang menulis/membaca data besar
  → Contoh: log aggregation, batch processing, media storage

Latensi (ms atau µs):
  → Berapa lama satu operasi baca/tulis diselesaikan
  → Kritikal untuk workload yang sensitif terhadap delay
  → Contoh: database dengan query kecil, cache layer

Ketiga metrik ini saling trade-off:
  Storage murah: IOPS rendah, throughput rendah, latensi tinggi
  SSD cloud:     IOPS tinggi, throughput menengah, latensi rendah
  NVMe lokal:    IOPS sangat tinggi, throughput tinggi, latensi sangat rendah

Profil Storage per Workload #

PostgreSQL / MySQL (database OLTP):
  Kebutuhan: IOPS tinggi, latensi rendah
  → Banyak operasi kecil (8-16KB per operasi)
  → Latensi fsync sangat penting untuk durability
  → Rekomendasi: gp3 dengan IOPS 3000-6000, atau io2 untuk workload besar

Redis (in-memory cache dengan persistence):
  Kebutuhan: Latensi sangat rendah, IOPS tinggi
  → RDB snapshot dan AOF log butuh IOPS burst
  → Rekomendasi: gp3, atau NVMe local storage jika latency kritikal

Elasticsearch / OpenSearch:
  Kebutuhan: Throughput tinggi, IOPS menengah
  → Index dan merge operation menulis data besar
  → Rekomendasi: gp3 dengan throughput 250-500 MB/s

Kafka (message broker):
  Kebutuhan: Throughput sangat tinggi, sequential write
  → Append-only log, sequential I/O pattern
  → Rekomendasi: throughput-optimized HDD (st1) untuk data lama,
                 gp3 untuk hot data

Batch processing / log archival:
  Kebutuhan: Throughput tinggi, IOPS tidak kritikal
  → Menulis file besar, sequential access pattern
  → Rekomendasi: cold HDD (sc1) untuk cost efficiency

Perbedaan Tipe Storage di AWS (Sebagai Referensi) #

gp3 (General Purpose SSD):
  Baseline IOPS: 3000 (tanpa biaya tambahan)
  Max IOPS:      16000 (berbayar)
  Throughput:    125 MB/s baseline, 1000 MB/s max
  Cocok untuk:   Sebagian besar workload produksi

io2 (Provisioned IOPS SSD):
  IOPS:          100 - 256000 (sesuai yang di-provision)
  Latensi:       sub-millisecond konsisten
  Cocok untuk:   Database kritikal yang butuh latensi konsisten

st1 (Throughput Optimized HDD):
  Max throughput: 500 MB/s
  Max IOPS:       500
  Cocok untuk:    Kafka, data warehouse, sequential workload besar

sc1 (Cold HDD):
  Max throughput: 250 MB/s
  Max IOPS:       250
  Cocok untuk:    Backup, arsip, akses jarang

Local Storage untuk Performa Maksimal #

Untuk workload yang sangat sensitif terhadap latensi storage, local persistent volume (disk yang dipasang langsung ke node) memberikan performa jauh lebih baik dari network-attached storage:

# StorageClass untuk local storage
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-nvme
provisioner: kubernetes.io/no-provisioner   # tidak ada dynamic provisioning
volumeBindingMode: WaitForFirstConsumer
# PV untuk local storage (harus dibuat manual)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv-worker1
spec:
  capacity:
    storage: 500Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-nvme
  local:
    path: /mnt/nvme0n1          # path ke disk lokal di node
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - worker-1            # disk ini hanya ada di worker-1

Trade-off local storage yang harus dipahami:

Keuntungan local storage:
  ✓ Latensi sangat rendah (sub-millisecond)
  ✓ IOPS tinggi (NVMe bisa mencapai jutaan IOPS)
  ✓ Tidak ada overhead network

Kerugian local storage:
  ✗ Data terikat ke satu node fisik
  ✗ Jika node mati, Pod tidak bisa dijadwalkan ulang (data tidak bisa follow)
  ✗ Tidak ada replikasi otomatis
  ✗ Butuh replikasi di level aplikasi (misalnya Kafka cluster, Cassandra)

Mengukur Performa Storage #

Sebelum memilih StorageClass dan tipe storage, ukur dulu apakah performa yang ada sudah cukup:

# Buat Pod untuk testing dengan fio (storage benchmark tool)
kubectl run storage-bench --image=nixery.dev/shell/fio --restart=Never \
  --overrides='
{
  "spec": {
    "containers": [{
      "name": "storage-bench",
      "image": "nixery.dev/shell/fio",
      "command": ["sleep", "infinity"],
      "volumeMounts": [{"name":"test","mountPath":"/test"}]
    }],
    "volumes": [{"name":"test","persistentVolumeClaim":{"claimName":"test-pvc"}}]
  }
}'

# Masuk ke Pod dan jalankan benchmark
kubectl exec -it storage-bench -- sh

# Test random read IOPS (simulasi database OLTP)
fio --name=randread \
    --ioengine=libaio \
    --iodepth=32 \
    --rw=randread \
    --bs=4k \
    --size=1G \
    --directory=/test \
    --output-format=json

# Test sequential write throughput (simulasi log/batch)
fio --name=seqwrite \
    --ioengine=libaio \
    --iodepth=1 \
    --rw=write \
    --bs=1M \
    --size=4G \
    --directory=/test

Pengaruh Network pada Storage Performance #

Untuk storage yang berbasis network (EBS, GCE PD, NFS), performa juga dipengaruhi oleh bandwidth dan latensi network antar node:

Faktor network yang mempengaruhi storage:

1. Instance/VM size → bandwidth EBS yang tersedia
   Contoh di AWS:
   t3.small: 1.5 Gbps EBS bandwidth → ~187 MB/s max
   m5.xlarge: 4.75 Gbps EBS bandwidth → ~590 MB/s max
   m5.8xlarge: 6.8 Gbps dedicated → max untuk gp3

2. Multi-Attach / RWX storage (NFS)
   → Tambahan latency karena network filesystem protocol
   → NFS bisa menambah 1-5ms latensi dibanding block storage
   → Gunakan RWX hanya jika benar-benar diperlukan

3. Cross-AZ I/O
   → Volume di AZ berbeda dari Pod menambah latensi network
   → Selalu gunakan WaitForFirstConsumer untuk menghindari ini

Ringkasan #

  • Tiga metrik utama: IOPS, throughput, latensi — database OLTP butuh IOPS dan latensi rendah; batch processing butuh throughput; pilih storage berdasarkan karakteristik workload.
  • Profil workload menentukan tipe storage — PostgreSQL butuh gp3 dengan IOPS provisioned; Kafka cocok dengan st1; backup dan arsip bisa pakai sc1 yang lebih murah.
  • Local storage untuk latensi minimum — NVMe lokal memberikan performa terbaik tapi data terikat ke satu node; butuh replikasi di level aplikasi.
  • Ukur dulu sebelum memilih — gunakan fio di dalam Pod dengan volume yang akan digunakan di produksi; jangan berasumsi performa dari spec saja.
  • Instance size membatasi bandwidth storage — di cloud, VM yang lebih kecil punya bandwidth EBS/PD yang lebih rendah; pastikan instance size cukup untuk kebutuhan I/O aplikasi.
  • Hindari cross-AZ I/OWaitForFirstConsumer di StorageClass memastikan PV di-provision di zone yang sama dengan Pod, menghindari latensi tambahan dari network cross-zone.

← Sebelumnya: Anti-Pattern Storage   Berikutnya: Kubernetes Network Model →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact