1 poin oleh GN⁺ 3 jam lalu | Belum ada komentar. | Bagikan ke WhatsApp
  • Pada klaster PostgreSQL berbasis k8s, saat terjadi gangguan jaringan, replication lag terakumulasi sehingga muncul kelemahan struktural yang membuat failover aman menjadi tidak mungkin; berikut cara mengatasinya
  • Arsitektur lama memprioritaskan availability di atas durability, sehingga saat primary terus menerima penulisan, replica makin tertinggal dan tidak ada lagi kandidat yang bisa dipromosikan tanpa kehilangan data
  • Sebagai solusi, synchronous replication diterapkan pada kandidat failover dan dikoordinasikan dengan manajer high availability open source Patroni
  • Dengan model replikasi hibrida di mana hanya standby di leader pool yang ikut dalam synchronous replication sementara read replica tetap asinkron, dicapai keseimbangan antara durability dan latensi
  • Meski ada biaya performa seperti peningkatan latensi tulis 53% saat memakai mode remote_apply, verifikasi 5 skenario gangguan menunjukkan failover otomatis yang aman dapat dicapai

Masalah yang Terungkap dalam GameDay

  • Datadog secara rutin menjalankan GameDay untuk menemukan celah dalam sistem dan proses secara proaktif, dengan memberi beban sengaja pada platform agar bisa mempelajari responsnya dalam kondisi nyata
  • Dalam salah satu GameDay, mereka mensimulasikan gangguan availability zone (AZ) di lingkungan staging dan memicu latensi jaringan, sehingga kelemahan arsitektur PostgreSQL pun terlihat
    • Node primary/writer dari beberapa klaster PostgreSQL berbasis Kubernetes berjalan di AZ yang terdampak
    • Lonjakan latensi jaringan membuat primary tidak bisa berkomunikasi stabil dengan replica, replication lag meningkat → penulisan tersendat → aplikasi menyajikan data yang usang
  • Karena tidak ada replica yang cukup mutakhir, failover tidak aman dilakukan, dan klaster praktis berhenti
  • Arsitektur ini bekerja baik dalam kondisi normal, tetapi pada situasi gangguan jaringan tertentu ia lebih memprioritaskan availability daripada durability, sehingga tidak ada jalur pemulihan yang aman
    • Primary tetap menerima penulisan meskipun replikasi tertunda, replication lag makin besar dan replica makin tertinggal
    • Akibatnya, tidak ada kandidat failover yang bisa dipromosikan tanpa risiko kehilangan data, dan satu-satunya pilihan adalah menunggu latensi mereda serta replica mengejar ketertinggalan
  • Tujuannya adalah membuat failover otomatis sekaligus aman tanpa merusak karakteristik performa PostgreSQL lebih dari yang diperlukan

Arsitektur Dasar: PostgreSQL di Atas Kubernetes

  • Klaster PostgreSQL berbasis Kubernetes terdiri dari dua pool: leader pool dan read replica pool, sementara PostgreSQL adalah sistem single-writer
    • Dengan pemisahan baca/tulis, pembacaan bisa diskalakan tanpa membebani leader, dan latensi tulis tetap dapat diprediksi dan stabil
  • Leader pool terdiri dari 1 node writer aktif tunggal yang menangani semua penulisan dan 2 node standby
    • Standby tidak melayani trafik aplikasi, tetapi bisa dipromosikan bila leader gagal
  • Read replica pool terdiri dari banyak node yang menangani trafik baca saja, dioptimalkan untuk skalabilitas baca dan isolasi query, dan sengaja dikecualikan dari target failover

Peran Patroni dan ZooKeeper

  • Patroni mengelola replikasi, failover, dan pemilihan leader, serta memakai ZooKeeper sebagai DCS
    • ZooKeeper menyimpan metadata seperti key/lock leader saat ini, konfigurasi klaster, dan status replikasi tiap anggota (misalnya LSN terbaru)
    • Patroni menggunakan informasi ini untuk memutuskan promosi atau penurunan peran secara konservatif, dengan mengutamakan konsistensi data ketimbang failover agresif
  • Saat node baru bergabung ke klaster, ia terlebih dahulu memeriksa di ZooKeeper apakah leader sudah ada
    • Jika tidak ada leader, node mencoba mendapatkan key leader dengan membuat znode sementara; ZooKeeper menjamin hanya satu node yang bisa mendapatkannya sehingga mencegah terbentuknya multi-primary
    • Jika leader sudah ada, node akan dikonfigurasi sebagai replica dan memulai streaming replication
  • Saat terjadi network partition, replica yang kehilangan koneksi ke leader atau ZooKeeper tidak bisa memverifikasi status klaster, sehingga Patroni akan menjeda atau menurunkan peran node tersebut
  • Jika leader kehilangan koneksi, Patroni bekerja sama dengan ZooKeeper agar hanya satu standby yang memenuhi syarat memperoleh leader lock, sehingga failover tetap terkontrol bahkan saat terjadi gangguan jaringan parsial
    • Setelah koneksi pulih, leader lama akan menurunkan dirinya menjadi standby jika gagal mendapatkan kembali leader lock, sehingga split brain dapat dicegah

