Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Məqalədə sizə PostgreSQL-də nasazlığa dözümlülük məsələsinə necə yanaşdığımızı, bunun bizim üçün niyə vacib olduğunu və sonda nə baş verdiyini izah edəcəyəm.

Bizim yüksək yüklənmiş xidmətimiz var: dünya üzrə 2,5 milyon istifadəçi, hər gün 50K+ aktiv istifadəçi. Serverlər İrlandiyanın bir bölgəsindəki Amazone-də yerləşir: 100-dən çox müxtəlif serverlər daim işləyir, onlardan təxminən 50-si verilənlər bazası ilədir.

Bütün backend müştəri ilə daimi veb-soket əlaqəsini saxlayan böyük monolit statuslu Java proqramıdır. Bir neçə istifadəçi eyni lövhədə eyni vaxtda işlədikdə, onların hamısı dəyişiklikləri real vaxt rejimində görür, çünki biz hər dəyişikliyi verilənlər bazasına yazırıq. Verilənlər bazalarımıza saniyədə təxminən 10K sorğumuz var. Redis-də pik yükdə saniyədə 80-100K sorğu yazırıq.
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Redis-dən PostgreSQL-ə niyə keçdik

Əvvəlcə xidmətimiz serverin RAM-da bütün məlumatları saxlayan əsas dəyər anbarı olan Redis ilə işləyirdi.

Redis-in üstünlükləri:

  1. Yüksək cavab sürəti, çünki hər şey yaddaşda saxlanılır;
  2. Yedəkləmə və təkrarlama asanlığı.

Redis-in bizim üçün mənfi cəhətləri:

  1. Real alqı-satqı yoxdur. Biz onları tətbiqimiz səviyyəsində simulyasiya etməyə çalışdıq. Təəssüf ki, bu, həmişə yaxşı nəticə vermir və çox mürəkkəb kodun yazılmasını tələb edirdi.
  2. Məlumatların miqdarı yaddaşın miqdarı ilə məhdudlaşır. Məlumatın miqdarı artdıqca yaddaş da artacaq və sonda biz seçilmiş nümunənin xüsusiyyətləri ilə tanış olacağıq, bu da AWS-də nümunənin növünü dəyişdirmək üçün xidmətimizi dayandırmağı tələb edir.
  3. Daim aşağı gecikmə səviyyəsini saxlamaq lazımdır, çünki. çoxlu sayda müraciətimiz var. Bizim üçün optimal gecikmə səviyyəsi 17-20 ms-dir. 30-40 ms səviyyəsində tətbiqimizdən və xidmətin pisləşməsindən sorğulara uzun cavablar alırıq. Təəssüf ki, bu, 2018-ci ilin sentyabrında başımıza gəldi, Redis ilə olan nümunələrdən biri nədənsə adi haldan 2 dəfə çox gecikmə aldı. Problemi həll etmək üçün planlaşdırılmamış texniki xidmət üçün günün ortasında xidməti dayandırdıq və problemli Redis instansiyasını əvəz etdik.
  4. Koddakı kiçik səhvlərlə belə məlumat uyğunsuzluğunu əldə etmək asandır və sonra bu məlumatları düzəltmək üçün kod yazmağa çox vaxt sərf edir.

Mənfi cəhətləri nəzərə aldıq və başa düşdük ki, normal əməliyyatlar və gecikmədən daha az asılılıqla daha rahat bir şeyə keçmək lazımdır. Araşdırma apardı, bir çox variantları təhlil etdi və PostgreSQL-i seçdi.

Artıq 1,5 ildir ki, yeni verilənlər bazasına keçirik və məlumatların yalnız kiçik bir hissəsini köçürdük, ona görə də indi Redis və PostgreSQL ilə eyni vaxtda işləyirik. Verilənlər bazaları arasında məlumatların köçürülməsi və dəyişdirilməsi mərhələləri haqqında daha çox məlumat yazılmışdır həmkarımın məqaləsi.

Biz ilk köçməyə başlayanda tətbiqimiz birbaşa verilənlər bazası ilə işləyirdi və master Redis və PostgreSQL-ə daxil olur. PostgreSQL klasteri master və asinxron replikasiyaya malik replikadan ibarət idi. Verilənlər bazası sxemi belə görünürdü:
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

