Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Yazıda PostgreSQL hata toleransı konusuna nasıl yaklaştığımızı, bizim için neden önemli hale geldiğini ve sonunda ne olduğunu anlatacağım.

Oldukça yüklü bir hizmetimiz var: Dünya çapında 2,5 milyon kullanıcı, her gün 50'den fazla aktif kullanıcı. Sunucular İrlanda'nın bir bölgesinde Amazone'da bulunuyor: 100'den fazla farklı sunucu sürekli çalışıyor ve bunların neredeyse 50'si veritabanlarıyla birlikte.

Arka ucun tamamı, istemciyle sürekli bir websocket bağlantısı sağlayan büyük, monolitik, durum bilgisi olan bir Java uygulamasıdır. Birkaç kullanıcı aynı anda aynı panoda çalıştığında, her değişikliği veritabanına yazdığımız için hepsi değişiklikleri gerçek zamanlı olarak görür. Veritabanlarımıza saniyede yaklaşık 10 bin istek geliyor. Redis'te pik yükte saniyede 80-100K istek yazıyoruz.
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Neden Redis'ten PostgreSQL'e geçtik?

Başlangıçta hizmetimiz, tüm verileri sunucunun RAM'inde saklayan bir anahtar-değer deposu olan Redis ile çalışıyordu.

Redis'in Artıları:

  1. Yüksek yanıt hızı, çünkü her şey hafızada saklanır;
  2. Yedekleme ve çoğaltma kolaylığı.

Redis'in bizim için eksileri:

  1. Gerçek bir işlem yok. Bunları uygulamamız düzeyinde simüle etmeye çalıştık. Ne yazık ki bu her zaman işe yaramıyordu ve çok karmaşık kodların yazılmasını gerektiriyordu.
  2. Veri miktarı hafıza miktarıyla sınırlıdır. Veri miktarı arttıkça bellek de büyüyecek ve sonunda seçilen bulut sunucusunun özelliklerine rastlayacağız; bu, AWS'de bulut sunucusunun türünü değiştirmek için hizmetimizi durdurmayı gerektirir.
  3. Çünkü sürekli olarak düşük gecikme seviyesini korumak gerekiyor. çok sayıda talebimiz var. Bizim için en uygun gecikme seviyesi 17-20 ms'dir. 30-40 ms düzeyinde uygulamamızdan gelen isteklere uzun yanıtlar alıyoruz ve hizmetin bozulmasına neden oluyoruz. Ne yazık ki bu, Eylül 2018'de Redis'li örneklerden birinin herhangi bir nedenle normalden 2 kat daha fazla gecikmeye maruz kalmasıyla başımıza geldi. Sorunu çözmek için planlanmamış bakım nedeniyle hizmeti gün ortasında durdurduk ve sorunlu Redis örneğini değiştirdik.
  4. Koddaki küçük hatalarda bile veri tutarsızlığı elde etmek kolaydır ve daha sonra bu verileri düzeltmek için kod yazmaya çok zaman harcarsınız.

Eksilerini hesaba kattık ve normal işlemlerle ve gecikmeye daha az bağımlı olan daha uygun bir şeye geçmemiz gerektiğini fark ettik. Araştırma yaptım, birçok seçeneği analiz ettim ve PostgreSQL'i seçtim.

1,5 yıldır yeni bir veritabanına geçiyoruz ve verilerin yalnızca küçük bir kısmını taşıdık, bu nedenle artık Redis ve PostgreSQL ile eş zamanlı çalışıyoruz. Veritabanları arasında veri taşıma ve değiştirme aşamaları hakkında daha fazla bilgi şurada yazılmıştır: meslektaşımın makalesi.

İlk taşınmaya başladığımızda uygulamamız doğrudan veritabanı ile çalışıyor ve master Redis ve PostgreSQL'e erişiyordu. PostgreSQL kümesi bir ana birim ve eşzamansız çoğaltma özelliğine sahip bir kopyadan oluşuyordu. Veritabanı şeması şu şekilde görünüyordu:
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

PgBouncer'ı Uygulamak