Mengapa Failover Aman Tidak Mungkin Dilakukan

  • Dalam model single-writer, saat terjadi gangguan Patroni akan memilih leader baru dari standby yang sehat
  • Untuk mencegah kehilangan data, Patroni melakukan pemeriksaan keamanan sebelum promosi, dengan inti pengecekan apakah replication lag masih berada di bawah ambang maximum_lag_on_failover
    • Jika standby tertinggal dari leader, promosi dapat menimbulkan data hilang atau inkonsistensi
  • Dalam GameDay, ketika primary kehilangan koneksi, replication lag semua standby melampaui ambang batas dan Patroni menolak failover dengan tepat
    • Klaster yang tersisa tanpa primary aman untuk menulis bukan karena Patroni bermasalah, tetapi karena memang tidak ada kandidat promosi yang aman

Dua Mode Streaming Replication

  • Dalam streaming replication, leader terus mengirim write-ahead log (WAL) berisi semua perubahan ke replica, dan replica menerapkan WAL itu secara lokal agar tetap sinkron
  • Replikasi Asinkron (default)

    • Leader tidak menunggu konfirmasi dari replica sebelum commit transaksi
    • Latensi tulis minimal, mendukung throughput tinggi
    • Namun, bila leader gagal, transaksi yang sudah commit di primary tetapi belum sempat direplikasi bisa hilang saat promosi
  • Replikasi Sinkron

    • Leader menunggu setidaknya 1 konfirmasi replica sebelum mengirim respons ke klien
    • Ini sangat mengurangi risiko setidaknya satu replica tertinggal terlalu jauh, dan memberi jaminan durability lebih kuat karena respons baru diberikan setelah dipastikan transaksi yang sudah commit ada di node lain
    • Kandidat failover lebih mungkin berada dalam keadaan mutakhir sehingga bisa dipromosikan tanpa risiko percabangan data

Konfigurasi Replikasi Hibrida

  • Untuk menyeimbangkan durability, latensi, dan throughput, diadopsi model replikasi hibrida
    • Node standby di leader pool ikut dalam synchronous replication, sehingga leader baru commit penulisan setelah mendapat konfirmasi dari standby sinkron yang ditunjuk
    • Read replica tetap memakai replikasi asinkron, karena hanya menangani trafik baca dan bukan target failover, sehingga beban replikasi pada leader pool tetap terbatas
  • Dengan cara ini, jaminan durability yang ketat hanya diterapkan pada kandidat failover tanpa memaksakan biaya latensi yang sama pada read replica

Tuning PostgreSQL dan Patroni untuk Failover Aman

  • Untuk mengaktifkan synchronous replication, parameter perlu disesuaikan di PostgreSQL dan Patroni sekaligus
  • Parameter utama yang diubah

    • synchronous_mode: mengaktifkan synchronous replication di Patroni; jika true, commit dilakukan setelah konfirmasi standby sinkron sesuai synchronous_node_count (default false → true, dikelola Patroni, wajib)
    • synchronous_node_count: jumlah node standby sinkron, dipakai untuk membentuk daftar synchronous_standby_names (default 1 → 1, dikelola Patroni, opsional)
    • synchronous_mode_strict: memaksa mode sinkron ketat; jika true dan tidak ada replica yang tersedia, penulisan diblokir alih-alih beralih ke asinkron (default false → true, dikelola Patroni, opsional)
    • synchronous_commit: pengaturan durability commit PostgreSQL (default on → remote_apply, dikelola PostgreSQL, opsional)
  • Setelah diterapkan, leader hanya akan mengirim respons transaksi ke klien setelah standby sinkron mengonfirmasi bahwa data sudah diterima dan diterapkan

