# Optimasi Redis Cluster untuk High-Throughput Caching di E-Commerce

> Diterbitkan oleh Literally Web ID pada 21 Oct 2026
> Sumber: https://literally.web.id/articles/optimasi-redis-cluster-untuk-high-throughput-caching-di-e-commerce

---

Pukul 2 pagi, alarm PagerDuty berteriak nyaring di Slack. Dashboard Grafana memerah pekat: database utama MySQL kami di-tier e-commerce mendadak megap-megap dengan CPU usage menyentuh 98% akibat flash sale kilat yang memicu 50.000 request per detik. Saat itu, perdebatan sengit langsung pecah di ruang perang virtual kami: apakah kita harus habis-habisan menerapkan pola **Cache Aside Pattern** yang fleksibel di level aplikasi PHP/Go kita, atau langsung mengandalkan **Write Through** demi menjamin konsistensi data secara instan di Redis Cluster?

Pertarungan ini bukan sekadar teori akademis di buku teks, melainkan soal hidup-mati infrastruktur web kita yang berjalan di atas Nginx, PHP-FPM, dan diproteksi Cloudflare di edge. Mari kita bedah performa kedua pendekatan ini secara head-to-head di arena uji beban nyata.

| Metrik Perbandingan | Cache Aside Pattern | Write Through | Redis Cluster Sharding | Mencegah Stampede (Mutex) |
| :--- | :--- | :--- | :--- | :--- |
| Kecepatan Baca (Read) | 9 / 10 | 8 / 10 | 10 / 10 | 8 / 10 |
| Latency Konsisten | 8 / 10 | 6 / 10 | 9 / 10 | 7 / 10 |
| Efisiensi RAM | 9 / 10 | 5 / 10 | 8 / 10 | 9 / 10 |
| Kemudahan Setup | 8 / 10 | 4 / 10 | 6 / 10 | 7 / 10 |
| Skalabilitas Ekosistem | 9 / 10 | 6 / 10 | 10 / 10 | 9 / 10 |

## 1. Pertarungan Filosofi: Dua Cara Pandang Berbeda dalam Memecahkan Masalah

Bayangkan Anda sedang mengelola antrean kasir di sebuah pusat perbelanjaan raksasa saat diskon 12.12. **Cache Aside Pattern** memperlakukan Redis sebagai gudang cadangan terpisah yang dikontrol penuh oleh aplikasi backend (Node.js, Go, atau PHP). Aplikasi Anda mengecek Redis dulu; kalau kosong (*cache miss*), baru aplikasi mengambil data ke MySQL, lalu menyimpannya kembali ke Redis. Filosofinya: *"Biar aplikasi yang berpikir dan bertanggung jawab penuh atas apa yang masuk dan keluar."*

Sebaliknya, pendekatan **Write Through** memaksa setiap kali ada data produk atau stok yang diubah di database, sistem langsung menulisnya secara serentak ke Redis dan MySQL dalam satu transaksi tunggal. Filosofinya: *"Jangan pernah biarkan ada celah data basi (stale data), sinkronisasi mutlak harus terjadi detik itu juga."*

> [!IMPORTANT]
> Dalam ekosistem high-throughput e-commerce, memilih filosofi yang salah berarti mengundang bencana *Connection Timeout* pada PHP-FPM atau Nginx upstream Anda ketika traffic melonjak tajam.

Transisi mulus dari filosofi di atas membawa kita langsung ke meja kerja, tempat di mana barisan kode ditulis dan konfigurasi diuji di bawah tekanan deadline.

## 2. Ronde 1: Ergonomi Menulis Kode & Pengalaman Konfigurasi Sehari-hari

Menulis kode untuk **Cache Aside Pattern** terasa sangat intuitif bagi backend engineer. Anda bisa mengimplementasikannya dengan mudah di dalam worker Go atau script PHP modern Anda. Berikut adalah cuplikan pola Cache Aside yang dipadukan dengan pencegahan *Cache Stampede* menggunakan teknik Mutex (Distributed Lock):

```go
package main

import (
    "context"
    "database/sql"
    "encoding/json"
    "fmt"
    "github.com/go-redis/redis/v8"
    "time"
)

var ctx = context.Background()

func GetProductData(rdb *redis.ClusterClient, db *sql.DB, productID string) (map[string]interface{}, error) {
    cacheKey := fmt.Sprintf("product:%s", productID);
    lockKey := fmt.Sprintf("lock:%s", productID);

    // 1. Coba ambil dari Redis Cluster
    val, err := rdb.Get(ctx, cacheKey).Result();
    if err == nil {
        var data map[string]interface{};
        json.Unmarshal([]byte(val), &data);
        return data, nil;
    }

    // 2. Cache Miss: Gunakan Distributed Mutex untuk cegah Cache Stampede
    lockAcquired, err := rdb.SetNX(ctx, lockKey, "locked", 5*time.Second).Result();
    if err != nil || !lockAcquired {
        // Jika gagal dapat lock, tunggu sebentar lalu coba baca cache lagi
        time.Sleep(50 * time.Millisecond);
        return GetProductData(rdb, db, productID);
    }

    defer rdb.Del(ctx, lockKey);

    // 3. Ambil dari MySQL Database Utama
    var name string;
    var price float64;
    err = db.QueryRow("SELECT name, price FROM products WHERE id = ?", productID).Scan(&name, &price);
    if err != nil {
        return nil, err;
    }

    result := map[string]interface{}{"id": productID, "name": name, "price": price};
    byteData, _ := json.Marshal(result);

    // 4. Set ke Redis dengan TTL acak untuk menghindari thundering herd
    rdb.Set(ctx, cacheKey, byteData, 10*time.Minute);

    return result, nil;
}
```

