UNDER PRESSURE

Level 2 · Database adalah Leher Botol

Sesi 17: Penjaga Pintu Database: PgBouncer, ProxySQL, & Transaction Pooling

Bayangkan jika 2.000 orang ingin bicara dengan satu petugas, lalu kita menaruh resepsionis yang hanya memperbolehkan 100 orang masuk sekaligus. Apakah 1.900 sisanya jadi lebih lambat — atau justru seluruh sistem menjadi 10 kali lebih cepat?

Sesi 17 / 343 menit baca

1. Bayangkan Jika

Sebuah restoran populer memiliki 10 meja makan dan 1 kasir. Jika 500 pengunjung dibiarkan merangsek masuk ke dalam dapur, mereka akan saling senggol, menjatuhkan piring koki, dan dalam 5 menit dapur tutup karena kekacauan.

Pemilik restoran kemudian menaruh satu satpam di pintu depan (bouncer). Satpam hanya mengizinkan 10 orang masuk ke meja. Orang ke-11 harus menunggu dengan tertib di ruang tunggu berpendingin. Hasilnya? Koki bisa memasak tanpa gangguan dengan kecepatan maksimal, meja cepat berganti, dan 500 orang selesai makan jauh lebih cepat daripada saat mereka dibiarkan menyerbu dapur bersamaan.


2. Apa yang Sebenarnya Terjadi

Sebuah Connection Pooler / SQL Proxy (seperti PgBouncer untuk PostgreSQL atau ProxySQL untuk MySQL) bertindak sebagai resepsionis cerdas di depan database:

  1. Multiplexing Koneksi (M:N Mapping): - Di sisi depan (client-side): PgBouncer dapat menahan 10.000 koneksi idle dari ratusan pod aplikasi dengan konsumsi RAM yang sangat kecil (~2 KB per koneksi socket epoll). - Di sisi belakang (server-side): PgBouncer hanya membuka 50–100 koneksi fisik nyata ke database engine (sesuai jumlah core CPU database).

  2. Tiga Mode Pooling: - Session Pooling: Koneksi database dipinjamkan ke klien selama sesi TCP klien hidup. Begitu disconnect, koneksi dikembalikan. (Paling aman, tapi rasio penghematan koneksi rendah). - Transaction Pooling: Koneksi database hanya dipinjamkan selama transaksi berlangsung (BEGIN ... COMMIT). Begitu transaksi selesai, koneksi fisik seketika dialihkan untuk melayani transaksi dari pod lain. (Menghemat 95% koneksi server!). - Statement Pooling: Koneksi dipinjamkan hanya untuk satu query tunggal. (Sangat agresif, transaksi multi-query dilarang).

  3. Kenapa Membatasi Koneksi Menaikkan Throughput? - Sesuai prinsip Teori Antrean (Sesi 3): Ketika beban melebihi kapasitas layanan, waktu antre meledak secara eksponensial. - Dengan membatasi koneksi aktif di database tepat pada angka optimal core CPU (misal: 64 proses aktif pada 16-core CPU), tidak ada CPU thrashing dan tidak ada lock contention liar. Query selesai dalam 2 ms alih-alih 200 ms!


3. Bagaimana Jika Kita Coba...

"Kita langsung pakai Transaction Pooling di semua aplikasi!"

Mengapa ini bisa merusak aplikasi jika tidak hati-hati? - Prepared Statements: Query template PREPARE stmt disimpan di sesi server DB. Jika transaksi berikutnya dijalankan di koneksi backend yang berbeda, query akan error prepared statement does not exist (solusinya: gunakan named prepared statement support di PgBouncer 1.21+ atau disable prepared statement di ORM). - Session State / SET Commands: Perintah seperti SET TIMEZONE = 'Asia/Jakarta' atau LISTEN / NOTIFY menempel pada koneksi fisik. Jika koneksi dioper ke pod lain, setting tersebut bisa bocor ke transaksi pengguna lain (session pollution). - Advisory Locks: Lock level sesi tidak otomatis dilepas saat commit, menggantung di koneksi fisik.


4. Nama Resminya

  • Connection Pooler: Perantara multiplexing koneksi (PgBouncer, ProxySQL, AWS RDS Proxy).
  • Transaction Pooling: Mode pelepasan koneksi backend pada boundary transaksi COMMIT/ROLLBACK.
  • Admission Control: Teknik menahan beban di gerbang depan untuk mencegah kolaps di hilir.
  • Connection Multiplexing: Mengawinkan ribuan koneksi klien ke puluhan koneksi server.
  • DISCARD ALL / RESET: Perintah pembersihan state koneksi sebelum digunakan ulang.

5. Di Dunia Kita

  • AWS RDS Proxy: Layanan managed connection pooler otomatis untuk PostgreSQL dan MySQL yang terintegrasi dengan IAM auth dan auto-failover.
  • Sidecar Pooler vs Central Pooler:
  • Sidecar: PgBouncer jalan di tiap pod (mengurangi network hop, tapi total koneksi DB tetap bertambah seiring jumlah pod).
  • Central Cluster: PgBouncer di-cluster terpusat di depan DB (kontrol penuh atas batas koneksi absolut DB).

6. Lensa Performance Tester

Metrik dan pengujian krusial: 1. Client Wait Time on Pooler: Berapa milidetik request klien mengantre di PgBouncer sebelum mendapat koneksi database? 2. Server Active vs Idle Pool: Apakah pool backend selalu terutilisasi 100% (indikasi butuh tambah pool) atau sering idle? 3. Prepared Statement Error Rate: Pantau error log aplikasi pasca migrasi ke transaction pooling. 4. Saturation Curve with Pooler: Buktikan bahwa kurva throughput tetap datar (plateau) dan tidak anjlok (hockey stick) saat simulasi 5.000 virtual users.


7. Pertanyaan untuk Ronde Berikutnya

Koneksi ke database sudah rapi terkendali. Tapi bagaimana jika 95% dari seluruh query yang masuk ke database ternyata hanya membaca data (SELECT profil, katalog, saldo), bukan menulis data baru?

Jawabannya ada di Sesi 18: Membaca Jauh Lebih Sering daripada Menulis (Read Replica & Replication Lag).