Biz taşınırken ürün de gelişiyordu: Kullanıcı sayısı ve PostgreSQL ile çalışan sunucu sayısı arttı, bağlantılarımız kopmaya başladı. PostgreSQL her bağlantı için ayrı bir süreç oluşturur ve kaynakları tüketir. Bağlantı sayısını belirli bir noktaya kadar artırabilirsiniz, aksi takdirde optimumun altında veritabanı performansı elde etme şansı vardır. Böyle bir durumda ideal seçenek, tabanın önünde duracak bir bağlantı yöneticisi seçmek olacaktır.

Bağlantı yöneticisi için iki seçeneğimiz vardı: Pgpool ve PgBouncer. Ancak ilki veritabanıyla işlemsel çalışma modunu desteklemiyor, bu yüzden PgBouncer'ı seçtik.

Aşağıdaki çalışma planını kurduk: Uygulamamız, arkasında PostgreSQL ana yöneticilerinin bulunduğu ve her ana bilgisayarın arkasında eşzamansız çoğaltma ile bir kopya bulunan bir PgBouncer'a erişiyor.
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Aynı zamanda veri miktarının tamamını PostgreSQL'de depolayamıyorduk ve veritabanıyla çalışma hızı bizim için önemliydi, bu nedenle PostgreSQL'i uygulama düzeyinde parçalamaya başladık. Yukarıda açıklanan şema bunun için nispeten uygundur: Yeni bir PostgreSQL parçası eklerken, PgBouncer yapılandırmasını güncellemek yeterlidir ve uygulama yeni parçayla hemen çalışabilir.

PgBouncer yük devretme

Bu plan, tek PgBouncer örneğinin öldüğü ana kadar işe yaradı. Tüm bulut sunucularının periyodik olarak ölen donanım üzerinde çalıştığı AWS'deyiz. Bu gibi durumlarda örnek yeni donanıma geçer ve tekrar çalışır. Bu PgBouncer'da oldu, ancak kullanılamaz hale geldi. Bu düşüşün sonucu hizmetimizin 25 dakika süreyle kullanılamaması oldu. AWS, bu gibi durumlar için o zamanlar ülkemizde uygulanmayan kullanıcı tarafı yedekliliğinin kullanılmasını önermektedir.

Bundan sonra PgBouncer ve PostgreSQL kümelerinin hata toleransı konusunu ciddi olarak düşündük çünkü benzer bir durum AWS hesabımızdaki herhangi bir bulut sunucusunda da yaşanabilir.

PgBouncer hata tolerans şemasını şu şekilde oluşturduk: tüm uygulama sunucuları, arkasında iki PgBouncer'ın bulunduğu Ağ Yük Dengeleyicisine erişir. Her PgBouncer, her parçanın aynı PostgreSQL ana bilgisayarına bakar. AWS bulut sunucusunun çökmesi tekrar meydana gelirse tüm trafik başka bir PgBouncer üzerinden yönlendirilir. Network Load Balancer yük devretme işlemi AWS tarafından sağlanır.

Bu şema, yeni PgBouncer sunucularının eklenmesini kolaylaştırır.
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

PostgreSQL Yük Devretme Kümesi Oluşturma

Bu sorunu çözerken farklı seçenekleri değerlendirdik: kendi kendine yazılan yük devretme, repmgr, AWS RDS, Patroni.

Kendi yazdığı senaryolar

Master'ın çalışmasını izleyebilir ve başarısız olursa kopyayı master'a yükseltebilir ve PgBouncer yapılandırmasını güncelleyebilirler.

Bu yaklaşımın avantajları maksimum basitliktir çünkü komut dosyalarını kendiniz yazarsınız ve tam olarak nasıl çalıştıklarını anlarsınız.