PgBouncer tətbiq edilir

Biz hərəkət edərkən məhsul da inkişaf edirdi: istifadəçilərin sayı və PostgreSQL ilə işləyən serverlərin sayı artdı və bizdə əlaqələr yox olmağa başladı. PostgreSQL hər bir əlaqə üçün ayrıca proses yaradır və resursları sərf edir. Bağlantıların sayını müəyyən bir nöqtəyə qədər artıra bilərsiniz, əks halda suboptimal verilənlər bazası performansını əldə etmək şansı var. Belə bir vəziyyətdə ideal seçim, bazanın qarşısında dayanacaq bir əlaqə menecerini seçmək olardı.

Bağlantı meneceri üçün iki seçimimiz var idi: Pgpool və PgBouncer. Lakin birincisi verilənlər bazası ilə işləməyin tranzaksiya rejimini dəstəkləmir, ona görə də biz PgBouncer-i seçdik.

Aşağıdakı iş sxemini qurduq: tətbiqimiz bir PgBouncer-ə daxil olur, onun arxasında PostgreSQL ustaları və hər masterin arxasında asinxron replikasiya ilə bir replika var.
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Eyni zamanda, biz PostgreSQL-də məlumatların bütün həcmini saxlaya bilmədik və verilənlər bazası ilə işləmə sürəti bizim üçün vacib idi, ona görə də PostgreSQL-i tətbiq səviyyəsində parçalamağa başladıq. Yuxarıda təsvir edilən sxem bunun üçün nisbətən əlverişlidir: yeni PostgreSQL parçasını əlavə edərkən PgBouncer konfiqurasiyasını yeniləmək kifayətdir və proqram dərhal yeni parça ilə işləyə bilər.

PgBouncer uğursuzluq

Bu sxem yeganə PgBouncer nümunəsinin öldüyü ana qədər işlədi. Biz AWS-dəyik, burada bütün nümunələr vaxtaşırı ölən aparat üzərində işləyir. Belə hallarda, nümunə sadəcə yeni aparata keçir və yenidən işləyir. Bu, PgBouncer ilə baş verdi, lakin əlçatmaz oldu. Bu payızın nəticəsi 25 dəqiqə ərzində xidmətimizin əlçatmazlığı oldu. AWS bu cür hallar üçün o vaxt ölkəmizdə tətbiq olunmayan istifadəçi tərəfi ehtiyatdan istifadə etməyi tövsiyə edir.

Bundan sonra biz PgBouncer və PostgreSQL klasterlərinin nasazlıqlara qarşı dözümlülüyü barədə ciddi düşündük, çünki oxşar vəziyyət bizim AWS hesabımızda istənilən instansiya ilə baş verə bilər.

PgBouncer xətalara dözümlülük sxemini aşağıdakı kimi qurduq: bütün proqram serverləri Şəbəkə Yükü Balanslaşdırıcısına daxil olur, onun arxasında iki PgBouncer var. Hər bir PgBouncer hər bir parçanın eyni PostgreSQL ustasına baxır. AWS instansiyasının qəzası yenidən baş verərsə, bütün trafik başqa PgBouncer vasitəsilə yönləndirilir. Network Load Balancer əvəzetməsi AWS tərəfindən təmin edilir.

Bu sxem yeni PgBouncer serverlərini əlavə etməyi asanlaşdırır.
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

PostgreSQL Failover Cluster yaradın

Bu problemi həll edərkən biz müxtəlif variantları nəzərdən keçirdik: öz-özünə yazılmış uğursuzluq, repmgr, AWS RDS, Patroni.

Öz-özünə yazılmış skriptlər

Onlar ustanın işinə nəzarət edə və uğursuz olarsa, replikanı ustaya təqdim edə və PgBouncer konfiqurasiyasını yeniləyə bilərlər.

Bu yanaşmanın üstünlükləri maksimum sadəlikdir, çünki skriptləri özünüz yazırsınız və onların necə işlədiyini dəqiq başa düşürsünüz.

