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):
- Heartbeat & Lease: Setiap agen Patroni secara periodik memperbarui lease di etcd untuk membuktikan bahwa node tersebut masih hidup dan sehat.
- Leader Election: Jika node Primary mati atau terputus dari jaringan, lease di etcd akan kedaluwarsa (expire).
- 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). - Re-configuration: Agen Patroni lainnya secara otomatis memperbarui konfigurasi replikasi mereka (
postgresql.confdanrecovery.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:
ttl: 30&loop_wait: 10: Parameter ini menentukan sensitivitas klaster. Agen Patroni melakukan poll ke etcd setiaploop_wait(10 detik). Jika agen Primary gagal memperbarui lease dalam waktuttl(30 detik), etcd akan mendeklarasikan Primary mati dan membuka pemilihan pemimpin baru.use_pg_rewind: true: Fitur penyelamatan luar biasa. Jika node Primary lama mati secara mendadak lalu hidup kembali (split-brain minor),pg_regin/pg_rewindmemungkinkan node tersebut menyelaraskan ulang riwayat WAL-nya dengan Primary baru tanpa harus melakukan pg_basebackup dari awal.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).
- Kesalahan Konfigurasi TTL Terlalu Pendek:
- Gejala: Terjadi flapping (promosi berulang-ulang tanpa henti) saat jaringan mengalami lonjakan latensi sesaat.
- Solusi: Tetapkan nilai
ttlminimal 30 detik danloop_wait10 detik untuk lingkungan produksi standar.
- Firewall Memblokir Port Internal:
- Gejala: Patroni gagal mendeteksi status etcd.
- Solusi: Pastikan port
2379,2380(etcd),5432(PostgreSQL), dan8008(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_barmanataupgBackRestyang 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.