L
MySQL • Literally Web ID

Arsitektur High Availability PostgreSQL dengan Patroni & Etcd

⏱️ 22 menit baca • 📅 12 Oct 2026 • 👁️ 1 views
Arsitektur High Availability PostgreSQL dengan Patroni & Etcd

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, ketersediaan tinggi (High Availability atau HA) pada lapisan basis data adalah fondasi utama yang menentukan apakah sebuah layanan enterprise dapat bertahan menghadapi gangguan infrastruktur. Kegagalan basis data (database downtime) tidak hanya mengakibatkan kerugian finansial yang masif, tetapi juga merusak integritas data jika tidak ditangani dengan mekanisme failover yang tepat. Di era di mana aplikasi backend web dibangun menggunakan tumpukan teknologi modern—seperti Go, Node.js, PHP-FPM di belakang Nginx, serta arsitektur berbasis event-driven dengan WebSocket—bottleneck terbesar sering kali bergeser dari lapisan aplikasi ke lapisan penyimpanan persisten (persistence layer).

Secara historis, administrator sistem mengandalkan replikasi master-slave manual atau skrip bash kustom yang dikombinasikan dengan Pacemaker dan Corosync untuk mengelola kluster PostgreSQL. Pendekatan ini terbukti rapuh, rentan terhadap kondisi split-brain (di mana dua node mengira diri mereka adalah master), dan memerlukan intervensi manual yang memakan waktu pemulihan (Recovery Time Objective / RTO yang tinggi).

Sebelum penerapan kluster berbasis otomatisasi, infrastruktur enterprise sering mengalami:

  • Downtime yang lama: Saat node utama mati, proses deteksi kegagalan dilakukan secara manual melalui alert monitoring, memicu eskalasi operasional yang lambat.
  • Risiko Kehilangan Data (Data Loss): Tanpa mekanisme konsensus yang kuat, promosi replika cadangan sering kali dilakukan sebelum WAL (Write-Ahead Logging) terakhir tersinkronisasi sepenuhnya, menyebabkan Recovery Point Objective (RPO) yang buruk.
  • Konfigurasi Aplikasi yang Kaku: Aplikasi harus diubah konfigurasinya atau memerlukan restarting saat terjadi perubahan alamat IP master.

Setelah menerapkan arsitektur High Availability PostgreSQL menggunakan Patroni, Etcd, dan HAProxy, sistem bertransformasi menjadi:

  • Otomatisasi Penuh: Failover terjadi dalam hitungan detik tanpa intervensi manusia.
  • Konsensus Terdistribusi: Etcd menjamin bahwa hanya ada satu sumber kebenaran (single source of truth) untuk status master, menghilangkan risiko split-brain.
  • Transparansi Aplikasi: HAProxy bertindak sebagai pintu gerbang cerdas yang secara dinamis merutekan lalu lintas baca-tulis (read-write traffic) ke master yang aktif saat ini, sementara lalu lintas baca (read-only) dapat disebar ke node replika.

2. Konsep Inti & Deep Dive Arsitektur

Untuk memahami bagaimana Patroni dan Etcd bekerja sama mengamankan kluster PostgreSQL, kita harus membedah arsitektur internal di balik layar (under the hood).

Komponen Utama Kluster

  1. Etcd: Sebuah penyimpanan kunci-nilai (key-value store) terdistribusi yang konsisten dan sangat tersedia (highly available), menggunakan algoritma konsensus Raft. Etcd bertindak sebagai penyimpan status kluster (Cluster Configuration Store) dan distributed lock manager.
  2. Patroni: Sebuah template berbasis Python yang berjalan sebagai daemon di samping setiap instance PostgreSQL. Patroni berinteraksi dengan Etcd untuk melaporkan kesehatan node, berpartisipasi dalam pemilihan pemimpin (leader election), dan mengonfigurasi PostgreSQL secara lokal.
  3. PostgreSQL: Mesin basis data relasional yang menjalankan replikasi streaming fisik bawaan.
  4. HAProxy: Lapisan load balancer TCP yang memeriksa kesehatan endpoint Patroni untuk mengarahkan koneksi aplikasi ke master atau replika yang valid.

Alur Kerja Konsensus dan Failover

