UNDER PRESSURE

Level 2 · Database adalah Leher Botol

Sesi 18: Membaca Jauh Lebih Sering daripada Menulis: Read Replica & Replication Lag

Bagaimana jika 95% beban database ternyata hanya orang yang melihat saldo dan membaca katalog, bukan mengubah data — dan saat kita pasang server cadangan untuk membaca, pengguna komplain postingan mereka yang baru diunggah tiba-tiba hilang?

Sesi 18 / 343 menit baca

1. Bayangkan Jika

Sebuah perpustakaan memiliki satu buku induk catatan rahasia. 1.000 mahasiswa datang: 950 orang hanya ingin membaca, dan 50 orang ingin menulis catatan baru. Karena hanya ada satu buku, antrean mengular 3 jam.

Kepala perpustakaan memfotokopi buku induk itu menjadi 5 buku salinan agar 950 pembaca bisa membaca serentak. Namun, ada jeda waktu 10 menit bagi petugas untuk memfotokopi setiap halaman baru yang baru saja ditulis di buku induk.

Seorang mahasiswa baru saja mendaftarkan namanya di buku induk, lalu langsung mengecek buku salinan: namanya belum ada. Dia panik mengira pendaftarannya gagal, lalu mendaftar ulang 5 kali!


2. Apa yang Sebenarnya Terjadi

Pemisahan beban baca dan tulis (Read/Write Splitting) adalah strategi dasar scaling database:

  1. Primary (Writer) vs Standby Replica (Reader): - Primary Database: Satu-satunya node yang menerima transaksi tulis (INSERT, UPDATE, DELETE). Menuliskan perubahan ke WAL (Write-Ahead Log). - Read Replicas: Node salinan yang menerima aliran data log dari Primary secara asinkron (Streaming Replication). Hanya melayani query baca (SELECT).

  2. Replication Lag: - Karena replikasi berjalan asinkron untuk menjaga latensi write di Primary tetap kilat (< 2 ms), ada jeda waktu beberapa milidetik hingga beberapa detik sebelum transaksi mendarat di disk replica. - Saat Primary dihantam beban write berat (misal: batch insert atau migrasi tabel), replication lag bisa membengkak dari 50 ms menjadi 15 detik!

  3. Read-Your-Own-Writes Problem: - Pengguna mengupdate foto profil -> Request tulis masuk ke Primary (OK). - Halaman me-refresh -> Request baca foto profil dilempar oleh Load Balancer ke Read Replica yang tertinggal lag 2 detik. - Browser menampilkan foto profil lama. Pengguna mengira sistem error dan mengklik tombol upload berkali-kali.


3. Bagaimana Jika Kita Coba...

"Kita buat replikasi synchronous saja ke semua replica!"

Mengapa ini ide buruk untuk performa? - Dalam replikasi sinkron (Synchronous Replication), setiap transaksi COMMIT di Primary harus menunggu konfirmasi bahwa data sudah ditulis di RAM/disk SEMUA replica. - Satu replica mengalami disk slow atau network stutter, seluruh transaksi write di Primary macet total (Write Latency Spike). Throughput sistem anjlok.


4. Nama Resminya

  • Read/Write Splitting: Memisahkan koneksi query baca dan tulis di level aplikasi / pooler.
  • Replication Lag / Replication Delay: Jeda waktu data antara master dan salinan.
  • Eventual Consistency: Jaminan bahwa data pasti akan konsisten pada akhirnya, bukan seketika itu juga.
  • Read-After-Write Consistency (Causal Consistency): Jaminan bahwa pengguna selalu melihat perubahan yang baru saja ia buat sendiri.
  • LSN (Log Sequence Number) Tracking: Token posisi log database untuk memastikan replica sudah mengejar transaksi tertentu sebelum dibaca.

5. Di Dunia Kita

Bagaimana engineering team menyelesaikan dilema ini: - Sticky Primary Routing (Session Pinning): Setelah pengguna melakukan operasi write, arahkan semua query read dari pengguna tersebut ke Primary selama 5 detik berikutnya (grace period). - LSN-Based Routing: Aplikasi menyertakan token LSN write terakhir; request read hanya dikirim ke replica jika LSN replica \ge LSN token. - Replica Lag Health Check: Jika replication lag replica > 5 detik, otomatis keluarkan replica tersebut dari pool pembagian trafik.


6. Lensa Performance Tester

Metrik dan pengujian krusial: 1. Replication Lag Under Peak Write Load: Ukur lonjakan lag replica (pg_stat_replication.replay_lag / Seconds_Behind_Master) saat beban write 2.000 TPS. 2. Read-After-Write Race Condition Test: Uji skenario otomatis: buat order baru -> langsung baca detail order dalam tempo < 10 ms. Berapa persentase transaksi yang mendapati data hilang (404)? 3. Primary Write Saturation: Pastikan Primary tidak kehabisan CPU karena dipaksa melayani streaming replication ke terlalu banyak replica (rekomendasi: max 3–5 direct replicas per primary).


7. Pertanyaan untuk Ronde Berikutnya

Read replica berhasil membagi beban baca ke 5 server. Tapi bagaimana jika ada 10.000 pengguna yang menanyakan satu data viral yang sama persis dalam satu detik — apakah kita harus menanyakannya ke database 10.000 kali?

Jawabannya ada di Sesi 19: Menunda Pertanyaan ke Database (Redis Cache, Hit Ratio, & Thundering Herd).