L
MySQL • Literally Web ID

Membangun High Availability PostgreSQL dengan Patroni dan Etcd

⏱️ 18 menit baca • 📅 12 Oct 2026 • 👁️ 1 views
Membangun High Availability PostgreSQL dengan Patroni dan Etcd

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, ketersediaan tinggi atau High Availability (HA) bukan lagi sebuah kemewahan, melainkan fondasi operasional mutlak. Ketika sebuah sistem menghandle jutaan request dari backend Go, Node.js, atau PHP-FPM, berinteraksi dengan layanan queue seperti Redis, dan menyajikan aset melalui Nginx reverse proxy di belakang CDN Cloudflare, titik kegagalan tunggal (Single Point of Failure) terbesar hampir selalu bermuara pada lapisan database relasional: PostgreSQL.

Secara tradisional, replikasi PostgreSQL berbasis streaming replication klasik memiliki kelemahan mendasar dalam hal otomatisasi. Ketika node Primary mengalami kegagalan perangkat keras, korupsi sistem file, atau putusnya jaringan, proses failover (promosi node Standby menjadi Primary) harus dilakukan secara manual oleh Infrastructure Engineer. Proses manual ini memakan waktu—sering disebut sebagai Mean Time to Recovery (MTTR) yang tinggi—yang dapat berkisar antara beberapa menit hingga jam. Dalam skenario bisnis modern, downtime selama 10 menit pada puncak transaksi e-commerce atau layanan SaaS dapat mengakibatkan kerugian finansial masif dan rusaknya reputasi brand.

Kondisi Sebelum Penerapan (Traditional Setup):

  • PostgreSQL Primary dan Standby dikonfigurasi secara statis.
  • Pemantauan menggunakan health check pihak ketiga yang sering memicu split-brain scenario jika terjadi false positive pada jaringan.
  • Proses failover manual yang rawan human error di tengah malam saat insiden terjadi.
  • Tidak adanya konsensus terdistribusi yang memvalidasi status kesehatan node secara terpusat.

Kondisi Sesudah Penerapan (Patroni + Etcd):

  • Klaster PostgreSQL dikelola secara otonom oleh Patroni menggunakan Distributed Consensus Store (DCS) berbasis etcd.
  • Deteksi kegagalan otomatis dalam hitungan detik tanpa intervensi manual.
  • Perlindungan ketat terhadap split-brain melalui sistem leader leasing berbasis Raft algorithm.
  • Integrasi transparan dengan alat perutean seperti HAProxy atau Patroni DCS API untuk mengarahkan traffic aplikasi secara mulus.

2. Konsep Inti & Deep Dive Arsitektur

Untuk memahami bagaimana Patroni dan etcd bekerja secara harmonis, kita harus membedah arsitektur di baliknya (under the hood). Patroni bukanlah sebuah database tersendiri, melainkan sebuah templat Python yang bertindak sebagai agen orkestrasi yang berjalan di setiap node klaster PostgreSQL.

Etcd adalah sebuah distributed reliable key-value store yang menggunakan algoritma konsensus Raft. Etcd bertindak sebagai satu sumber kebenaran (single source of truth) yang mencatat siapa yang berhak memegang status Primary saat ini melalui sebuah leader key dengan mekanisme TTL (Time to Live) atau lease.

+-------------------------------------------------------------+
|                        Application Layer                    | 
|               (Go / Node.js / PHP / Nginx)                  | 
+------------------------------+------------------------------+
                               |
                               v
+-------------------------------------------------------------+
|                        HAProxy / Router                     | 
+--------------+------------------------------+---------------+
               |                              |
               v (Port 5000)                  v (Port 5001)
+------------------------------+    +-------------------------+
|      PostgreSQL Primary      |    |   PostgreSQL Standby    |
|   Managed by Patroni Agent   |    | Managed by Patroni Agent|
+--------------+---------------+    +------------+------------+
               |                                  ^
               +------- Streaming Replication ----+
               |
               v
+-------------------------------------------------------------+
|                           etcd Cluster                      | 
|         (Distributed Consensus Store / Raft Protocol)       | 
+-------------------------------------------------------------+