+-------------------------------------------------------------+
|                        Client Apps                          |
+------------------------------id-----------------------------+
                               |
                               v
+-------------------------------------------------------------+
|                   HAProxy (Port 5000 / 5001)                | 
+-------+---------------------------------------------+-------+
        | (Read/Write)                                | (Read-Only)
        v                                             v
+---------------+                              +---------------+
|  PostgreSQL   |                              |  PostgreSQL   | 
|  Node 1 (M)   | <--- Streaming Replication - |  Node 2 (R)   |
+-------+-------+                              +-------+-------+
        |                                              |
        v                                              v
+-------+-------+                              +-------+-------+
| Patroni Agent |                              | Patroni Agent |
+-------+-------+                              +-------+-------+
        \                                              /
         \--------------------  ----------------------/
                              v
+-------------------------------------------------------------+
|                   Etcd Consensus Cluster                    | 
|       (Raft Protocol - Leader Election & TTL Keys)          | 
+-------------------------------------------------------------+
  1. Pemilihan Pemimpin (Leader Election): Patroni di Node 1 berhasil mengakuisisi leader key di Etcd dengan masa hidup (Time-to-Live / TTL) tertentu. Node 1 bertindak sebagai Master.
  2. Penyegaran Detak Jantung (Heartbeat): Patroni Node 1 secara berkala memperbarui TTL leader key di Etcd untuk membuktikan bahwa node tersebut masih hidup.
  3. Deteksi Kegagalan: Jika Node 1 mengalami kegagalan perangkat keras atau terputus dari jaringan, Patroni Node 1 gagal memperbarui TTL di Etcd. Setelah TTL kedaluwarsa, kunci tersebut terhapus.
  4. Promosi Replikasi: Patroni di Node 2 mendeteksi hilangnya leader key, lalu memulai proses pemilihan. Patroni Node 2 berkomunikasi dengan Etcd untuk mengklaim kepemimpinan. Setelah berhasil, Patroni Node 2 mengeluarkan perintah pg_ctl promote untuk mengubah instance PostgreSQL lokal dari mode recovery (read-only) menjadi master baru.
  5. Pemberitahuan Load Balancer: HAProxy secara rutin melakukan pemeriksaan kesehatan (health check) ke endpoint HTTP Patroni (/primary atau /replica). HAProxy segera memperbarui rute lalu lintas aplikasi ke master yang baru.

3. Perbandingan Komparatif / Analisis Pendekatan

Berikut adalah analisis perbandingan mendalam antara pendekatan tradisional vs pendekatan modern berbasis Patroni + Etcd:

Parameter Perbandingan Tradisional (Pacemaker / Corosync + Script) Modern (Patroni + Etcd + HAProxy) Dampak Sumber Daya / Trade-off
Waktu Pemulihan (RTO) 30 - 120 Detik 5 - 15 Detik Patroni mendeteksi kegagalan lebih cepat via TTL Etcd.
Risiko Split-Brain Tinggi (terutama saat partisi jaringan) Sangat Rendah (diatasi konsensus Raft) Etcd menjamin kuorum mayoritas.
Kompleksitas Setup Tinggi & Dokumentasi Terfragmentasi Sedang (Standar Industri Teruji) Membutuhkan pemahaman dasar etcd.
Overhead CPU & RAM Rendah Sangat Rendah (Python ringan + Etcd) Etcd mengonsumsi RAM kecil (< 100MB per node).
Dukungan Cloud/Baremetal Terbatas pada konfigurasi OS tertentu Fleksibel (Baremetal, VM, Kubernetes) Patroni mendukung berbagai dynamic configuration store.

[!WARNING] Hindari menggunakan kluster Etcd dengan jumlah node genap (misal: 2 atau 4 node). Algoritma konsensus Raft memerlukan kuorum mayoritas ($N/2 + 1$). Kluster 3 node dapat menoleransi kegagalan 1 node, sementara kluster 2 node akan kehilangan kuorum jika 1 node mati.


4. Prasyarat Sistem & Persiapan Lingkungan

Untuk mengimplementasikan panduan ini, kita akan menyiapkan 3 buah node Virtual Machine / Baremetal dengan sistem operasi Ubuntu Server 22.04 LTS.