Eksileri:

  • Master ölmemiş olabilir, bunun yerine bir ağ arızası oluşmuş olabilir. Bunun farkında olmayan yük devretme, kopyayı ana ağa yükseltirken, eski ana çalışmaya devam edecektir. Sonuç olarak master rolünde iki sunucumuz olacak ve bunlardan hangisinin en son güncel verilere sahip olduğunu bilemeyeceğiz. Bu duruma aynı zamanda bölünmüş beyin de denir;
  • Cevap vermeden kaldık. Bizim yapılandırmamızda, ana kopya ve bir kopya, geçişten sonra kopya ana kopyaya taşınır ve artık kopyalarımız kalmaz, bu nedenle manuel olarak yeni bir kopya eklememiz gerekir;
  • 12 PostgreSQL parçamız varken, yük devretme işleminin ek izlenmesine ihtiyacımız var, bu da 12 kümeyi izlememiz gerektiği anlamına geliyor. Parça sayısındaki artışla birlikte yük devretmeyi de güncellemeyi unutmamalısınız.

Kendi kendine yazılan yük devretme çok karmaşık görünüyor ve önemsiz olmayan bir destek gerektiriyor. Tek bir PostgreSQL kümesiyle bu en kolay seçenek olacaktır ancak ölçeklenmediği için bizim için uygun değildir.

Temsilci

PostgreSQL kümesinin çalışmasını yönetebilen PostgreSQL kümeleri için Çoğaltma Yöneticisi. Aynı zamanda, kutudan çıktığı haliyle otomatik bir yük devretme özelliği yoktur, bu nedenle iş için bitmiş çözümün üzerine kendi "sarmalayıcınızı" yazmanız gerekecektir. Yani her şey kendi kendine yazılan senaryolardan daha da karmaşık hale gelebilir, bu yüzden Repmgr'ı denemedik bile.

AWS RDS'si

İhtiyacımız olan her şeyi destekler, nasıl yedekleme yapılacağını bilir ve bir bağlantı havuzunu korur. Otomatik geçiş özelliği vardır: Ana öğe öldüğünde kopya yeni ana öğe haline gelir ve AWS, dns kaydını yeni ana öğe olarak değiştirir; kopyalar farklı AZ'lerde bulunabilir.

Dezavantajları arasında ince ayarların olmaması yer alır. İnce ayar örneği olarak: örneklerimizin tcp bağlantıları için kısıtlamaları vardır ve bu ne yazık ki RDS'de yapılamaz:

net.ipv4.tcp_keepalive_time=10
net.ipv4.tcp_keepalive_intvl=1
net.ipv4.tcp_keepalive_probes=5
net.ipv4.tcp_retries2=3

Ayrıca AWS RDS'nin normal bulut sunucusu fiyatından neredeyse iki kat daha pahalı olması, bu çözümden vazgeçilmesinin ana nedeniydi.

patroni

Bu, PostgreSQL'i iyi belgelerle, otomatik yük devretmeyle ve github'daki kaynak koduyla yönetmek için kullanılan bir python şablonudur.

Patroni'nin artıları:

  • Her konfigürasyon parametresi anlatılmıştır, nasıl çalıştığı açıktır;
  • Otomatik yük devretme, kutudan çıktığı gibi çalışır;
  • Python'da yazılmıştır ve biz de python'da çok şey yazdığımızdan, sorunlarla başa çıkmamız ve hatta belki de projenin geliştirilmesine yardımcı olmamız daha kolay olacaktır;
  • PostgreSQL'i tamamen yönetir, kümenin tüm düğümlerindeki yapılandırmayı aynı anda değiştirmenize olanak tanır ve yeni yapılandırmayı uygulamak için kümenin yeniden başlatılması gerekiyorsa, bu Patroni kullanılarak tekrar yapılabilir.

Eksileri:

  • PgBouncer ile nasıl doğru şekilde çalışılacağı belgelerde açık değildir. Her ne kadar buna eksi demek zor olsa da, çünkü Patroni'nin görevi PostgreSQL'i yönetmek ve Patroni ile bağlantıların nasıl ilerleyeceği zaten bizim sorunumuz;
  • Patroni'nin büyük hacimlerde uygulanmasına ilişkin az sayıda örnek bulunurken, sıfırdan uygulanmasına ilişkin birçok örnek bulunmaktadır.

Sonuç olarak failover kümesi oluşturmak için Patroni’yi seçtik.

Patroni Uygulama Süreci