Sebaliknya, mengonfigurasi **Write Through** menuntut kedisiplinan tingkat tinggi di layer ORM atau database triggers. Jika salah satu koneksi Redis di cluster mengalami *network partition*, seluruh proses *checkout* keranjang belanja bisa macet total karena aplikasi menunggu balasan dari Redis yang tak kunjung datang. Pengalaman debugging Write Through sering kali memakan waktu berjam-jam karena melibatkan pelacakan transaksi ganda antara MySQL dan Redis.

Perbedaan ergonomi ini baru permulaan; mari kita lihat bagaimana kedua pendekatan ini bertahan saat digempur beban ekstrem di arena pengujian.

## 3. Ronde 2: Uji Ketahanan di Bawah Gempuran Beban Ekstrem

Kami melakukan simulasi uji beban menggunakan `k6` dengan skenario 20.000 virtual users (VUs) mengakses halaman detail produk secara simultan selama 10 menit. 

Pada kubu **Cache Aside Pattern** dengan implementasi *Mutex*, grafik latensi memperlihatkan kestabilan yang luar biasa. P99 latency berhasil dijaga di bawah 12 milidetik. Ketika ribuan request secara bersamaan menembak produk yang sedang viral, hanya satu thread yang diizinkan menembus MySQL berkat mekanisme `SetNX` Redis, sementara thread lainnya menunggu dengan elegan atau langsung mengambil data begitu cache terisi.

Sebaliknya, pada uji coba **Write Through tanpa sharding yang matang**, CPU pada node Redis utama langsung melompat ke 100%. Mengapa? Karena setiap kali ada pembaruan stok kecil (misal: tombol 'like' atau perubahan status flash sale), Redis dipaksa menulis ulang data secara sinkronus, memicu *write amplification* yang parah pada cluster.

> [!WARNING]
> Jangan pernah mengabaikan konfigurasi `maxmemory-policy` pada Redis Cluster Anda. Tanpa kebijakan *eviction* yang tepat seperti `volatile-lru` atau `allkeys-lru`, Redis akan memuntahkan error `OOM command not allowed when used memory > 'maxmemory'` tepat di tengah-tengah transaksi flash sale yang sedang memuncak.

Ketahanan di bawah beban ekstrem ini langsung berkorelasi dengan seberapa efisien infrastruktur Anda menyedot daya listrik dan kapasitas RAM server.

## 4. Ronde 3: Konsumsi Sumber Daya Server & Efisiensi Biaya Nyata

Dari sudut pandang kapasitas RAM dan utilisasi server, **Cache Aside** terbukti jauh lebih hemat biaya. Kita bisa dengan leluasa menentukan kapan sebuah data layak masuk ke cache (lazy loading), sehingga memori RAM Redis seluas 64GB yang kita sewa di cloud hanya terisi oleh data produk yang benar-benar aktif dibeli pengunjung.

Sementara itu, **Write Through** memaksa semua data masuk ke dalam memori Redis seketika ia diciptakan di database, terlepas dari apakah produk tersebut dilihat orang atau tidak. Akibatnya, memori Redis membengkak hingga 3x lipat, memaksa tim DevOps kami segera melakukan *vertical scaling* dan menambah biaya infrastruktur bulanan secara signifikan.

Efisiensi ini menuntun kita pada garis batas penentuan keputusan arsitektural yang harus diambil tanpa keraguan.

## 5. Kapan Wajib Menggunakan Cache Aside Pattern

Anda wajib memilih **Cache Aside Pattern** jika aplikasi e-commerce Anda memiliki karakteristik berikut:
- Rasio pembacaan (read-heavy) jauh lebih besar dibanding penulisan (misalnya katalog produk, review, dan profil pengguna dengan rasio 95:5).
- Skala traffic bersifat fluktuatif tajam, di mana Anda membutuhkan fleksibilitas penuh di sisi aplikasi (Go/Node/PHP) untuk mengatur strategi *fallback* jika Redis mengalami kendala.
- Anda ingin menghemat anggaran operasional cloud dengan hanya menyimpan data terpanas (*hot data*) di dalam memori RAM Redis.

## 6. Kapan Wajib Menggunakan Write Through

Di sisi lain, Anda boleh melirik **Write Through** (atau variasinya *Write Behind* dengan hati-hati) apabila:
- Sistem Anda menangani pencatatan saldo dompet digital (*digital wallet*), ledger keuangan, atau inventaris stok terbatas yang tidak boleh mengalami selisih satu angka pun antara database dan cache.
- Kepatuhan audit finansial menuntut konsistensi data yang mutlak secara *real-time* tanpa toleransi adanya data basi sesDetik pun.
- Arsitektur backend Anda sudah terintegrasi dengan event-driven broker seperti Kafka yang memastikan urutan penulisan data terjamin rapi.

## 7. Keputusan Akhir: Rekomendasi Jujur untuk Tim Engineering

Sebagai arsitek yang pernah jatuh bangun di berbagai insiden dini hari, keputusan jujur saya untuk sistem high-throughput e-commerce modern adalah: **Gunakan Cache Aside Pattern yang dikombinasikan dengan Redis Cluster sharding dan Distributed Mutex untuk pencegahan Cache Stampede.**

Write Through terlalu kaku dan membebani resource Redis secara tidak efisien untuk mayoritas fitur e-commerce komersial. Dengan Cache Aside, Anda memegang kendali penuh kapan data harus disegarkan, bagaimana TTL diatur secara acak untuk menghindari *thundering herd*, dan bagaimana menjaga agar database MySQL utama Anda tetap bernapas lega meskipun jutaan mata pengunjung sedang menyerbu toko online Anda.