Spesifikasi Lingkungan:

  • Node 1 (DB-01): 192.168.10.11 (PostgreSQL, Patroni, Etcd)
  • Node 2 (DB-02): 192.168.10.12 (PostgreSQL, Patroni, Etcd)
  • Node 3 (DB-03 / Witness): 192.168.10.13 (PostgreSQL, Patroni, Etcd, HAProxy)

Prasyarat Awal (Jalankan di Semua Node):

  1. Konfigurasi Resolusi Host (/etc/hosts):
192.168.10.11 db-01
192.168.10.12 db-02
192.168.10.13 db-03
  1. Nonaktifkan Swap untuk performa basis data yang konsisten:
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab
  1. Sinkronkan Waktu Sistem (NTP):
sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chronyd

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Instalasi Etcd (Semua Node)

Instal paket Etcd di ketiga node untuk membentuk kluster konsensus.

sudo apt update
sudo apt install -y etcd-server etcd-client

Hentikan layanan bawaan untuk mengonfigurasi parameter kluster:

sudo systemctl stop etcd

Edit file konfigurasi /etc/default/etcd atau buat file sistem unit baru. Berikut adalah konfigurasi valid /etc/etcd/etcd.yml (atau sesuaikan dengan format systemd environment):

name: 'db-01'
data-dir: '/var/lib/etcd/db-01.etcd'
listen-peer-urls: 'http://192.168.10.11:2380'
listen-client-urls: 'http://192.168.10.11:2379,http://127.0.0.1:2379'
initial-advertise-peer-urls: 'http://192.168.10.11:2380'
advertise-client-urls: 'http://192.168.10.11:2379'
initial-cluster: 'db-01=http://192.168.10.11:2380,db-02=http://192.168.10.12:2380,db-03=http://192.168.10.13:2380'
initial-cluster-token: 'etcd-postgres-cluster'
initial-cluster-state: 'new'

(Catatan: Sesuaikan IP dan nama node (db-02 dan db-03) pada masing-masing server).:

Nyalakan dan aktifkan layanan Etcd:

sudo systemctl daemon-reload
sudo systemctl enable --now etcd

Verifikasi kesehatan kluster Etcd:

etcdctl --endpoints=http://192.168.10.11:2379,http://192.168.10.12:2379,http://192.168.10.13:2379 endpoint health

Langkah 2: Instalasi PostgreSQL dan Patroni (Semua Node)

Instal PostgreSQL (versi 15) dan pustaka pendukung Python untuk Patroni:

sudo apt install -y postgresql-15 postgresql-client-15 python3-pip python3-psycopg2
sudo systemctl stop postgresql
sudo systemctl disable postgresql

Instal Patroni melalui pip:

sudo pip3 install patroni[etcd3]

Langkah 3: Konfigurasi Patroni

Buat direktori konfigurasi Patroni:

sudo mkdir -p /etc/patroni
sudo chown postgres:postgres /etc/patroni

Buat file konfigurasi /etc/patroni/patroni.yml (contoh untuk db-01):-

scope: postgres-cluster
namespace: /service
name: db-01

etcd3:
  hosts: 
    - 192.168.10.11:2379
    - 192.168.10.12:2379
    - 192.168.10.13:2379

restapi:
  listen: 192.168.10.11:8008
  connect_address: 192.168.10.11:8008

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    synchronous_mode: false
    postgresql:
      use_pg_rewind: true
      use_slots: true
      parameters:
        max_connections: 200
        shared_buffers: 256MB
        effective_cache_size: 768MB
        maintenance_work_mem: 64MB
        work_mem: 4MB
        min_wal_size: 1GB
        max_wal_size: 4GB
        checkpoint_completion_target: 0.9
        wal_level: replica
        max_wal_senders: 10
        max_replication_slots: 10

  initdb:
    - encoding: UTF8
    - data-checksums

  pg_hba:
    - host replication replicator 192.168.10.0/24 md5
    - host all all 0.0.0.0/0 md5

postgresql:
  listen: 192.168.10.11:5432
  connect_address: 192.168.10.11:5432
  data_dir: /var/lib/postgresql/15/patroni
  bin_dir: /usr/lib/postgresql/15/bin
  admin_user: postgres
  admin_password: secure_admin_password
  replication:
    username: replicator
    password: secure_replication_password

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false