Menyeimbangkan Durability dan Latensi

  • Synchronous replication meningkatkan durability, tetapi karena leader harus menunggu konfirmasi dari standby sinkron, latensi tulis naik dan throughput bisa terdampak di bawah beban berkelanjutan
  • Dampak performa bergantung pada jumlah standby sinkron (synchronous_node_count) dan tingkat durability yang diatur lewat synchronous_commit
  • Trade-off per tingkat durability synchronous_commit

    • remote_apply: menunggu replica menulis, flush, dan memutar ulang WAL; konsistensi paling kuat, latensi paling tinggi
    • on (secara internal remote_flush): menunggu replica melakukan flush WAL ke disk; durability kuat tetapi data belum tentu bisa dibaca di standby
    • remote_write: menunggu WAL mencapai cache OS replica (bukan disk); latensi lebih rendah tetapi rentan terhadap crash OS
    • local: commit setelah flush ke disk lokal tanpa menunggu standby; tidak ada jaminan durability antar-node
    • off: commit sebelum flush WAL lokal; latensi paling rendah dan risiko kehilangan data paling tinggi

Benchmark Performa Replikasi Sinkron

  • Karena setiap commit harus menunggu konfirmasi dari setidaknya satu standby, synchronous replication menambah latensi; untuk mengukur dampaknya, dilakukan benchmark dengan pgbench, alat uji beban standar PostgreSQL (Patroni versi 3.2.1)
  • Digunakan suite transaksi TPC-B yang mensimulasikan campuran baca/tulis sederhana, dengan dua metrik yang diukur
    • Latensi rata-rata: waktu pemrosesan rata-rata per transaksi (ms)
    • Transaksi per detik (tps): jumlah transaksi selesai, tidak termasuk waktu setup koneksi
  • Parameter pengujian

    • Faktor skala (ukuran database), jumlah klien (trafik pengguna bersamaan), jumlah thread (CPU dan paralelisme), serta jumlah transaksi (intensitas workload) diubah untuk meniru kondisi operasional yang realistis
    • Replikasi sinkron dengan mode quorum commit tidak diuji dalam benchmark ini
  • Hasil benchmark

    • Tingkat kenaikan latensi tulis: remote_apply 53%, on 46%, remote_write 38%, local 32%
    • Tingkat penurunan throughput (tps): remote_apply 34%, on 31%, remote_write 27%, local 23%
    • remote_apply secara konsisten menunjukkan latensi tertinggi dan throughput terendah karena menunggu WAL diputar ulang dan diterapkan di replica, tetapi ia juga memberi konsistensi terkuat sehingga cocok untuk failover aman
  • Penerapan di produksi

    • Setelah benchmark, remote_apply diterapkan ke beberapa klaster dengan trafik tulis tinggi, dan tidak ada dampak berarti pada latensi tulis atau throughput di level aplikasi meski berada di bawah beban produksi berkelanjutan
    • Untuk mengurangi risiko performa, rollout dilakukan bertahap per data center dan per lapisan workload, dengan periode bake-in dan pemantauan berkelanjutan di antara tiap tahap
    • Contoh: workload pemrosesan resource ber-throughput tinggi tetap berjalan tanpa penundaan pemrosesan atau backlog downstream, meski latensi tulis DB meningkat setelah synchronous replication diaktifkan
    • synchronous_commit bisa disesuaikan seketika tanpa downtime lewat patronictl edit-config, memberi fleksibilitas untuk segera menurunkan durability commit pada workload dengan throughput sangat tinggi

