Memahami object storage (S3/R2/GCS), CDN edge caching, consistent hashing untuk distribusi data, dan desain sistem upload gambar dari client ke presigned URL lalu ke CDN edge untuk serving global

Setelah di episode 7 kita memahami API design untuk komunikasi antar services, pada episode ini kita masuk ke komponen yang menangani data non-relasional: file, gambar, video, dan aset digital. Di era konten digital, sebagian besar data yang dihasilkan sistem bukan text di database — melainkan file di object storage yang dilayani ke jutaan pengguna melalui CDN.
Memahami storage dan CDN bukan lagi optional untuk system designer. Setiap aplikasi modern — dari e-commerce (gambar produk) sampai social media (video) — membutuhkan arsitektur storage yang scalable, cost-effective, dan globally available.
Object storage (AWS S3, Cloudflare R2, Google Cloud Storage) adalah layanan untuk menyimpan file sebagai objects dalam buckets.
| Konsep | Penjelasan |
|---|---|
| Bucket | Container untuk objects (satu bucket = satu namespace global) |
| Object | File + metadata + unique key |
| Key | Path unik dalam bucket (images/2026/08/photo.jpg) |
| Durability | 99.999999999% (11 nines) untuk S3 |
| Availability | 99.99% (S3 Standard) |
Otomatis memindahkan objects berdasarkan usia:
Day 0-30: S3 Standard (频繁访问)
Day 30-90: S3 Standard-IA (infrequent access)
Day 90-365: S3 Glacier Instant Retrieval
Day 365+: S3 Glacier Deep ArchiveDampaknya: storage cost turun 60-80% tanpa perubahan kode.
Cara upload langsung dari client ke S3 tanpa melalui server — mengurangi beban server dan mempercepat upload.
1. Client minta presigned URL ke server
2. Server generate URL dengan signature dan expiry
3. Client upload langsung ke S3 menggunakan presigned URL
4. S3 return success → client notify serveraws s3 presign s3://my-bucket/photo.jpg --expires-in 3600Aktifkan versioning untuk melindungi dari accidental deletion:
DELETE photo.jpg → S3 tidak benar-benar hapus, tapi tambahkan delete marker
→ Version sebelumnya masih bisa di-recoverCDN menyimpan copy konten di server edge yang dekat secara geografis dengan pengguna.
| Metode | Cara Kerja | Kelebihan | Kekurangan |
|---|---|---|---|
| Pull | CDN ambil dari origin saat cache miss | Simple, otomatis | Cold request lambat |
| Push | Developer push konten ke CDN | Kontrol penuh, no cold miss | Lebih banyak effort |
Kontrol kapan cache di-edge dihapus:
# Versioned URL (recommended)
/style.v1.css → v2.css (rename saat update)
# API invalidation
cf.purgeCache({ files: ['/images/photo.jpg'] })
# TTL-based
Cache-Control: max-age=86400 (cache 1 hari)Bagaimana CDN membedakan cached response:
Default: URL path + query string
/custom?width=800 → berbeda dari /custom?width=400
Custom cache key:
- Ignore query string tertentu (utm_source, fbclid)
- Vary by Accept-Encoding (gzip vs brotli)
- Vary by device type (mobile vs desktop)Consistent hashing adalah teknik untuk distribusi data ke node tanpa repartitioning besar saat node ditambah/dihapus.
hash(key) % N → N berubah (tambah/hapus node) → SEMUA key harus dipindah!Node dan key di-map ke lingkaran 0-360°
Key ditugaskan ke node terdekat searah jarum jam
Node A (0°) → Node B (120°) → Node C (240°)
Key "user:1" di 45° → Node B (terdekat clockwise)Saat Node B dihapus, hanya key yang ditugaskan ke Node B yang berpindah ke Node C — key lain tetap di tempat.
Untuk distribusi lebih merata, setiap physical node punya beberapa virtual nodes di ring:
Node A: A-1 (10°), A-2 (130°), A-3 (250°)
Node B: B-1 (40°), B-2 (160°), B-3 (280°)
→ Distribusi lebih merata, load balancing lebih baikDigunakan di: Cassandra (virtual nodes), DynamoDB, memcached (ketama consistent hashing).
1. Client → API: POST /upload-url (filename, content-type)
2. API → S3: generate presigned PUT URL (expiry 5 menit)
3. API → Client: return presigned URL
4. Client → S3: PUT file ke presigned URL (direct upload)
5. S3 → Client: 200 OK (upload berhasil)
6. Client → API: POST /upload-complete (file key, metadata)
7. API → Database: save file metadata
8. API → CDN: invalidate cache pathAlur ini memastikan:
Note
Presigned URL expiry harus cukup lama untuk upload (5-10 menit) tapi cukup pendek untuk keamanan. Selalu set Content-Type dan Content-Length validation di bucket policy untuk mencegah abuse.
Inti yang harus dibawa pulang:
Di episode 9 selanjutnya kita akan membahas full-text search: Elasticsearch — inverted index, scoring BM25, arsitektur cluster/shard/replica, dan praktik setup Elasticsearch untuk product search. Search adalah fitur yang sering di-underestimate tapi krusial untuk user experience!