Eksiler:

  • Usta ölməmiş ola bilər, əvəzində şəbəkə nasazlığı baş verə bilər. Failover, bundan xəbərsiz olaraq, replikanı ustaya təqdim edəcək, köhnə usta isə işləməyə davam edəcək. Nəticədə, master rolunda iki server alacağıq və onlardan hansının ən son məlumatlara sahib olduğunu bilməyəcəyik. Bu vəziyyətə bölünmüş beyin də deyilir;
  • Biz cavabsız qaldıq. Bizim konfiqurasiyamızda master və bir replika, keçiddən sonra replika master-a doğru hərəkət edir və bizdə artıq replika yoxdur, ona görə də əl ilə yeni replika əlavə etməliyik;
  • 12 PostgreSQL parçamız olduğu halda, əvəzetmə əməliyyatının əlavə monitorinqinə ehtiyacımız var, yəni 12 klasterə nəzarət etməliyik. Parçaların sayının artması ilə əvəzetməni yeniləməyi də yadda saxlamalısınız.

Öz-özünə yazılmış uğursuzluq çox mürəkkəb görünür və qeyri-trivial dəstək tələb edir. Tək PostgreSQL klasteri ilə bu, ən asan seçim olardı, lakin miqyaslı deyil, ona görə də bizim üçün uyğun deyil.

Repmgr

PostgreSQL klasterlərinin işini idarə edə bilən PostgreSQL klasterləri üçün Replikasiya Meneceri. Eyni zamanda, qutudan çıxarılan avtomatik uğursuzluq yoxdur, buna görə də iş üçün hazır həllin üstünə öz "sarğı"nızı yazmalısınız. Beləliklə, hər şey öz-özünə yazılmış skriptlərdən daha mürəkkəb ola bilər, buna görə də Repmgr-ı sınamadıq.

AWS RDS

Ehtiyacımız olan hər şeyi dəstəkləyir, ehtiyat nüsxələri necə edəcəyimizi bilir və əlaqələr hovuzunu saxlayır. Onun avtomatik keçidi var: master öləndə replika yeni master olur və AWS dns qeydini yeni masterə dəyişir, replikalar isə müxtəlif AZ-larda yerləşdirilə bilər.

Dezavantajlara incə düzəlişlərin olmaması daxildir. İncə tənzimləmə nümunəsi olaraq: nümunələrimizdə tcp əlaqələri üçün məhdudiyyətlər var, təəssüf ki, RDS-də edilə bilməz:

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

Bundan əlavə, AWS RDS adi nümunə qiymətindən demək olar ki, iki dəfə bahadır, bu da bu həlldən imtina etməyin əsas səbəbi idi.

Patroni

Bu, PostgreSQL-i yaxşı sənədləşdirmə, avtomatik əvəzetmə və github-da mənbə kodu ilə idarə etmək üçün python şablonudur.

Patroninin üstünlükləri:

  • Hər bir konfiqurasiya parametri təsvir edilmişdir, necə işlədiyi aydındır;
  • Avtomatik uğursuzluq qutudan kənar işləyir;
  • Pythonda yazılmışdır və özümüz pythonda çox yazdığımız üçün problemlərin öhdəsindən gəlmək və bəlkə də layihənin inkişafına kömək etmək bizim üçün daha asan olacaq;
  • PostgreSQL-i tam idarə edir, klasterin bütün qovşaqlarında konfiqurasiyanı bir anda dəyişməyə imkan verir və yeni konfiqurasiyanı tətbiq etmək üçün klasteri yenidən işə salmaq lazımdırsa, bu, Patroni vasitəsilə yenidən edilə bilər.

Eksiler:

  • Sənədlərdən PgBouncer ilə necə düzgün işləmək aydın deyil. Bunu mənfi adlandırmaq çətin olsa da, çünki Patroninin vəzifəsi PostgreSQL-i idarə etməkdir və Patroni ilə əlaqələrin necə gedəcəyi artıq bizim problemimizdir;
  • Patroninin böyük həcmdə həyata keçirilməsinə dair bir neçə nümunə var, sıfırdan həyata keçirilməsinə dair bir çox nümunə var.

Nəticə etibarı ilə biz uğursuz klaster yaratmaq üçün Patronini seçdik.

Patronun İcra Prosesi