Verifikasi Failover lewat Skenario Gangguan

  • Dilakukan verifikasi apakah synchronous replication dan kontrol failover ketat benar-benar melindungi integritas data, mencegah split-brain, dan menjamin pemulihan otomatis
  • Skenario 1: Kehilangan 1 standby sinkron

    • Saat standby sinkron hilang, Patroni mencoba mempertahankan synchronous replication dengan menugaskan standby lain yang memenuhi syarat
    • Patroni pada node leader mendeteksi koneksi streaming yang putus, macet, atau tertunda lewat pg_stat_replication, dan melacak keanggotaan replica lewat ZooKeeper
    • Ia menghitung ulang daftar streaming replica yang sehat dan memenuhi syarat, lalu memperbarui synchronous_standby_names berdasarkan synchronous_node_count, sehingga synchronous replication tetap aktif
  • Skenario 2: Kehilangan semua standby sinkron

    • Perilakunya bergantung pada nilai synchronous_mode_strict
    • Mode non-ketat: mengutamakan availability tulis

      • Patroni mengosongkan synchronous_standby_names untuk menonaktifkan sementara synchronous replication, sehingga leader beralih ke asinkron dan tetap mengizinkan penulisan hingga replica sehat bergabung kembali
    • Mode ketat: memblokir penulisan demi keamanan

      • Patroni mengatur synchronous_standby_names menjadi *; meski tidak ada standby sinkron eksplisit, PostgreSQL tetap menerima dan commit transaksi tulis secara lokal, tetapi menahan respons ke klien sampai ada replica yang mengonfirmasi WAL
      • Saat replica yang cocok untuk ikut synchronous replication tersambung kembali, Patroni akan menetapkannya sebagai standby sinkron
  • Skenario 3: Semua standby dan replica tidak tersedia

    • Jika semua replica tidak tersedia dan synchronous_mode_strict = true, PostgreSQL akan menahan konfirmasi transaksi sampai setidaknya satu replica yang memenuhi syarat kembali
    • Konsistensi data tetap terjaga, tetapi aplikasi akan mengalami ketidakmampuan menulis sementara
  • Skenario 4: Leader gagal saat synchronous commit

    • Ini adalah edge case ketika leader sedang menunggu konfirmasi dari standby sinkron tetapi berhenti sebelum konfirmasi diterima
    • Penyebab umum: transaksi klien dibatalkan saat commit, proses PostgreSQL pada leader crash atau dihentikan, atau terjadi network partition di tahap commit
    • Jika PostgreSQL sudah flush WAL ke lokal tetapi gagal mereplikasikannya ke standby, maka tanpa konfirmasi transaksi itu tidak akan terlihat di replica
    • Jika leader crash sebelum WAL direplikasi ke standby sinkron dan standby tersebut dipromosikan, transaksi bisa hilang dan histori antara leader lama dan primary baru akan bercabang
    • Leader lama menggunakan pg_rewind untuk mengidentifikasi titik percabangan timeline dan memundurkan data directory agar sesuai dengan timeline primary baru, membuang perubahan lokal yang belum direplikasi lalu bergabung kembali sebagai standby
    • Perilaku ini merupakan hasil dari mekanisme internal synchronous commit PostgreSQL, bukan Patroni, dan menegaskan pentingnya tuning serta pemantauan yang cermat terhadap konfigurasi quorum dan mekanisme konfirmasi
  • Skenario 5: ZooKeeper tidak tersedia

    • Saat ZooKeeper tidak tersedia, Patroni tidak dapat memverifikasi kepemimpinan atau melakukan pemilihan baru, sehingga beralih ke perilaku konservatif untuk mencegah inkonsistensi data
    • Saat failsafe mode nonaktif

      • Meski ZooKeeper tidak bisa dijangkau, jika leader masih bisa diakses dan semua node sehat, penulisan tetap berjalan, tetapi hanya sampai TTL leader lock kedaluwarsa
      • Saat loop pembaruan leader key terlewati dan lock tidak bisa diperbarui, Patroni akan menurunkan leader dan mengubah klaster menjadi read-only
    • Saat failsafe mode aktif

      • Jika leader kehilangan koneksi ke ZooKeeper, Patroni terus memeriksa keterjangkauan semua anggota klaster lewat REST API
      • Penulisan hanya diteruskan bila semua anggota dapat diakses; jika tidak, leader diturunkan menjadi read-only

Failover dan Switchover Manual di Bawah Replikasi Sinkron

  • Selain failover dan switchover otomatis berbasis health check serta koordinasi ZooKeeper, Patroni juga mendukung operasi manual lewat perintah patronictl; saat synchronous replication aktif, tidak semua standby adalah kandidat valid, sehingga diterapkan guardrail untuk melindungi integritas data
  • Failover ke standby asinkron

    • patronictl failover: gagal jika node yang dipilih asinkron
    • patronictl switchover: gagal jika node yang dipilih asinkron
    • Memaksa failover ke node asinkron saat synchronous replication aktif akan melewati jaminan durability dan bisa menyebabkan kehilangan data
  • Jika targetnya standby sinkron

    • patronictl failover: berhasil, leader dipindahkan ke standby sinkron
    • patronictl switchover: berhasil, handoff yang mulus dilakukan antara leader dan standby sinkron
  • Setelah perilaku berbagai mode synchronous_commit dan guardrail Patroni diverifikasi, synchronous replication diaktifkan pada klaster produksi dengan workload tulis tinggi, baca tinggi, dan campuran, tanpa dampak terukur pada latensi maupun throughput
  • Jika muncul masalah, sistem bisa dikembalikan dengan aman ke replikasi asinkron tanpa downtime dengan mengatur synchronous_mode: false