Patroni'den önce, bir ana ve eşzamansız çoğaltma ile bir kopyadan oluşan konfigürasyonda 12 PostgreSQL parçamız vardı. Uygulama sunucuları, veritabanlarına, arkasında PgBouncer'lı iki örnek bulunan Network Load Balancer aracılığıyla erişiyordu ve bunların arkasında da tüm PostgreSQL sunucuları vardı.
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Patroni'yi uygulamak için dağıtılmış bir depolama kümesi yapılandırması seçmemiz gerekiyordu. Patroni, etcd, Zookeeper, Consul gibi dağıtılmış konfigürasyon depolama sistemleriyle çalışır. Piyasada Vault ile birlikte çalışan tam teşekküllü bir Consul kümemiz var ve artık onu kullanmıyoruz. Consul'u amacına uygun olarak kullanmaya başlamak için harika bir neden.

Patroni Konsolos ile nasıl çalışır?

Üç düğümden oluşan bir Consul kümemiz ve bir lider ve bir kopyadan oluşan bir Patroni kümemiz var (Patroni'de efendiye küme lideri, kölelere kopyalar denir). Patroni kümesinin her bir örneği sürekli olarak kümenin durumu hakkında Konsolos'a bilgi gönderir. Bu nedenle Consul'dan Patroni kümesinin mevcut konfigürasyonunu ve şu anda kimin lider olduğunu her zaman öğrenebilirsiniz.

Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Patroni'yi Consul'a bağlamak için, Consul ile nasıl çalıştığımıza ve isteğe bağlı olarak bağlantı şemasına bağlı olarak http veya https formatında bir ana bilgisayar belirtmeniz gerektiğini söyleyen resmi belgeleri incelemek yeterlidir:

host: the host:port for the Consul endpoint, in format: http(s)://host:port
scheme: (optional) http or https, defaults to http

Basit görünüyor ama tuzaklar burada başlıyor. Consul ile https üzerinden güvenli bir bağlantı üzerinden çalışıyoruz ve bağlantı yapılandırmamız şu şekilde görünecek:

consul:
  host: https://server.production.consul:8080 
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

Ama bu işe yaramıyor. Patroni başlangıçta Consul'a bağlanamıyor çünkü yine de http üzerinden geçmeye çalışıyor.

Patroni'nin kaynak kodu sorunun çözümüne yardımcı oldu. İyi ki python ile yazılmış. Ana bilgisayar parametresinin hiçbir şekilde ayrıştırılmadığı ve protokolün şemada belirtilmesi gerektiği ortaya çıktı. Consul ile çalışmaya yönelik çalışma konfigürasyon bloğu bizim için şu şekilde görünüyor:

consul:
  host: server.production.consul:8080
  scheme: https
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

konsolosluk şablonu

Bu nedenle yapılandırma için depolamayı seçtik. Şimdi Patroni kümesindeki lideri değiştirirken PgBouncer'ın konfigürasyonunu nasıl değiştireceğini anlamamız gerekiyor. Dokümantasyonda bu sorunun cevabı yok çünkü. orada prensip olarak PgBouncer ile çalışma anlatılmamıştır.

Çözüm arayışında, Сonsul şablonunun PgBouncer ve Patroni'yi eşleştirmede çok yardımcı olduğunu yazan bir makale bulduk (ne yazık ki başlığını hatırlamıyorum). Bu bizi Consul-template'in nasıl çalıştığını araştırmaya yöneltti.

Consul-template'in Consul'daki PostgreSQL kümesinin yapılandırmasını sürekli olarak izlediği ortaya çıktı. Lider değiştiğinde PgBouncer konfigürasyonunu günceller ve yeniden yüklemek için bir komut gönderir.

Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Şablonun büyük bir artısı, kod olarak saklanmasıdır; bu nedenle, yeni bir parça eklerken, yeni bir taahhütte bulunmak ve şablonu otomatik olarak güncellemek yeterlidir; Kod olarak Altyapı ilkesini destekler.

Patroni ile yeni mimari

Sonuç olarak, aşağıdaki çalışma planını elde ettik:
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Tüm uygulama sunucuları dengeleyiciye erişir → arkasında iki PgBouncer örneği vardır → her örnekte, her Patroni kümesinin durumunu izleyen ve mevcut lidere istek gönderen PgBouncer yapılandırmasının uygunluğunu izleyen Consul-template başlatılır. her kümenin.

Manuel test

Bu şemayı küçük bir test ortamında başlatmadan önce çalıştırdık ve otomatik geçişin çalışmasını kontrol ettik. Tahtayı açtılar, çıkartmayı hareket ettirdiler ve o anda kümenin liderini “öldürdüler”. AWS'de bu, örneği konsol aracılığıyla kapatmak kadar basittir.

Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Çıkartma 10-20 saniye içinde geri döndü ve ardından tekrar normal şekilde hareket etmeye başladı. Bu, Patroni kümesinin doğru çalıştığı anlamına gelir: lideri değiştirdi, bilgileri Consul'a gönderdi ve Сonsul-template bu bilgiyi hemen aldı, PgBouncer yapılandırmasını değiştirdi ve yeniden yükleme komutunu gönderdi.

Yüksek yük altında nasıl hayatta kalabilir ve kesinti süresini minimumda tutabilirsiniz?

Her şey mükemmel çalışıyor! Ancak yeni sorular var: Yüksek yük altında nasıl çalışacak? Üretimdeki her şey hızlı ve güvenli bir şekilde nasıl kullanıma sunulur?

Yük testi yaptığımız test ortamı ilk soruyu cevaplamamıza yardımcı oluyor. Mimari açıdan üretimle tamamen aynıdır ve üretime yaklaşık olarak eşit hacimde test verileri üretmiştir. Test sırasında PostgreSQL ustalarından birini "öldürmeye" karar veriyoruz ve ne olacağını görüyoruz. Ancak bundan önce, otomatik yuvarlamayı kontrol etmek önemlidir, çünkü bu ortamda birkaç PostgreSQL parçamız var, bu nedenle üretimden önce yapılandırma komut dosyalarının mükemmel testini gerçekleştireceğiz.

Her iki görev de iddialı görünüyor ancak PostgreSQL 9.6'ya sahibiz. Hemen 11.2'ye yükseltebilir miyiz?

Bunu 2 adımda yapmaya karar veriyoruz: önce 11.2'ye yükseltin, ardından Patroni'yi başlatın.

PostgreSQL güncellemesi

PostgreSQL sürümünü hızlı bir şekilde güncellemek için bu seçeneği kullanın -kDiskte sabit bağlantıların oluşturulduğu ve verilerinizi kopyalamanıza gerek olmayan. 300-400 GB bazlarda güncelleme 1 saniye sürer.

Çok fazla parçamız var, bu nedenle güncellemenin otomatik olarak yapılması gerekiyor. Bunu yapmak için tüm güncelleme sürecini bizim için yürüten bir Ansible playbook yazdık:

/usr/lib/postgresql/11/bin/pg_upgrade 
<b>--link </b>
--old-datadir='' --new-datadir='' 
 --old-bindir=''  --new-bindir='' 
 --old-options=' -c config_file=' 
 --new-options=' -c config_file='

Burada yükseltmeye başlamadan önce bunu parametreyle gerçekleştirmeniz gerektiğini unutmamak önemlidir. --kontrol etmekyükseltebileceğinizden emin olmak için. Komut dosyamız ayrıca yükseltme süresince yapılandırmaların değiştirilmesini de sağlar. Senaryomuz 30 saniyede tamamlandı, bu mükemmel bir sonuç.

Patroni'yi başlat

İkinci sorunu çözmek için Patroni konfigürasyonuna bakmanız yeterli. Resmi depoda, Patroni'yi ilk başlattığınızda yeni bir veritabanının başlatılmasından sorumlu olan initdb ile örnek bir yapılandırma vardır. Ancak zaten hazır bir veritabanımız olduğundan, bu bölümü konfigürasyondan kaldırdık.

Patroni'yi mevcut bir PostgreSQL kümesine kurup çalıştırmaya başladığımızda yeni bir sorunla karşılaştık: her iki sunucu da lider olarak başladı. Patroni, kümenin erken durumu hakkında hiçbir şey bilmiyor ve her iki sunucuyu da aynı ada sahip iki ayrı küme olarak başlatmaya çalışıyor. Bu sorunu çözmek için, ikincil cihazdaki verileri içeren dizini silmeniz gerekir:

rm -rf /var/lib/postgresql/

Bunun yalnızca köle üzerinde yapılması gerekiyor!

Temiz bir kopya bağlandığında, Patroni bir temel yedekleme lideri oluşturur ve onu kopyaya geri yükler ve ardından duvar günlüklerine göre mevcut durumu yakalar.

Karşılaştığımız diğer bir zorluk da tüm PostgreSQL kümelerinin varsayılan olarak main olarak adlandırılmasıdır. Her kümenin diğeri hakkında hiçbir şey bilmediği durumlarda bu normaldir. Ancak Patroni'yi kullanmak istediğinizde tüm kümelerin benzersiz bir isme sahip olması gerekir. Çözüm PostgreSQL yapılandırmasındaki küme adını değiştirmektir.

yük testi

Panolarda kullanıcı deneyimini simüle eden bir test başlattık. Yük ortalama günlük değerimize ulaştığında aynı testi tekrarladık, PostgreSQL lideriyle bir örneği kapattık. Otomatik yük devretme beklediğimiz gibi çalıştı: Patroni lideri değiştirdi, Consul-template PgBouncer yapılandırmasını güncelledi ve yeniden yükleme için bir komut gönderdi. Grafana'daki grafiklerimize göre veritabanına bağlantı ile ilgili sunuculardan 20-30 saniyelik gecikmeler ve az miktarda hatalar olduğu açıktı. Bu normal bir durumdur, bu tür değerler yük devretmemiz için kabul edilebilir ve hizmet kesintisinden kesinlikle daha iyidir.

Patroni'yi üretime getirmek

Sonuç olarak aşağıdaki planı hazırladık:

  • Consul şablonunu PgBouncer sunucularına dağıtın ve başlatın;
  • PostgreSQL'in 11.2 sürümüne güncellemesi;
  • Kümenin adını değiştirin;
  • Patroni Kümesini başlatıyoruz.

Aynı zamanda, planımız neredeyse her zaman ilk noktayı belirlememize olanak tanıyor, her PgBouncer'ı sırayla işten çıkarabiliyor ve consul-template'i konuşlandırıp çalıştırabiliyoruz. Biz de öyle yaptık.

Hızlı dağıtım için Ansible'ı kullandık, çünkü zaten tüm oyun kitaplarını bir test ortamında test ettik ve tüm betiğin yürütme süresi her parça için 1,5 ila 2 dakika arasındaydı. Hizmetimizi durdurmadan her şeyi sırayla her parçaya dağıtabiliriz, ancak her PostgreSQL'i birkaç dakikalığına kapatmamız gerekir. Bu durumda verileri bu shard üzerinde bulunan kullanıcılar şu an için tam olarak çalışamıyor ve bu bizim açımızdan kabul edilemez.

Bu durumdan çıkış yolu ise 3 ayda bir yapılan planlı bakımlardı. Bu, hizmetimizi tamamen kapattığımız ve veritabanı örneklerimizi yükselttiğimiz zamanlanmış çalışma için bir penceredir. Bir sonraki pencereye kadar bir hafta kaldı ve bekleyip daha fazla hazırlanmaya karar verdik. Bekleme süresi boyunca kendimizi ek olarak güvence altına aldık: En son verilerin saklanmaması durumunda her PostgreSQL parçası için yedek bir kopya oluşturduk ve her parça için Patroni kümesinde yeni bir kopya olması gereken yeni bir örnek ekledik. Verileri silmek için bir komut çalıştırmamak için. Bütün bunlar hata riskinin en aza indirilmesine yardımcı oldu.
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Hizmetimizi yeniden başlattık, her şey olması gerektiği gibi çalıştı, kullanıcılar çalışmaya devam etti ancak grafiklerde Consul sunucularında anormal derecede yüksek bir yük olduğunu fark ettik.
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Bunu neden test ortamında göremedik? Bu sorun, Altyapıyı kod ilkesi olarak takip etmenin ve test ortamlarından üretime kadar tüm altyapıyı iyileştirmenin gerekli olduğunu çok iyi göstermektedir. Aksi takdirde karşılaştığımız soruna ulaşmamız çok kolaydır. Ne oldu? Consul önce üretimde, ardından test ortamlarında göründü, sonuç olarak test ortamlarında Consul'un sürümü üretimdekinden daha yüksekti. Sürümlerden yalnızca birinde, consul-template ile çalışırken CPU sızıntısı çözüldü. Bu nedenle Consul'u güncelleyerek sorunu çözdük.

Patroni kümesini yeniden başlat

Ancak şüphelenmediğimiz yeni bir sorunla karşı karşıyayız. Consul'u güncellerken, consul izin komutunu kullanarak Consul düğümünü kümeden kaldırırız → Patroni başka bir Consul sunucusuna bağlanır → her şey çalışır. Ancak Consul kümesinin son örneğine ulaştığımızda ve ona consul Leave komutunu gönderdiğimizde, tüm Patroni kümeleri yeniden başlatıldı ve günlüklerde aşağıdaki hatayı gördük:

ERROR: get_cluster
Traceback (most recent call last):
...
RetryFailedError: 'Exceeded retry deadline'
ERROR: Error communicating with DCS
<b>LOG: database system is shut down</b>

Patroni kümesi, kendi kümesiyle ilgili bilgileri alamadı ve yeniden başlatıldı.

Bir çözüm bulmak için Patroni yazarlarıyla github'daki bir sayı aracılığıyla iletişime geçtik. Yapılandırma dosyalarımızda iyileştirmeler önerdiler:

consul:
 consul.checks: []
bootstrap:
 dcs:
   retry_timeout: 8

Sorunu bir test ortamında tekrarlamayı başardık ve bu seçenekleri orada test ettik ancak ne yazık ki işe yaramadı.

Sorun hala çözülmemiş durumda. Aşağıdaki çözümleri denemeyi planlıyoruz:

  • Her Patroni kümesi örneğinde Consul-agent kullanın;
  • Koddaki sorunu düzeltin.

Hatanın nerede oluştuğunu anlıyoruz: Sorun muhtemelen yapılandırma dosyası aracılığıyla geçersiz kılınmayan varsayılan zaman aşımının kullanılmasından kaynaklanmaktadır. Son Consul sunucusu kümeden kaldırıldığında tüm Consul kümesi bir saniyeden fazla askıda kalıyor, bu nedenle Patroni kümenin durumunu alamıyor ve tüm kümeyi tamamen yeniden başlatıyor.

Neyse ki başka hatayla karşılaşmadık.

Patroni kullanmanın sonuçları

Patroni'nin başarılı lansmanından sonra her kümeye ek bir kopya ekledik. Artık her kümede bir yeter sayı var: geçiş sırasında bölünmüş beyin durumunda güvenlik ağı için bir lider ve iki kopya.
Yük Devretme Kümesi PostgreSQL + Patroni. Uygulama deneyimi

Patroni üç aydan fazla bir süredir üretim üzerinde çalışıyor. Bu süre zarfında bize yardım etmeyi zaten başardı. Yakın zamanda AWS'de kümelerden birinin lideri öldü, otomatik yük devretme çalıştı ve kullanıcılar çalışmaya devam etti. Patroni asıl görevini yerine getirdi.

Patroni kullanımının küçük bir özeti:

  • Yapılandırma değişikliklerinin kolaylığı. Bir örnekteki yapılandırmayı değiştirmek yeterlidir ve kümenin tamamına çekilecektir. Yeni konfigürasyonun uygulanması için yeniden başlatma gerekiyorsa Patroni bunu size bildirecektir. Patroni tek bir komutla tüm kümeyi yeniden başlatabilir ve bu da çok kullanışlıdır.
  • Otomatik yük devretme çalışıyor ve bize yardımcı olmayı zaten başardı.
  • Uygulama kesintisi olmadan PostgreSQL güncellemesi. Öncelikle replikaları yeni sürüme güncellemeli, ardından Patroni kümesindeki lideri değiştirip eski lideri güncellemelisiniz. Bu durumda otomatik yük devretme için gerekli test gerçekleşir.

Kaynak: habr.com

Yorum ekle