[!IMPORTANT] Pastikan direktori data PostgreSQL /var/lib/postgresql/15/patroni kosong sebelum menjalankan Patroni untuk pertama kalinya. Patroni akan menjalankan perintah initdb secara otomatis pada node pertama.

Langkah 4: Membuat Systemd Service untuk Patroni

Buat file /etc/systemd/system/patroni.service:

[Unit]
Description=Patroni orchestrator for PostgreSQL
After=network.target etcd.service

[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
TimeoutSec=30
Restart=no

[Install]
WantedBy=multi-user.target

Aktifkan dan jalankan Patroni di semua node:

sudo systemctl daemon-reload
sudo systemctl enable --now patroni

Verifikasi status kluster:

patronictl -c /etc/patroni/patroni.yml list

Langkah 5: Konfigurasi HAProxy Load Balancer (Node 3)

Instal HAProxy di db-03 untuk merutekan koneksi aplikasi:

sudo apt install -y haproxy

Konfigurasikan /etc/haproxy/haproxy.cfg:

global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    daemon

defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend postgres_primary_front
    bind *:5000
    default_backend postgres_primary_back

backend postgres_primary_back
    mode tcp
    option httpchk GET /primary
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server db-01 192.168.10.11:5432 maxconn 200 check port 8008
    server db-02 192.168.10.12:5432 maxconn 200 check port 8008
    server db-03 192.168.10.13:5432 maxconn 200 check port 8008

frontend postgres_replica_front
    bind *:5001
    default_backend postgres_replica_back

backend postgres_replica_back
    mode tcp
    option httpchk GET /replica
    http-check expect status 200
    default-server inter 3s fall 3 rise 2
    server db-01 192.168.10.11:5432 maxconn 200 check port 8008
    server db-02 192.168.10.12:5432 maxconn 200 check port 8008
    server db-03 192.168.10.13:5432 maxconn 200 check port 8008

Nyalakan layanan HAProxy:

sudo systemctl enable --now haproxy

6. Bedah Kode & Penjelasan Detail Baris Kunci

Mari kita bedah parameter kritis dalam konfigurasi Patroni:

  • ttl: 30: Menentukan masa hidup kunci pemimpin di Etcd dalam detik. Jika master gagal mengirimkan sinyal heartbeat selama 30 detik, Etcd akan menghapus kunci tersebut dan memicu pemilihan pemimpin baru.
  • loop_wait: 10: Interval waktu (dalam detik) di mana daemon Patroni memeriksa status lokal dan memperbarui status di Etcd. Nilai yang terlalu kecil dapat membebani Etcd, sementara nilai yang terlalu besar memperlambat deteksi kegagalan.
  • maximum_lag_on_failover: 1048576: Batas maksimal jeda byte WAL (1MB) yang diizinkan bagi replika untuk dipromosikan menjadi master. Jika replika tertinggal lebih dari nilai ini, Patroni tidak akan mempromosikannya guna mencegah kehilangan data transaksi penting.
  • use_pg_rewind: true: Memungkinkan node master lama yang telah pulih untuk menyinkronkan ulang dirinya secara otomatis dengan master baru menggunakan utilitas pg_rewind tanpa perlu melakukan pg_basebackup dari awal.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Dalam lingkungan produksi dengan ribuan permintaan per detik dari aplikasi backend (misal: Node.js/Go yang melayani lalu lintas web tinggi), kegagalan koneksi basis data dapat menyebabkan connection storms.

Penanganan Lonjakan Koneksi:

  1. Pemisahan Beban Kerja (Read/Write Splitting): Aplikasi backend dikonfigurasi untuk mengirim operasi tulis (INSERT, UPDATE, DELETE) ke port HAProxy 5000 (mengarah ke Master) dan operasi baca (SELECT) ke port 5001 (mengarah ke Replikasi). Ini mengurangi beban CPU pada node Master hingga 60%.
  2. Manajemen Sesi HAProxy: Penggunaan parameter on-marked-down shutdown-sessions pada backend HAProxy memastikan bahwa ketika master gagal dan dialihkan, koneksi TCP lama yang macet langsung diputus, memaksa aplikasi membuat ulang koneksi ke master baru yang telah dipromosikan.

8. Common Pitfalls, Anti-Patterns & Solusi

  1. Anti-Pattern: Menggunakan Jumlah Node Etcd Genap

    • Masalah: Menyebarkan kluster Etcd pada 2 atau 4 node. Ketika terjadi gangguan jaringan yang memisahkan kluster menjadi dua bagian yang sama besar (skenario split-brain), kuorum tidak tercapai dan kluster menjadi macet (read-only atau gagal melakukan failover).
    • Solusi: Selalu gunakan jumlah node ganjil minimum 3 untuk produksi.
  2. Kesalahan Konfigurasi pg_hba.conf Manual

    • Masalah: Mengubah file pg_hba.conf secara langsung di dalam server PostgreSQL. Patroni mengelola konfigurasi ini secara terpusat melalui blok bootstrap.dcs.pg_hba di dalam file patroni.yml.
    • Solusi: Selalu ubah aturan autentikasi melalui file konfigurasi Patroni lalu lakukan reload kluster.
  3. Mengabaikan Pemantauan Disk Ruang WAL

    • Masalah: Jika replika tertinggal terlalu jauh dan slot replikasi tidak dibatasi, ruang disk pada master akan habis karena menumpuk file WAL.
    • Solusi: Gunakan parameter max_replication_slots dan pantau metrik disk secara aktif menggunakan Prometheus dan Grafana.

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk menguji ketahanan dan performa kluster, jalankan pengujian beban menggunakan perangkat benchmark seperti pgbench yang dikombinasikan dengan simulasi pemutusan jaringan (chaos engineering).

Menjalankan Benchmark dengan pgbench:

  1. Inisialisasi tabel benchmark melalui HAProxy (Port 5000):
pgbench -i -s 50 -h 192.168.10.13 -p 5000 -U postgres postgres
  1. Jalankan pengujian konkurensi tinggi selama 5 menit:
pgbench -c 50 -j 4 -T 300 -h 192.168.10.13 -p 5000 -U postgres postgres
  1. Simulasi Kegagalan (Chaos Test): Selama pengujian pgbench berjalan, matikan layanan Patroni pada node Master aktif (sudo systemctl stop patroni).
  2. Analisis Hasil: Amati log HAProxy dan Patroni. Pengujian yang sukses akan menunjukkan jeda koneksi sesaat selama 5 hingga 10 detik, diikuti oleh kelanjutan transaksi setelah master baru dipromosikan secara otomatis.

Parameter Tuning Lanjutan di patroni.yml:

  • shared_buffers: Atur ke 25% dari total RAM sistem.
  • effective_cache_size: Atur ke 75% dari total RAM sistem.
  • checkpoint_completion_target: Setel ke 0.9 untuk mendistribusikan penulisan I/O secara merata guna menghindari lonjakan latensi (disk I/O spikes).

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum merilis kluster High Availability PostgreSQL ini ke lingkungan produksi publik, pastikan Anda telah memverifikasi daftar periksa berikut:

  • Kluster Etcd berjalan dengan 3 node ganjil dan responsif (< 10ms latency antar node).
  • Autentikasi sandi aman dan tidak menggunakan kredensial default.
  • Firewall (UFW / iptables) dikonfigurasi hanya mengizinkan port internal (5432, 2379, 2380, 8008, 5000, 5001) antar node yang berhak.
  • Skrip pencadangan otomatis (automated backup dengan pg_back atau barman) dikonfigurasi secara berkala ke penyimpanan eksternal (S3/MinIO).
  • Pemantauan metrik (Prometheus exporter untuk Patroni dan PostgreSQL) aktif dan terintegrasi dengan sistem alerting (PagerDuty / Telegram / Email).

Dengan menerapkan arsitektur Patroni, Etcd, dan HAProxy ini, infrastruktur basis data enterprise Anda kini memiliki ketahanan militer terhadap kegagalan perangkat keras, memastikan ketersediaan layanan web yang mulus bagi seluruh pengguna.

🏷️ Tags: #High Availability #Postgresql #Patroni #Etcd #Haproxy