Mengapa Tidak Memilih DRBD

  • Dalam evaluasi high availability, sistem replikasi tingkat blok DRBD (Distributed Replicated Block Device) juga dipertimbangkan; sistem ini mencerminkan seluruh volume antar-server, termasuk data directory PostgreSQL dan file WAL, untuk membuat replica standby hampir real-time
  • DRBD bisa menawarkan latensi lebih rendah dibanding streaming replication bawaan PostgreSQL, tetapi memerlukan perubahan arsitektur besar, termasuk infrastruktur baru, pemantauan, dan playbook operasional
  • Dengan mempertimbangkan setup berbasis Kubernetes yang sudah matang serta kontrol halus dari synchronous replication PostgreSQL, dipilihlah replikasi di level database karena memberikan visibilitas, fleksibilitas, dan keandalan operasional yang lebih baik

Pemantauan Replikasi Sinkron

  • Setelah synchronous replication diaktifkan, status replikasi dan kesiapan failover dipantau dengan ketat, terutama dua sinyal berikut yang membantu menjaga stabilitas dalam skala besar
  • Event tunggu SyncRep

    • Terjadi ketika primary menunggu konfirmasi dari standby sinkron sebelum commit selesai dan status dikembalikan; sebagian kemunculan ini normal, tetapi jika terlalu lama atau terlalu sering, itu menandakan masalah performa replica atau latensi jaringan antar-node
    • Mengapa penting: penantian yang lama akan meningkatkan latensi tulis dan menurunkan throughput
    • Yang dilacak: durasi dan frekuensi event tunggu SyncRep dan WalSenderWaitForReply, dikumpulkan dari metrik Datadog postgresql.activity.waits yang difilter dengan tag wait_event:SyncRep (secara internal melakukan query pada tabel pg_stat_activity)
  • Tidak terdeteksinya standby sinkron

    • Jika Patroni dalam waktu lama tidak mendeteksi standby sinkron yang sehat, klaster kehilangan kemampuan melakukan failover aman
    • Mengapa penting: tanpa standby sinkron, failover menjadi rentan terhadap kehilangan data
    • Ambang peringatan: bila patroni_sync_standby tetap kosong, akan dipicu alert kesehatan high availability (HA); data ini dikumpulkan dari OpenMetrics dan tidak memiliki integrasi Datadog native
  • Synchronous replication meningkatkan durability, tetapi ketika replica tidak sehat atau tidak dapat dijangkau, availability dan performa bisa menurun; pemantauan waktu tunggu dan ketersediaan standby sangat penting untuk menjaga availability dan performa di bawah beban

Failover Aman Sejak Tahap Desain

  • Gangguan AZ yang disimulasikan menyingkap kelemahan fatal dalam arsitektur PostgreSQL: replica tertinggal dari leader sehingga tim dipaksa memilih antara menunggu gangguan jaringan selesai atau menerima percabangan data, trade-off yang tidak dapat diterima di produksi
  • Dengan mengadopsi synchronous replication berbasis Patroni dan men-tuning durability serta latensi, failover menjadi mungkin sekaligus aman bahkan dalam kondisi jaringan yang menurun; benchmark dan simulasi gangguan berulang menunjukkan pemulihan yang dapat diprediksi tanpa merusak performa pada skala besar
  • Dengan memblokir penulisan saat synchronous replication bermasalah, kegagalan diekspos secara eksplisit ke layanan upstream; tidak seperti replikasi asinkron yang bisa diam-diam kehilangan penulisan, pendekatan ini memungkinkan penanganan lewat retry, queueing, dan cara lain sehingga mode gangguan lebih terlihat dan lebih bisa dipulihkan
  • Ke depan, mereka sedang mengeksplorasi mode commit berbasis quorum serta observabilitas yang lebih mendalam terhadap status replikasi

Belum ada komentar.

Belum ada komentar.