Alur Kerja di Balik Layar (Under the Hood):

  1. Heartbeat & Lease: Setiap agen Patroni secara periodik memperbarui lease di etcd untuk membuktikan bahwa node tersebut masih hidup dan sehat.
  2. Leader Election: Jika node Primary mati atau terputus dari jaringan, lease di etcd akan kedaluwarsa (expire).
  3. Promosi Standby: Salah satu node Standby yang mendeteksi kedaluwarsa tersebut akan berlomba untuk mengambil alih leader key di etcd. Node yang berhasil mendapatkan key tersebut akan menginstruksikan instance PostgreSQL lokalnya untuk melakukan promosi (pg_ctl promote).
  4. Re-configuration: Agen Patroni lainnya secara otomatis memperbarui konfigurasi replikasi mereka (postgresql.conf dan recovery.conf/standby.signal) untuk mengikuti Primary yang baru.

3. Perbandingan Komparatif / Analisis Pendekatan

Berikut adalah analisis perbandingan mendalam antara beberapa pendekatan HA PostgreSQL yang umum digunakan di industri:

Parameter Patroni + etcd Repmgr (Replication Manager) Pacemaker + Corosync Cloud Native PG (CNPG)
Kompleksitas Setup Sedang Rendah - Sedang Tinggi Rendah (di Kubernetes)
Konsensus Store etcd / Consul / ZooKeeper Tidak Ada (menggunakan DB/SSH) Corosync Kubernetes API Server
Risiko Split-Brain Sangat Rendah (DCS Guarded) Sedang (Tergantung Konfigurasi) Rendah (Fencing / STONITH) Sangat Rendah
Overhead Sumber Daya Rendah (Python + etcd ringan) Sangat Rendah Sedang-Tinggi Tergantung Pod K8s
Waktu Failover (MTTR) 10 - 30 Detik 30 - 60 Detik 15 - 45 Detik 15 - 30 Detik
Lingkungan Terbaik Bare-metal, VM, Hybrid VM Sederhana Enterprise On-Premise Kubernetes Only

[!TIP] Untuk infrastruktur berbasis Virtual Private Server (VPS) atau Cloud Virtual Machine tradisional (AWS EC2, GCP Compute Engine), kombinasi Patroni + etcd adalah standar industri paling stabil dan terbukti di skala produksi besar.


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum memulai instalasi, pastikan Anda menyiapkan minimal 3 buah server (untuk kuorum etcd yang sehat) dengan spesifikasi minimal:

  • OS: Ubuntu 22.04 LTS / Debian 12
  • CPU: 2 Core / 4 Thread
  • RAM: 4 GB
  • Jaringan: Koneksi privat internal berkecepatan tinggi antar node.

Mapping IP Contoh:

  • node1: 192.168.1.10 (etcd, patroni, postgresql)
  • node2: 192.168.1.11 (etcd, patroni, postgresql)
  • node3: 192.168.1.12 (etcd, patroni, postgresql)

Persiapan Sistem Dasar (Jalankan di Semua Node):

# Perbarui sistem dan instal dependensi dasar
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl vim git jq ufw

# Nonaktifkan swap untuk performa database optimal
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# Konfigurasi zona waktu seragam
sudo timedatectl set-timezone UTC

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Instalasi etcd

Instal etcd di ketiga node. Contoh konfigurasi untuk node1 (/etc/etcd/etcd.yml atau via argumen systemd):

sudo apt install -y etcd-server etcd-client

Buat file konfigurasi /etc/etcd/etcd.conf.yml di node1:

name: 'node1'
data-dir: '/var/lib/etcd/node1.etcd'
listen-peer-urls: 'http://192.168.1.10:2380'
listen-client-urls: 'http://192.168.1.10:2379,http://127.0.0.1:2379'
initial-advertise-peer-urls: 'http://192.168.1.10:2380'
advertise-client-urls: 'http://192.168.1.10:2379'
initial-cluster: 'node1=http://192.168.1.10:2380,node2=http://192.168.1.11:2380,node3=http://192.168.1.12:2380'
initial-cluster-token: 'etcd-postgres-cluster'
initial-cluster-state: 'new'

(Ulangi penyesuaian IP untuk node2 dan node3). Aktifkan dan jalankan etcd:

sudo systemctl enable etcd
sudo systemctl restart etcd

Langkah 2: Instalasi PostgreSQL dan Patroni

Instal PostgreSQL dan pustaka Python yang dibutuhkan oleh Patroni di semua node:

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

Instal Patroni menggunakan pip:

sudo pip3 install patroni[etcd3]

Langkah 3: Konfigurasi Patroni YAML

Buat direktori konfigurasi Patroni dan buat file /etc/patroni/postgresql.yml di node1:

scope: postgres-cluster
amespace: /service
name: node1

etcd3:
  hosts:
    - 192.168.1.10:2379
    - 192.168.1.11:2379
    - 192.168.1.12:2379

restapi:
  listen: 192.168.1.10:8008
  connect_address: 192.168.1.10:8008

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      use_slots: true
      parameters:
        max_connections: 200
        shared_buffers: 1GB
        effective_cache_size: 3GB
        maintenance_work_mem: 256MB
        checkpoint_completion_target: 0.9
        wal_buffers: 16MB
        default_statistics_target: 100
        random_page_cost: 1.1
        effective_io_concurrency: 200
        work_mem: 5242kB
        min_wal_size: 1GB
        max_wal_size: 4GB
        max_worker_processes: 4
        max_parallel_workers_per_gather: 2
        max_parallel_workers: 4

  initdb:
    - encoding: UTF8
    - data-checksums

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

postgresql:
  listen: 192.168.1.10:5432
  connect_address: 192.168.1.10:5432
  data_dir: /var/lib/postgresql/15/patroni
  bin_dir: /usr/lib/postgresql/15/bin
  admin_username: postgres
  admin_password: secure_postgres_admin_password
  replication:
    username: replicator
    password: secure_replication_password

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

Langkah 4: Menjalankan Patroni sebagai Systemd Service

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

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

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

[Install]
WantedBy=multi-user.target

Sesuaikan hak akses kepemilikan file data PostgreSQL:

sudo chown -R postgres:postgres /etc/patroni
sudo chown -R postgres:postgres /var/lib/postgresql

sudo systemctl daemon-reload
sudo systemctl enable patroni
sudo systemctl start patroni

Ulangi konfigurasi Patroni di node2 dan node3 dengan menyesuaikan IP masing-masing pada bagian name, restapi.listen, restapi.connect_address, postgresql.listen, dan postgresql.connect_address.


6. Bedah Kode & Penjelasan Detail Baris Kunci

Mari kita bedah parameter krusial dalam file YAML Patroni di atas:

  1. ttl: 30 & loop_wait: 10: Parameter ini menentukan sensitivitas klaster. Agen Patroni melakukan poll ke etcd setiap loop_wait (10 detik). Jika agen Primary gagal memperbarui lease dalam waktu ttl (30 detik), etcd akan mendeklarasikan Primary mati dan membuka pemilihan pemimpin baru.
  2. use_pg_rewind: true: Fitur penyelamatan luar biasa. Jika node Primary lama mati secara mendadak lalu hidup kembali (split-brain minor), pg_regin/pg_rewind memungkinkan node tersebut menyelaraskan ulang riwayat WAL-nya dengan Primary baru tanpa harus melakukan pg_basebackup dari awal.
  3. use_slots: true: Menggunakan replication slots secara otomatis. Ini mencegah node Primary menghapus file WAL sebelum node Standby sempat menerimanya, menghindari situasi di mana replika tertinggal jauh dan rusak secara permanen.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Dalam arsitektur enterprise berbeban tinggi (misalnya sistem pembayaran finansial dengan 10.000 TPS), aplikasi backend tidak boleh terikat secara statis ke IP server database tertentu.

Integrasi dengan HAProxy:

Pasang HAProxy di server terpisah atau di server aplikasi untuk melakukan load balancing dan health checking endpoint Patroni REST API.

Contoh /etc/haproxy/haproxy.cfg:

global
    log /dev/log local0

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

frontend postgres_primary
    bind *:5000
    default_backend postgres_primary_nodes

backend postgres_primary_nodes
    mode tcp
    option httpchk GET /primary
    http-check expect status 200
    default-server inter 3s fall 3 rise 2
    server node1 192.168.1.10:5432 maxconn 200 check port 8008
    server node2 192.168.1.11:5432 maxconn 200 check port 8008
    server node3 192.168.1.12:5432 maxconn 200 check port 8008