Patronidən əvvəl bir master və asinxron replikasiya ilə bir replika konfiqurasiyasında 12 PostgreSQL parçamız var idi. Tətbiq serverləri verilənlər bazalarına Şəbəkə Yükü Balanslaşdırıcısı vasitəsilə daxil oldular, bunun arxasında PgBouncer ilə iki nümunə və onların arxasında bütün PostgreSQL serverləri var idi.
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Patroni tətbiq etmək üçün paylanmış saxlama klasteri konfiqurasiyasını seçməli idik. Patroni etcd, Zookeeper, Consul kimi paylanmış konfiqurasiya saxlama sistemləri ilə işləyir. Bazarda Vault ilə birlikdə işləyən tam hüquqlu Konsul klasterimiz var və biz ondan artıq istifadə etmirik. Konsuldan təyinatı üzrə istifadə etməyə başlamaq üçün əla səbəb.

Patroni konsulla necə işləyir

Bizdə üç qovşaqdan ibarət olan Konsul klasteri və lider və replikadan ibarət Patroni klasteri var (Patronidə master klaster lideri, qullar isə replika adlanır). Patroni klasterinin hər bir nümunəsi daim konsula klasterin vəziyyəti haqqında məlumat göndərir. Buna görə də, Konsuldan həmişə Patroni klasterinin cari konfiqurasiyasını və hazırda liderin kim olduğunu öyrənə bilərsiniz.

Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Patronini konsula qoşmaq üçün konsulla necə işlədiyimizdən və isteğe bağlı olaraq əlaqə sxemindən asılı olaraq http və ya https formatında host təyin etməyiniz lazım olduğunu söyləyən rəsmi sənədləri öyrənmək kifayətdir:

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

Sadə görünür, amma burada tələlər başlayır. Konsulla biz https vasitəsilə təhlükəsiz bağlantı üzərində işləyirik və əlaqə konfiqurasiyamız belə görünəcək:

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

Amma bu işləmir. Başlanğıcda Patroni Konsulla əlaqə saxlaya bilmir, çünki o, hər halda http vasitəsilə keçməyə çalışır.

Patroninin mənbə kodu problemi həll etməyə kömək etdi. Yaxşı ki, o, python dilində yazılıb. Belə çıxır ki, host parametri heç bir şəkildə təhlil edilmir və protokol sxemdə göstərilməlidir. Konsulla işləmək üçün işçi konfiqurasiya bloku bizim üçün belə görünür:

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

konsul şablonu

Beləliklə, konfiqurasiya üçün yaddaş seçdik. İndi biz başa düşməliyik ki, PgBouncer Patroni klasterində lider dəyişərkən konfiqurasiyasını necə dəyişəcək. Sənədlərdə bu sualın cavabı yoxdur, çünki. orada, prinsipcə, PgBouncer ilə iş təsvir edilmir.

Həll axtarışında bir məqalə tapdıq (təəssüf ki, başlığı xatırlamıram) burada yazılmışdı ki, Konsul şablonu PgBouncer və Patroni cütləşdirməkdə çox kömək etdi. Bu, bizi Konsul şablonunun necə işlədiyini araşdırmağa sövq etdi.

Məlum oldu ki, Consul-template daim Konsulda PostgreSQL klasterinin konfiqurasiyasına nəzarət edir. Lider dəyişdikdə, o, PgBouncer konfiqurasiyasını yeniləyir və onu yenidən yükləmək üçün əmr göndərir.

Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Şablonun böyük bir üstünlüyü onun kod kimi saxlanmasıdır, ona görə də yeni bir parça əlavə edərkən İnfrastrukturu kod prinsipi kimi dəstəkləyərək yeni öhdəliyi etmək və şablonu avtomatik yeniləmək kifayətdir.

Patroni ilə yeni memarlıq

Nəticədə aşağıdakı iş sxemini əldə etdik:
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Bütün proqram serverləri balanslaşdırıcıya daxil olur → onun arxasında iki PgBouncer nümunəsi var → hər bir nümunədə hər bir Patroni klasterinin vəziyyətinə nəzarət edən və hazırkı liderə sorğu göndərən PgBouncer konfiqurasiyasının uyğunluğuna nəzarət edən Konsul şablonu işə salınır. hər klasterdən.

Manual test

