← Semua pembelajaran / Laravel Nol → Enterprise
Fase 9 · Deploy di AWS

Aurora & RDS

Aurora memisahkan compute dari storage, sehingga menambah replica baca menjadi operasi menit, bukan jam. Untuk beban yang didominasi baca, itu pengungkit besar — asal kamu paham konsekuensi konsistensinya.

Intisari

  • Satu writer, sampai 15 reader, berbagi satu lapisan penyimpanan.
  • Ada dua endpoint: writer dan reader. Laravel bisa memakai keduanya lewat konfigurasi read/write.
  • Replication lag biasanya di bawah 100 ms, tapi tidak nol — dan itu terasa di tempat yang tidak terduga.
  • Failover otomatis; aplikasi harus tahan terhadap koneksi yang putus sesaat.
  • Batas koneksi bergantung ukuran instans — worker mode mengurangi tekanan koneksi, bukan menambahnya.

Bentuk klaster

Aurora Cluster
├── Writer instance      → portal.cluster-abc.ap-southeast-1.rds.amazonaws.com
├── Reader instance 1  ┐
├── Reader instance 2  ├→ portal.cluster-ro-abc.ap-southeast-1.rds.amazonaws.com
└── Reader instance 3  ┘   (endpoint reader menyeimbangkan di antara ketiganya)
        │
        └── satu lapisan penyimpanan bersama, direplikasi ke 3 AZ

Konfigurasi Laravel

// config/database.php
'mysql' => [
    'driver' => 'mysql',

    'read'  => ['host' => [env('DB_HOST_READ')]],
    'write' => ['host' => [env('DB_HOST')]],
    'sticky' => true,

    'database' => env('DB_DATABASE'),
    'username' => env('DB_USERNAME'),
    'password' => env('DB_PASSWORD'),
    'charset'  => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'strict'   => true,

    'options' => [
        PDO::ATTR_TIMEOUT => 5,
    ],
],
QueryDiarahkan ke
SELECTEndpoint reader
INSERT, UPDATE, DELETEWriter
Di dalam transaksiWriter, seluruhnya
SELECT setelah menulis (dengan sticky)Writer, untuk sisa permintaan itu

Replication lag, dan di mana ia menggigit

SituasiMasalahPerbaikan
Simpan lalu redirect ke halaman detailsticky mengurusnya — masih satu permintaan—
Simpan lalu kirim job antreanWorker adalah proses lain; bisa membaca reader yang belum ter-update->afterCommit(), tunda beberapa detik, atau kirim datanya
Webhook masuk tepat setelah kita menulisPermintaan berbeda, tanpa stickyBaca dari writer untuk jalur ini
Dua tab pengguna yang samaSatu melihat data lamaBiasanya bisa diterima
// Paksa satu query membaca dari writer
$artikel = Artikel::on('mysql::write')->find($id);

// Untuk job yang baru saja dibuat setelah penulisan
BuatRingkasan::dispatch($artikel->id)->afterCommit()->delay(now()->addSeconds(5));

Bug "job gagal karena barisnya tidak ditemukan" hampir selalu ini penyebabnya. Kamu membuat baris, mengirim job, worker menjalankannya 200 ms kemudian, dan membacanya dari reader yang belum menerima replikasinya. afterCommit() menyelesaikan setengah masalah — memastikan transaksi sudah commit. Sisanya diselesaikan dengan penundaan singkat, atau dengan membaca dari writer di dalam job.

Memilih bentuk klaster

PilihanKapan
Aurora Serverless v2Lalu lintas tidak merata; kapasitas naik-turun otomatis
Aurora provisionedBeban stabil; lebih murah untuk kapasitas yang selalu terpakai
RDS MySQL biasaLebih murah untuk aplikasi kecil; replica lebih lambat dibuat
Aurora + reader di AZ berbedaWajib untuk produksi — failover butuh ini

Koneksi

ModelKoneksi yang dibuka
PHP-FPM, 50 proses × 4 kontainerSampai 200 — dibuka dan ditutup terus-menerus
Worker mode, 8 worker × 4 kontainer32, dipakai ulang
Lambda, 500 pemanggilan bersamaanSampai 500 — perlu RDS Proxy

Ini keuntungan worker mode yang jarang disebut. Koneksi database mahal untuk dibuat, dan setiap proses PHP-FPM membukanya sendiri untuk setiap permintaan. Worker mode membuka satu koneksi per worker dan memakainya berulang — tekanan ke database berkurang, dan latensi per query pun turun karena tidak ada handshake di setiap permintaan.

Failover

1. Writer gagal
2. Aurora mempromosikan salah satu reader (biasanya 30–60 detik)
3. Endpoint writer diarahkan ke instans baru lewat DNS
4. Koneksi lama menjadi tidak valid
// Job antrean sebaiknya tahan terhadap koneksi yang putus
public function handle(): void
{
    retry(3, function () {
        DB::reconnect();
        // ...
    }, 1000);
}

Cache DNS bisa memperpanjang gangguan. Setelah failover, endpoint writer menunjuk ke IP baru. Kalau proses PHP-mu masih menyimpan hasil resolusi lama, ia akan terus mencoba menghubungi instans yang sudah tidak jadi writer. Di worker mode ini lebih terasa karena prosesnya berumur panjang — pastikan koneksi yang gagal benar-benar dibangun ulang, bukan diulang di atas soket yang sudah mati.

Yang harus dipantau

MetrikAlarm saat
CPUUtilization> 70% berkelanjutan
DatabaseConnections> 80% dari batas
AuroraReplicaLag> 1 detik
FreeableMemoryTurun terus
DeadlocksBukan nol
Performance InsightsQuery teratas berubah tiba-tiba

Nyalakan Performance Insights sejak hari pertama. Ia gratis untuk retensi tujuh hari dan menjawab pertanyaan yang paling sering muncul saat insiden: query mana yang sedang menghabiskan waktu database, tepat pada menit itu. Tanpa itu, kamu hanya melihat "CPU tinggi" tanpa tahu penyebabnya.

Latihan: konfigurasikan koneksi read/write terpisah, lalu tulis satu baris dan segera baca dari job antrean tanpa penundaan. Reproduksi kegagalannya, lalu perbaiki dengan afterCommit() plus penundaan singkat.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.