frontend postgres_replicas
    bind *:5001
    default_backend postgres_replica_nodes

backend postgres_replica_nodes
    mode tcp
    option httpchk GET /replica
    http-check expect status 200
    default-server inter 3s fall 3 rise 2
    server node1 192.168.1.10:5432 maxconn 200 check port 8008
    server node2 192.168.1.11:5432 maxconn 200 check port 8008
    server node3 192.168.1.12:5432 maxconn 200 check port 8008

Aplikasi Anda cukup mengarahkan koneksi tulis (write) ke haproxy_ip:5000 dan koneksi baca (read-only) ke haproxy_ip:5001.


8. Common Pitfalls, Anti-Patterns & Solusi

[!WARNING] Anti-Pattern Terbesar: Menjalankan klaster etcd dengan jumlah node genap (misal: 2 atau 4 node). Etcd bergantung pada algoritma konsensus Raft yang memerlukan mayoritas mutlak (quorum $N/2 + 1$). Klaster 2 node akan kolaps jika 1 node mati karena kuorum gagal tercapai (1 dari 2 bukanlah mayoritas mutlak).

  1. Kesalahan Konfigurasi TTL Terlalu Pendek:
    • Gejala: Terjadi flapping (promosi berulang-ulang tanpa henti) saat jaringan mengalami lonjakan latensi sesaat.
    • Solusi: Tetapkan nilai ttl minimal 30 detik dan loop_wait 10 detik untuk lingkungan produksi standar.
  2. Firewall Memblokir Port Internal:
    • Gejala: Patroni gagal mendeteksi status etcd.
    • Solusi: Pastikan port 2379, 2380 (etcd), 5432 (PostgreSQL), dan 8008 (Patroni API) diizinkan di dalam jaringan internal menggunakan UFW:
      sudo ufw allow from 192.168.1.0/24 to any port 2379,2380,5432,8008 proto tcp
      

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memvalidasi ketahanan klaster, lakukan pengujian failover secara langsung di lingkunganstaging menggunakan tolok ukur pgbench.

# Inisialisasi data benchmark
pgbench -i -s 50 -h 192.168.1.10 -U postgres postgres

# Jalankan beban kerja transaksi kontinu
pgbench -c 50 -j 4 -T 300 -h 192.168.1.10 -U postgres postgres

Saat pgbench berjalan, matikan paksa node Primary (sudo systemctl stop patroni pada node1). Amati log Patroni dan catat berapa detik waktu yang dibutuhkan oleh aplikasi untuk kembali tersambung secara normal melalui HAProxy.

Parameter Tuning Lanjutan (postgresql.conf via Patroni DCS):

postgresql:
  parameters:
    checkpoint_timeout: '15min'
    max_wal_size: '16GB'
    min_wal_size: '2GB'
    effective_io_concurrency: '300'
    random_page_cost: '1.1'

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan klaster Patroni + etcd ke lingkungan Live Production, pastikan Anda telah memverifikasi daftar periksa berikut:

  • Jumlah node etcd ganjil (minimal 3 node terdistribusi di Availability Zone yang berbeda).
  • Pengujian skenario pemadaman listrik mendadak (Hard Power Off) pada node Primary.
  • Konfigurasi backup otomatis menggunakan pg_barman atau pgBackRest yang terintegrasi dengan penyimpanan S3/MinIO.
  • Pemantauan metrik (Prometheus + Grafana) untuk memantau status patroni_cluster_members, etcd_server_leader_changes, dan replikasi lag.
  • Verifikasi izin akses file kredensial dan enkripsi TLS untuk komunikasi etcd dan Patroni API di lingkungan sensitif.

Dengan menerapkan arsitektur High Availability berbasis Patroni dan etcd ini, infrastruktur backend Anda kini memiliki ketahanan enterprise-grade yang mampu meminimalkan downtime hingga mendekati nol, menjaga konsistensi data secara absolut, dan memberikan ketenangan pikiran bagi seluruh tim engineering.

🏷️ Tags: #High Availability #Postgresql #Patroni #Etcd #Database Administration