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
fiodi 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/O —
WaitForFirstConsumerdi 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 →