PostgreSQL Streaming Replikasyon ve Patroni ile Yüksek Erişilebilirlik Mimarisi
Veritabanı sistemlerinin kesintisiz çalışması, modern uygulamaların en temel gereksinimlerinden biridir. PostgreSQL, doğal olarak güçlü bir veritabanı platformu olsa da, tek bir sunucuda çalışması durumunda tek hata noktası (Single Point of Failure - SPoF) riski taşır. Bu riski ortadan kaldırmak ve yüksek erişilebilirliği (High Availability - HA) sağlamak için PostgreSQL'in streaming replikasyon yetenekleri ile Patroni gibi otomasyon araçlarını birleştirmek kritik öneme sahiptir.
PostgreSQL Streaming Replikasyon Temelleri
PostgreSQL'in streaming replikasyonu, ana veritabanı sunucusundaki (primary) değişikliklerin neredeyse gerçek zamanlı olarak bir veya daha fazla yedek sunucuya (standby) aktarılması prensibine dayanır. Bu süreç, PostgreSQL'in Write-Ahead Log (WAL) mekanizması aracılığıyla gerçekleşir. Primary sunucu, tüm değişiklikleri WAL segmentlerine yazar ve bu segmentler, standby sunuculara gönderilir. Standby sunucular, bu WAL kayıtlarını uygulayarak kendilerini primary ile senkronize tutar.
Replikasyon Modları: Asenkron ve Senkron
- Asenkron Replikasyon: Primary sunucu, WAL kayıtlarını standby sunucuların alıp almadığını beklemeden işlemlere devam eder. Bu mod, yüksek performans sunar ancak primary arızalandığında, standby sunucuda henüz uygulanmamış son verilerin kaybı riski vardır.
- Senkron Replikasyon: Primary sunucu, bir işlemin commit edildiğini kabul etmeden önce, WAL kayıtlarının en az bir standby sunucu tarafından başarıyla alındığını ve uygulandığını bekler. Bu, veri kaybı riskini ortadan kaldırır ancak gecikme (latency) ekleyerek performansı düşürebilir. Genellikle, yüksek veri tutarlılığı gerektiren kritik sistemlerde tercih edilir.
Temel bir streaming replikasyon kurulumu için postgresql.conf ve pg_hba.conf dosyalarında ayarlamalar yapmak ve ardından pg_basebackup ile bir başlangıç yedeği almak gerekir.
# postgresql.conf (Primary)wal_level = replica # veya hot_standby, logicalmax_wal_senders = 10 # Replikasyon bağlantı sayısıwal_keep_segments = 64 # WAL segmentlerini tutma süresi (gerektiğinde artırılabilir)archive_mode = on # WAL arşivlemeyi etkinleştirarchive_command = 'cp %p /path/to/wal_archive/%f' # WAL dosyalarını arşivleme komutu# pg_hba.conf (Primary)host replication repl_user 0.0.0.0/0 md5# Standby sunucuda başlangıç yedeği alma (Primary çalışır durumdayken)pg_basebackup -h primary_ip -D /var/lib/postgresql/data -U repl_user -P -v -R-R parametresi, standby sunucusunun başlangıçta bir recovery.conf (veya 12+ sürümlerinde postgresql.auto.conf içinde) dosyası oluşturmasını sağlar ve bu, sunucunun bir standby olarak başlatılması için gereklidir.
Patroni: PostgreSQL Yüksek Erişilebilirlik Orkestrasyonu
PostgreSQL'in yerel streaming replikasyonu güçlü olsa da, primary sunucu arızalandığında otomatik failover (yedek sunucuya geçiş), split-brain senaryolarının yönetimi ve yeni bir primary'nin seçimi gibi görevler manuel müdahale gerektirir. İşte bu noktada Patroni devreye girer. Patroni, PostgreSQL için bir yüksek erişilebilirlik şablonu olup, dağıtılmış bir konsensüs sistemi (DCS) kullanarak (Etcd, Consul, ZooKeeper gibi) kümenin durumunu izler, lider seçimi yapar ve otomatik failover ve switchover operasyonlarını yönetir.
Patroni'nin Çalışma Prensibi
Her PostgreSQL düğümünde çalışan bir Patroni ajanı bulunur. Bu ajanlar sürekli olarak PostgreSQL örneğinin sağlığını kontrol eder ve kümenin durumunu DCS'e bildirir. Patroni, DCS'i kullanarak bir lider (primary) seçer ve diğer düğümleri standby olarak yapılandırır. Lider arızalandığında, Patroni otomatik olarak yeni bir lider seçer ve eski standby düğümlerini yeni lidere yönlendirir.
Gerçek Dünya Üretim Senaryosu: AWS üzerinde Patroni Kümesi
Bir e-ticaret uygulamasının kritik envanter veritabanı için AWS üzerinde üç düğümlü bir PostgreSQL/Patroni kümesi kuralım. Senaryo gereksinimleri: yüksek erişilebilirlik, otomatik failover, düşük RTO (Recovery Time Objective) ve RPO (Recovery Point Objective).
- Altyapı Hazırlığı: Üç adet EC2 instance (m5.large veya daha iyisi) farklı Availability Zone'larda konumlandırılır. Her instance'a ayrı EBS birimleri (io1/io2 Block Express) veritabanı ve WAL dizinleri için eklenir. Bir VPC içinde özel alt ağlar ve güvenlik grupları oluşturulur. Patroni ve PostgreSQL portları (örneğin, 8008 ve 5432) küme içindeki düğümler arasında açık olmalıdır.
- DCS Seçimi: Bu senaryo için Etcd'yi tercih edelim. Her Patroni düğümünde yerel bir Etcd istemcisi çalışabilir veya ayrı, daha küçük bir Etcd kümesi kurulabilir. Basitlik açısından, genellikle Patroni düğümlerinin kendileri bir Etcd kümesi oluşturur.
- Kurulum ve Yapılandırma: Her EC2 instance'ına PostgreSQL ve Patroni yüklenir.
# patroni.yml (Örnek Yapılandırma)scope: my_pg_cluster # Küme adınamespace: /service/patroni/my_pg_cluster # DCS'teki yolrestapi: listen: 0.0.0.0:8008 connect_address: <EC2_Private_IP>:8008postgresql: listen: 0.0.0.0:5432 connect_address: <EC2_Private_IP>:5432 data_dir: /var/lib/postgresql/data bin_dir: /usr/lib/postgresql/14/bin pgpass: /etc/patroni/pgpass create_replica_method: - basebackup parameters: wal_level: replica hot_standby: 'on' max_connections: 100 max_wal_senders: 10 wal_log_hints: 'on' max_replication_slots: 10 archive_mode: 'on' archive_command: 'cp %p /mnt/wal_archive/%f' authentication: replication: username: repl_user password: repl_password superuser: username: admin_user password: admin_password callbacks: on_start: "/usr/local/bin/patroni_start.sh" on_stop: "/usr/local/bin/patroni_stop.sh" on_role_change: "/usr/local/bin/patroni_role_change.sh"etcd: host: '<Etcd_Member_1_IP>:2379,<Etcd_Member_2_IP>:2379,<Etcd_Member_3_IP>:2379' ttl: 30 # Saniye cinsinden Patroni lider kiralama süresiYukarıdaki yapılandırmada, scope küme adını, namespace ise DCS'teki yolu belirtir. postgresql bölümü, PostgreSQL'in kendi parametrelerini içerir. etcd bölümü, Patroni'nin DCS olarak Etcd ile nasıl iletişim kuracağını tanımlar. ttl parametresi, liderin ne kadar süreyle aktif kabul edileceğini belirler; bu süre zarfında liderin periyodik olarak kendisini DCS'e kaydetmesi gerekir. Aksi takdirde, Patroni yeni bir lider seçimi başlatır.
Başlangıçta, tüm Patroni servisleri başlatılır. İlk çalışan Patroni, kümenin liderliğini üstlenir ve bir PostgreSQL primary başlatır. Diğer Patroni düğümleri, pg_basebackup kullanarak primary'den bir basebackup alır ve standby olarak yapılandırılır.
# Patroni küme durumunu kontrol etmepatronictl list my_pg_cluster+ Cluster: my_pg_cluster (6900403362095982022) --+----+-----------+----+-----------+----+---------+| Member | Host | Role | State | TL | Lag in MB ||--------+---------------+---------+--------+----+-----------|| pg-node-1 | 10.0.1.10 | Leader | running| 1 | || pg-node-2 | 10.0.2.20 | Replica | running| 1 | 0 || pg-node-3 | 10.0.3.30 | Replica | running| 1 | 0 |+--------+---------------+---------+--------+----+---------+Failover ve Switchover Testi
Üretim ortamında, Patroni'nin failover yeteneğini test etmek hayati öneme sahiptir.
- Yapay Arıza Oluşturma: Primary sunucuyu durdurarak (örneğin,
sudo systemctl stop postgresqlveya EC2 instance'ı sonlandırarak) Patroni'nin tepkisini gözlemleyin. Patroni, belirlenenttlsüresi sonunda primary'nin kaydını DCS'ten düşürür ve otomatik olarak yeni bir lider seçer. - Switchover: Planlı bir bakım veya primary'nin manuel olarak değiştirilmesi gerektiğinde
patronictl switchoverkomutu kullanılır. Bu, mevcut primary'den bir standby'a kontrollü bir geçiş sağlar.
# Planlı switchoverpatronictl switchover my_pg_clusterPatroni, bu komutla mevcut primary'yi graceful bir şekilde kapatır, seçilen standby'ı primary yapar ve diğer standby'ları yeni primary'e yönlendirir.
Uygulama Bağlantısı
Uygulamalar, veritabanına doğrudan bir IP adresi ile bağlanmak yerine, AWS Route 53 gibi bir DNS hizmetini kullanarak bir CNAME kaydı (örn. db.mywebapp.com) ile bağlanmalıdır. Patroni, lider değiştiğinde bu DNS kaydını güncelleyebilir veya daha iyisi, bir load balancer (örn. AWS NLB) veya HAProxy gibi bir mekanizma önüne konularak bağlantılar otomatik olarak doğru primary'ye yönlendirilir.
Bu mimari, veritabanı düzeyinde yüksek erişilebilirliği garanti eder. Primary arızalandığında, Patroni saniyeler içinde yeni bir primary yükseltir ve veri kaybını minimuma indirir (asenkron replikasyonda küçük bir pencere, senkron replikasyonda sıfır veri kaybı).
Sonuç
PostgreSQL streaming replikasyonu ve Patroni'nin birleşimi, veritabanı altyapıları için son derece sağlam, ölçeklenebilir ve yüksek erişilebilir bir çözüm sunar. Otomatik failover, self-healing yetenekleri ve dinamik küme yönetimi sayesinde, operasyonel yük azalır ve kritik iş yükleri için kesintisiz hizmet güvence altına alınır. Bu kombinasyon, özellikle AWS gibi bulut platformlarında, esnek ve dayanıklı veritabanı hizmetleri oluşturmak isteyen kuruluşlar için vazgeçilmez bir stratejidir.