Biz bu sxemi kiçik bir sınaq mühitində işə salmadan əvvəl işlədik və avtomatik keçidin işini yoxladıq. Lövhəni açdılar, stikeri yerindən tərpətdilər və həmin anda klasterin liderini “öldürdülər”. AWS-də bu, nümunəni konsol vasitəsilə bağlamaq qədər sadədir.

Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Stiker 10-20 saniyə ərzində geri qayıtdı və sonra yenidən normal hərəkət etməyə başladı. Bu o deməkdir ki, Patroni klasteri düzgün işləyirdi: o, lideri dəyişdirdi, məlumatları Konsula göndərdi və Konsul şablonu dərhal bu məlumatı götürdü, PgBouncer konfiqurasiyasını dəyişdirdi və yenidən yükləmə əmrini göndərdi.

Yüksək yük altında necə yaşamaq və dayanma müddətini minimum saxlamaq olar?

Hər şey mükəmməl işləyir! Ancaq yeni suallar var: Yüksək yük altında necə işləyəcək? İstehsalda hər şeyi tez və təhlükəsiz şəkildə necə yaymaq olar?

Yük testini apardığımız test mühiti ilk suala cavab verməyə kömək edir. Memarlıq baxımından istehsalla tamamilə eynidir və həcmcə istehsala təxminən bərabər olan test məlumatlarını yaratmışdır. Test zamanı sadəcə PostgreSQL ustalarından birini “öldürmək” və nə baş verdiyini görmək qərarına gəlirik. Ancaq bundan əvvəl avtomatik yuvarlanmağı yoxlamaq vacibdir, çünki bu mühitdə bir neçə PostgreSQL parçamız var, buna görə istehsaldan əvvəl konfiqurasiya skriptlərinin əla sınaqlarını alacağıq.

Hər iki tapşırıq iddialı görünür, lakin bizdə PostgreSQL 9.6. Dərhal 11.2-ə yüksəldə bilərikmi?

Biz bunu 2 addımda etməyə qərar veririk: əvvəlcə 11.2-ə yüksəldin, sonra Patronini işə salın.

PostgreSQL yeniləməsi

PostgreSQL versiyasını tez yeniləmək üçün seçimdən istifadə edin -k, diskdə sabit bağlantılar yaradılır və məlumatlarınızı kopyalamağa ehtiyac yoxdur. 300-400 GB bazalarda yeniləmə 1 saniyə çəkir.

Bizdə çoxlu qırıqlar var, ona görə də yeniləmə avtomatik olaraq edilməlidir. Bunu etmək üçün biz bütün yeniləmə prosesini bizim üçün idarə edən bir Ansible oyun kitabı yazdıq:

/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 qeyd etmək vacibdir ki, təkmilləşdirməyə başlamazdan əvvəl onu parametrlə yerinə yetirməlisiniz --yoxlayıntəkmilləşdirə biləcəyinizə əmin olmaq üçün. Skriptimiz təkmilləşdirmə müddəti üçün konfiqurasiyaların dəyişdirilməsini də edir. Skriptimiz 30 saniyəyə tamamlandı, bu əla nəticədir.

Patroni işə salın

İkinci problemi həll etmək üçün Patroni konfiqurasiyasına baxmaq kifayətdir. Rəsmi repozitoriyada initdb ilə nümunə konfiqurasiya var, o, Patronini ilk dəfə işə saldığınız zaman yeni verilənlər bazasını işə salmaqdan məsuldur. Amma artıq hazır verilənlər bazamız olduğundan biz sadəcə olaraq bu bölməni konfiqurasiyadan çıxardıq.

Artıq mövcud olan PostgreSQL klasterində Patroni quraşdırmağa və onu işə salmağa başlayanda yeni problemlə qarşılaşdıq: hər iki server lider kimi fəaliyyətə başladı. Patroni klasterin ilkin vəziyyəti haqqında heç nə bilmir və hər iki serveri eyni adlı iki ayrı klaster kimi işə salmağa çalışır. Bu problemi həll etmək üçün qulda olan məlumatları olan qovluğu silməlisiniz:

rm -rf /var/lib/postgresql/

Bunu yalnız qul üzərində etmək lazımdır!

Təmiz replika qoşulduqda, Patroni baza ehtiyat nüsxəsi lideri yaradır və onu replikaya bərpa edir və sonra wal qeydlərinə görə cari vəziyyətə çatır.

