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,
],
],
| Query | Diarahkan ke |
|---|---|
SELECT | Endpoint reader |
INSERT, UPDATE, DELETE | Writer |
| Di dalam transaksi | Writer, seluruhnya |
SELECT setelah menulis (dengan sticky) | Writer, untuk sisa permintaan itu |
Replication lag, dan di mana ia menggigit
| Situasi | Masalah | Perbaikan |
|---|---|---|
| Simpan lalu redirect ke halaman detail | sticky mengurusnya — masih satu permintaan | — |
| Simpan lalu kirim job antrean | Worker adalah proses lain; bisa membaca reader yang belum ter-update | ->afterCommit(), tunda beberapa detik, atau kirim datanya |
| Webhook masuk tepat setelah kita menulis | Permintaan berbeda, tanpa sticky | Baca dari writer untuk jalur ini |
| Dua tab pengguna yang sama | Satu melihat data lama | Biasanya 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
| Pilihan | Kapan |
|---|---|
| Aurora Serverless v2 | Lalu lintas tidak merata; kapasitas naik-turun otomatis |
| Aurora provisioned | Beban stabil; lebih murah untuk kapasitas yang selalu terpakai |
| RDS MySQL biasa | Lebih murah untuk aplikasi kecil; replica lebih lambat dibuat |
| Aurora + reader di AZ berbeda | Wajib untuk produksi — failover butuh ini |
Koneksi
| Model | Koneksi yang dibuka |
|---|---|
| PHP-FPM, 50 proses × 4 kontainer | Sampai 200 — dibuka dan ditutup terus-menerus |
| Worker mode, 8 worker × 4 kontainer | 32, dipakai ulang |
| Lambda, 500 pemanggilan bersamaan | Sampai 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
| Metrik | Alarm saat |
|---|---|
CPUUtilization | > 70% berkelanjutan |
DatabaseConnections | > 80% dari batas |
AuroraReplicaLag | > 1 detik |
FreeableMemory | Turun terus |
Deadlocks | Bukan nol |
| Performance Insights | Query 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.