Qarşılaşdığımız başqa bir çətinlik, bütün PostgreSQL klasterlərinin defolt olaraq əsas adlandırılmasıdır. Hər bir klaster digəri haqqında heç nə bilmirsə, bu normaldır. Lakin siz Patroni istifadə etmək istədiyiniz zaman bütün klasterlərin unikal adı olmalıdır. Həll yolu PostgreSQL konfiqurasiyasında klaster adını dəyişməkdir.

yük testi

Lövhələrdə istifadəçi təcrübəsini simulyasiya edən testi işə saldıq. Yük orta gündəlik dəyərimizə çatdıqda, eyni testi təkrarladıq, PostgreSQL lideri ilə bir nümunəni söndürdük. Avtomatik uğursuzluq gözlədiyimiz kimi işlədi: Patroni lideri dəyişdi, Konsul şablonu PgBouncer konfiqurasiyasını yenilədi və yenidən yükləmək üçün əmr göndərdi. Grafanadakı qrafiklərimizə görə, verilənlər bazasına qoşulma ilə bağlı serverlərdən 20-30 saniyə gecikmələr və az miqdarda səhvlər olduğu aydın idi. Bu normal bir vəziyyətdir, bu cür dəyərlər uğursuzluğumuz üçün məqbuldur və mütləq xidmətin dayandırılması müddətindən daha yaxşıdır.

Patroninin istehsala gətirilməsi

Nəticədə aşağıdakı planı hazırladıq:

  • Konsul şablonunu PgBouncer serverlərinə yerləşdirin və işə salın;
  • 11.2 versiyasına PostgreSQL yeniləmələri;
  • Klasterin adını dəyişdirin;
  • Patroni Klasterinin işə salınması.

Eyni zamanda, sxemimiz bizə demək olar ki, istənilən vaxt ilk nöqtəni qoymağa imkan verir, biz hər bir PgBouncer-i növbə ilə işdən çıxara və onun üzərində konsul şablonunu yerləşdirib işlədə bilərik. Biz belə etdik.

Sürətli yerləşdirmə üçün biz Ansible-dan istifadə etdik, çünki biz artıq test mühitində bütün oyun kitablarını sınaqdan keçirmişik və tam skriptin icra müddəti hər bir parça üçün 1,5 ilə 2 dəqiqə arasında idi. Xidmətimizi dayandırmadan hər şeyi növbə ilə hər bir parçaya təqdim edə bilərdik, lakin hər PostgreSQL-i bir neçə dəqiqə söndürməli olacağıq. Bu halda, məlumatları bu parçada olan istifadəçilər hazırda tam işləyə bilməzlər və bu, bizim üçün qəbuledilməzdir.

Bu vəziyyətdən çıxış yolu 3 aydan bir həyata keçirilən planlı təmir idi. Bu, xidmətimizi tamamilə bağladığımız və verilənlər bazası nümunələrimizi təkmilləşdirdiyimiz zaman planlaşdırılmış iş üçün pəncərədir. Növbəti pəncərəyə bir həftə qaldı və biz sadəcə gözləmək və daha çox hazırlaşmağa qərar verdik. Gözləmə müddətində biz özümüzü əlavə olaraq təmin etdik: hər bir PostgreSQL parçası üçün ən son məlumatların saxlanılmaması halında ehtiyat replika yaratdıq və hər bir parça üçün yeni bir nümunə əlavə etdik ki, bu da Patroni klasterində yeni replikaya çevrilməlidir. məlumatların silinməsi əmrini yerinə yetirməmək üçün. Bütün bunlar səhv riskini minimuma endirməyə kömək etdi.
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Xidmətimizi yenidən işə saldıq, hər şey lazım olduğu kimi işlədi, istifadəçilər işləməyə davam etdilər, lakin qrafiklərdə Konsul serverlərində qeyri-adi dərəcədə yüksək yük olduğunu gördük.
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Niyə biz bunu test mühitində görmədik? Bu problem çox gözəl göstərir ki, İnfrastrukturu kod prinsipi kimi izləmək və sınaq mühitindən tutmuş istehsala qədər bütün infrastrukturu təkmilləşdirmək lazımdır. Əks halda, əldə etdiyimiz problemi əldə etmək çox asandır. Nə olub? Konsul əvvəlcə istehsalda, daha sonra sınaq mühitlərində göründü, nəticədə sınaq mühitlərində Konsulun versiyası istehsaldan daha yüksək oldu. Yalnız buraxılışların birində konsul şablonu ilə işləyərkən CPU sızması həll edildi. Ona görə də biz sadəcə olaraq konsulu yenilədik, bununla da problemi həll etdik.

Patroni klasterini yenidən başladın

Bununla belə, heç şübhə etmədiyimiz yeni bir problemlə üzləşdik. Konsulu yeniləyərkən biz sadəcə olaraq konsul buraxma əmrindən istifadə edərək Konsul qovşağını klasterdən çıxarırıq → Patroni başqa Konsul serverinə qoşulur → hər şey işləyir. Ancaq biz Konsul klasterinin son nümunəsinə çatdıqda və konsul icazəsi əmrini ona göndərdikdə, bütün Patroni klasterləri sadəcə olaraq yenidən başladılar və qeydlərdə aşağıdakı səhvi 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 klasteri öz klasteri haqqında məlumat əldə edə bilmədi və yenidən başladı.

Həll tapmaq üçün biz github-da problem vasitəsilə Patroni müəllifləri ilə əlaqə saxladıq. Onlar konfiqurasiya fayllarımıza təkmilləşdirmələr təklif etdilər:

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

Problemi sınaq mühitində təkrarlaya bildik və bu variantları orada sınaqdan keçirdik, lakin təəssüf ki, onlar işləmədi.

Problem hələ də həll olunmamış qalır. Aşağıdakı həlləri sınamağı planlaşdırırıq:

  • Hər Patroni klaster nümunəsində Konsul-agentdən istifadə edin;
  • Koddakı problemi həll edin.

Xətanın harada baş verdiyini başa düşürük: problem, ehtimal ki, konfiqurasiya faylı vasitəsilə ləğv edilməyən standart vaxt aşımının istifadəsidir. Son Konsul serveri klasterdən çıxarıldıqda, bütün Konsul klasteri bir saniyədən çox dayanır, buna görə Patroni klasterin statusunu ala bilmir və bütün klasteri tamamilə yenidən işə salır.

Xoşbəxtlikdən başqa səhvlərlə qarşılaşmadıq.

Patroni istifadəsinin nəticələri

Patroninin uğurla istifadəyə verilməsindən sonra biz hər klasterə əlavə replika əlavə etdik. İndi hər bir klasterdə bir kvorum var: keçid zamanı bölünmüş beyin halında təhlükəsizlik şəbəkəsi üçün bir lider və iki replika.
Failover Cluster PostgreSQL + Patroni. İcra təcrübəsi

Patroni üç aydan çoxdur ki, istehsal üzərində işləyir. Bu müddət ərzində o, artıq bizə kömək etməyi bacardı. Bu yaxınlarda AWS-də klasterlərdən birinin lideri öldü, avtomatik uğursuzluq işlədi və istifadəçilər işləməyə davam etdilər. Patroni əsas vəzifəsini yerinə yetirdi.

Patroninin istifadəsinin kiçik bir xülasəsi:

  • Konfiqurasiya dəyişikliklərinin asanlığı. Bir nümunədə konfiqurasiyanı dəyişdirmək kifayətdir və o, bütün klasterə çəkiləcəkdir. Yeni konfiqurasiyanı tətbiq etmək üçün yenidən yükləmə tələb olunarsa, Patroni sizə xəbər verəcəkdir. Patroni bir əmrlə bütün klasteri yenidən işə sala bilər ki, bu da çox rahatdır.
  • Avtomatik uğursuzluq işləyir və artıq bizə kömək etməyi bacardı.
  • Tətbiq fasiləsi olmadan PostgreSQL yeniləməsi. Əvvəlcə replikaları yeni versiyaya yeniləməlisiniz, sonra Patroni klasterində lideri dəyişdirməli və köhnə lideri yeniləməlisiniz. Bu halda, avtomatik uğursuzluğun zəruri sınaqları baş verir.

Mənbə: www.habr.com

Добавить комментарий