Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Dalam artikel itu saya akan memberitahu anda bagaimana kami mendekati isu toleransi kesalahan PostgreSQL, mengapa ia menjadi penting bagi kami dan apa yang berlaku pada akhirnya.

Kami mempunyai perkhidmatan yang sangat sarat: 2,5 juta pengguna di seluruh dunia, 50K+ pengguna aktif setiap hari. Pelayan terletak di Amazone di satu wilayah Ireland: 100+ pelayan berbeza sentiasa berfungsi, di mana hampir 50 daripadanya menggunakan pangkalan data.

Seluruh bahagian belakang ialah aplikasi Java stateful monolitik yang besar yang mengekalkan sambungan soket web yang berterusan dengan pelanggan. Apabila beberapa pengguna bekerja pada papan yang sama pada masa yang sama, mereka semua melihat perubahan dalam masa nyata, kerana kami menulis setiap perubahan pada pangkalan data. Kami mempunyai kira-kira 10K permintaan sesaat ke pangkalan data kami. Pada beban puncak dalam Redis, kami menulis 80-100K permintaan sesaat.
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Mengapa kami bertukar daripada Redis kepada PostgreSQL

Pada mulanya, perkhidmatan kami berfungsi dengan Redis, kedai nilai kunci yang menyimpan semua data dalam RAM pelayan.

Kelebihan Redis:

  1. Kelajuan tindak balas yang tinggi, kerana segala-galanya disimpan dalam ingatan;
  2. Kemudahan sandaran dan replikasi.

Kekurangan Redis untuk kami:

  1. Tiada transaksi sebenar. Kami cuba mensimulasikannya pada tahap aplikasi kami. Malangnya, ini tidak selalu berfungsi dengan baik dan memerlukan penulisan kod yang sangat kompleks.
  2. Jumlah data dihadkan oleh jumlah memori. Apabila jumlah data meningkat, ingatan akan berkembang, dan, pada akhirnya, kami akan menghadapi ciri-ciri tika yang dipilih, yang dalam AWS memerlukan menghentikan perkhidmatan kami untuk menukar jenis tika.
  3. Ia adalah perlu untuk sentiasa mengekalkan tahap kependaman yang rendah, kerana. kami mempunyai bilangan permintaan yang sangat besar. Tahap kelewatan optimum untuk kami ialah 17-20 ms. Pada tahap 30-40 ms, kami mendapat respons yang panjang kepada permintaan daripada permohonan kami dan kemerosotan perkhidmatan. Malangnya, ini berlaku kepada kami pada September 2018, apabila salah satu kejadian dengan Redis atas sebab tertentu menerima kependaman 2 kali lebih banyak daripada biasa. Untuk menyelesaikan isu ini, kami menghentikan perkhidmatan tengah hari untuk penyelenggaraan tidak berjadual dan menggantikan contoh Redis yang bermasalah.
  4. Adalah mudah untuk mendapatkan ketidakkonsistenan data walaupun dengan ralat kecil dalam kod dan kemudian menghabiskan banyak masa menulis kod untuk membetulkan data ini.

Kami mengambil kira keburukan dan menyedari bahawa kami perlu beralih kepada sesuatu yang lebih mudah, dengan transaksi biasa dan kurang bergantung pada kependaman. Menjalankan penyelidikan, menganalisis banyak pilihan dan memilih PostgreSQL.

Kami telah berpindah ke pangkalan data baharu selama 1,5 tahun dan telah memindahkan hanya sebahagian kecil daripada data, jadi kini kami bekerja serentak dengan Redis dan PostgreSQL. Maklumat lanjut tentang peringkat memindahkan dan menukar data antara pangkalan data ditulis dalam artikel rakan sekerja saya.

Apabila kami mula bergerak, aplikasi kami berfungsi secara langsung dengan pangkalan data dan mengakses master Redis dan PostgreSQL. Kelompok PostgreSQL terdiri daripada induk dan replika dengan replikasi tak segerak. Beginilah rupa skema pangkalan data:
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Melaksanakan PgBouncer

Semasa kami bergerak, produk itu juga sedang berkembang: bilangan pengguna dan bilangan pelayan yang berfungsi dengan PostgreSQL meningkat, dan kami mula kekurangan sambungan. PostgreSQL mencipta proses berasingan untuk setiap sambungan dan menggunakan sumber. Anda boleh meningkatkan bilangan sambungan sehingga satu titik tertentu, jika tidak, terdapat peluang untuk mendapatkan prestasi pangkalan data suboptimum. Pilihan yang ideal dalam situasi sedemikian ialah memilih pengurus sambungan yang akan berdiri di hadapan pangkalan.

Kami mempunyai dua pilihan untuk pengurus sambungan: Pgpool dan PgBouncer. Tetapi yang pertama tidak menyokong mod transaksi bekerja dengan pangkalan data, jadi kami memilih PgBouncer.

Kami telah menyediakan skema kerja berikut: aplikasi kami mengakses satu PgBouncer, di belakangnya adalah induk PostgreSQL, dan di belakang setiap induk terdapat satu replika dengan replikasi tak segerak.
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Pada masa yang sama, kami tidak dapat menyimpan keseluruhan jumlah data dalam PostgreSQL dan kelajuan bekerja dengan pangkalan data adalah penting bagi kami, jadi kami mula memecah PostgreSQL pada peringkat aplikasi. Skim yang diterangkan di atas agak mudah untuk ini: apabila menambah serpihan PostgreSQL baharu, sudah cukup untuk mengemas kini konfigurasi PgBouncer dan aplikasi boleh berfungsi dengan serta-merta dengan serpihan baharu.

PgBouncer failover

Skim ini berjaya sehingga satu-satunya contoh PgBouncer mati. Kami berada dalam AWS, di mana semua kejadian dijalankan pada perkakasan yang mati secara berkala. Dalam kes sedemikian, contoh hanya beralih ke perkakasan baharu dan berfungsi semula. Ini berlaku dengan PgBouncer, tetapi ia menjadi tidak tersedia. Akibat kejatuhan ini ialah ketiadaan perkhidmatan kami selama 25 minit. AWS mengesyorkan menggunakan lebihan sisi pengguna untuk situasi sedemikian, yang tidak dilaksanakan di negara kita pada masa itu.

Selepas itu, kami serius memikirkan tentang toleransi kesalahan gugusan PgBouncer dan PostgreSQL, kerana situasi yang sama boleh berlaku dengan mana-mana kejadian dalam akaun AWS kami.

Kami membina skim toleransi kesalahan PgBouncer seperti berikut: semua pelayan aplikasi mengakses Pengimbang Beban Rangkaian, di belakangnya terdapat dua PgBouncer. Setiap PgBouncer melihat master PostgreSQL yang sama bagi setiap serpihan. Jika ranap kejadian AWS berlaku lagi, semua trafik diubah hala melalui PgBouncer yang lain. Failover Pengimbang Beban Rangkaian disediakan oleh AWS.

Skim ini memudahkan untuk menambah pelayan PgBouncer baharu.
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Buat Kluster Failover PostgreSQL

Apabila menyelesaikan masalah ini, kami mempertimbangkan pilihan yang berbeza: failover yang ditulis sendiri, repmgr, AWS RDS, Patroni.

Skrip tulisan sendiri

Mereka boleh memantau kerja tuan dan, jika gagal, mempromosikan replika kepada tuan dan mengemas kini konfigurasi PgBouncer.

Kelebihan pendekatan ini adalah kesederhanaan maksimum, kerana anda menulis skrip sendiri dan memahami dengan tepat cara ia berfungsi.

Cons:

  • Tuan mungkin tidak mati, sebaliknya kegagalan rangkaian mungkin telah berlaku. Failover, tidak menyedari perkara ini, akan mempromosikan replika kepada tuan, manakala tuan lama akan terus bekerja. Akibatnya, kami akan mendapat dua pelayan sebagai tuan dan kami tidak akan tahu yang mana antara mereka mempunyai data terkini yang terkini. Keadaan ini juga dipanggil split-brain;
  • Kami dibiarkan tanpa jawapan. Dalam konfigurasi kami, induk dan satu replika, selepas bertukar, replika bergerak ke atas dan kami tidak lagi mempunyai replika, jadi kami perlu menambah replika baharu secara manual;
  • Kami memerlukan pemantauan tambahan bagi operasi failover, sementara kami mempunyai 12 serpihan PostgreSQL, yang bermaksud kami perlu memantau 12 kluster. Dengan peningkatan bilangan serpihan, anda juga mesti ingat untuk mengemas kini failover.

Failover yang ditulis sendiri kelihatan sangat rumit dan memerlukan sokongan yang tidak remeh. Dengan satu kluster PostgreSQL, ini akan menjadi pilihan yang paling mudah, tetapi ia tidak berskala, jadi ia tidak sesuai untuk kita.

Repmgr

Pengurus Replikasi untuk kluster PostgreSQL, yang boleh menguruskan operasi kluster PostgreSQL. Pada masa yang sama, ia tidak mempunyai failover automatik di luar kotak, jadi untuk kerja anda perlu menulis "pembungkus" anda sendiri di atas penyelesaian siap. Jadi segala-galanya boleh menjadi lebih rumit daripada dengan skrip yang ditulis sendiri, jadi kami tidak mencuba Repmgr.

AWS RDS

Menyokong semua yang kami perlukan, tahu cara membuat sandaran dan mengekalkan kumpulan sambungan. Ia mempunyai pensuisan automatik: apabila tuan mati, replika menjadi tuan baharu, dan AWS menukar rekod dns kepada tuan baharu, manakala replika boleh ditempatkan di AZ yang berbeza.

Kelemahannya termasuk kekurangan pelarasan halus. Sebagai contoh penalaan halus: contoh kami mempunyai sekatan untuk sambungan tcp, yang, malangnya, tidak boleh dilakukan dalam RDS:

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

Di samping itu, AWS RDS hampir dua kali lebih mahal daripada harga contoh biasa, yang merupakan sebab utama untuk meninggalkan penyelesaian ini.

Patroni

Ini ialah templat python untuk mengurus PostgreSQL dengan dokumentasi yang baik, failover automatik dan kod sumber pada github.

Kelebihan Patroni:

  • Setiap parameter konfigurasi diterangkan, jelas cara ia berfungsi;
  • Failover automatik berfungsi di luar kotak;
  • Ditulis dalam python, dan kerana kita sendiri banyak menulis dalam python, lebih mudah bagi kita untuk menangani masalah dan, mungkin, juga membantu pembangunan projek;
  • Menguruskan PostgreSQL sepenuhnya, membolehkan anda menukar konfigurasi pada semua nod kluster sekaligus, dan jika kluster perlu dimulakan semula untuk menggunakan konfigurasi baharu, maka ini boleh dilakukan sekali lagi menggunakan Patroni.

Cons:

  • Tidak jelas daripada dokumentasi cara bekerja dengan PgBouncer dengan betul. Walaupun sukar untuk memanggilnya sebagai tolak, kerana tugas Patroni adalah untuk mengurus PostgreSQL, dan bagaimana sambungan kepada Patroni akan pergi sudah menjadi masalah kami;
  • Terdapat beberapa contoh pelaksanaan Patroni pada jumlah yang besar, manakala terdapat banyak contoh pelaksanaan dari awal.

Hasilnya, kami memilih Patroni untuk mencipta kelompok failover.

Proses Pelaksanaan Patroni

Sebelum Patroni, kami mempunyai 12 serpihan PostgreSQL dalam konfigurasi satu induk dan satu replika dengan replikasi tak segerak. Pelayan aplikasi mengakses pangkalan data melalui Pengimbang Beban Rangkaian, di belakangnya terdapat dua kejadian dengan PgBouncer, dan di belakangnya terdapat semua pelayan PostgreSQL.
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Untuk melaksanakan Patroni, kami perlu memilih konfigurasi kluster storan yang diedarkan. Patroni berfungsi dengan sistem penyimpanan konfigurasi teragih seperti etcd, Zookeeper, Consul. Kami hanya mempunyai kluster Konsul penuh di pasaran, yang berfungsi bersama Vault dan kami tidak menggunakannya lagi. Sebab yang bagus untuk mula menggunakan Konsul untuk tujuan yang dimaksudkan.

Bagaimana Patroni bekerja dengan Konsul

Kami mempunyai kluster Konsul, yang terdiri daripada tiga nod, dan kluster Patroni, yang terdiri daripada ketua dan replika (dalam Patroni, tuan dipanggil ketua kluster, dan hamba dipanggil replika). Setiap contoh kluster Patroni sentiasa menghantar maklumat tentang keadaan kluster kepada Konsul. Oleh itu, daripada Konsul anda sentiasa boleh mengetahui konfigurasi semasa kluster Patroni dan siapa ketua pada masa ini.

Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Untuk menyambungkan Patroni ke Konsul, cukup untuk mengkaji dokumentasi rasmi, yang mengatakan bahawa anda perlu menentukan hos dalam format http atau https, bergantung pada cara kami bekerja dengan Konsul, dan skema sambungan, secara pilihan:

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

Ia kelihatan mudah, tetapi di sini perangkap bermula. Dengan Konsul, kami bekerja melalui sambungan selamat melalui https dan konfigurasi sambungan kami akan kelihatan seperti ini:

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

Tetapi itu tidak berkesan. Pada permulaan, Patroni tidak dapat menyambung ke Konsul, kerana ia cuba melalui http juga.

Kod sumber Patroni membantu menangani masalah itu. Perkara yang baik ia ditulis dalam python. Ternyata parameter hos tidak dihuraikan dalam apa jua cara, dan protokol mesti dinyatakan dalam skema. Beginilah rupa blok konfigurasi yang berfungsi untuk bekerja dengan Konsul bagi kami:

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

templat konsul

Jadi, kami telah memilih storan untuk konfigurasi. Sekarang kita perlu memahami cara PgBouncer akan menukar konfigurasinya apabila menukar ketua dalam kelompok Patroni. Tiada jawapan kepada soalan ini dalam dokumentasi, kerana. di sana, pada dasarnya, bekerja dengan PgBouncer tidak diterangkan.

Untuk mencari penyelesaian, kami menjumpai artikel (malangnya saya tidak ingat tajuknya) di mana ia ditulis bahawa Π‘onsul-template banyak membantu dalam menggandingkan PgBouncer dan Patroni. Ini mendorong kami untuk menyiasat cara Consul-template berfungsi.

Ternyata Consul-template sentiasa memantau konfigurasi kluster PostgreSQL dalam Consul. Apabila ketua bertukar, ia mengemas kini konfigurasi PgBouncer dan menghantar arahan untuk memuatkannya semula.

Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Tambahan besar templat ialah ia disimpan sebagai kod, jadi apabila menambah serpihan baharu, sudah cukup untuk membuat komitmen baharu dan mengemas kini templat secara automatik, menyokong Infrastruktur sebagai prinsip kod.

Seni bina baharu dengan Patroni

Akibatnya, kami mendapat skema kerja berikut:
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Semua pelayan aplikasi mengakses pengimbang β†’ terdapat dua contoh PgBouncer di belakangnya β†’ pada setiap contoh, Consul-template dilancarkan, yang memantau status setiap kelompok Patroni dan memantau perkaitan konfigurasi PgBouncer, yang menghantar permintaan kepada ketua semasa daripada setiap kluster.

Ujian manual

Kami menjalankan skim ini sebelum melancarkannya pada persekitaran ujian kecil dan menyemak operasi pensuisan automatik. Mereka membuka papan, mengalihkan pelekat, dan pada masa itu mereka "membunuh" ketua kluster. Dalam AWS, ini semudah mematikan contoh melalui konsol.

Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Pelekat itu kembali semula dalam masa 10-20 saat, dan kemudian mula bergerak seperti biasa. Ini bermakna kluster Patroni berfungsi dengan betul: ia menukar ketua, menghantar maklumat kepada Π‘onsul, dan Π‘onsul-template segera mengambil maklumat ini, menggantikan konfigurasi PgBouncer dan menghantar arahan untuk memuat semula.

Bagaimana untuk bertahan di bawah beban yang tinggi dan memastikan masa henti minimum?

Semuanya berfungsi dengan sempurna! Tetapi terdapat soalan baharu: Bagaimanakah ia berfungsi di bawah beban tinggi? Bagaimana dengan cepat dan selamat melancarkan segala-galanya dalam pengeluaran?

Persekitaran ujian di mana kami menjalankan ujian beban membantu kami menjawab soalan pertama. Ia benar-benar sama dengan pengeluaran dari segi seni bina dan telah menghasilkan data ujian yang lebih kurang sama dalam jumlah pengeluaran. Kami memutuskan untuk hanya "membunuh" salah seorang master PostgreSQL semasa ujian dan melihat apa yang berlaku. Tetapi sebelum itu, adalah penting untuk menyemak rolling automatik, kerana pada persekitaran ini kami mempunyai beberapa serpihan PostgreSQL, jadi kami akan mendapat ujian skrip konfigurasi yang sangat baik sebelum pengeluaran.

Kedua-dua tugas kelihatan bercita-cita tinggi, tetapi kami mempunyai PostgreSQL 9.6. Bolehkah kita menaik taraf segera kepada 11.2?

Kami memutuskan untuk melakukannya dalam 2 langkah: mula-mula naik taraf kepada 11.2, kemudian lancarkan Patroni.

Kemas kini PostgreSQL

Untuk mengemas kini versi PostgreSQL dengan cepat, gunakan pilihan -k, di mana pautan keras dibuat pada cakera dan tidak perlu menyalin data anda. Pada asas 300-400 GB, kemas kini mengambil masa 1 saat.

Kami mempunyai banyak serpihan, jadi kemas kini perlu dilakukan secara automatik. Untuk melakukan ini, kami menulis buku permainan Ansible yang mengendalikan keseluruhan proses kemas kini untuk kami:

/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='

Adalah penting untuk diperhatikan di sini bahawa sebelum memulakan naik taraf, anda mesti melaksanakannya dengan parameter --semakuntuk memastikan anda boleh menaik taraf. Skrip kami juga membuat penggantian konfigurasi untuk tempoh peningkatan. Skrip kami siap dalam masa 30 saat, yang merupakan hasil yang sangat baik.

Lancarkan Patroni

Untuk menyelesaikan masalah kedua, lihat sahaja konfigurasi Patroni. Repositori rasmi mempunyai konfigurasi contoh dengan initdb, yang bertanggungjawab untuk memulakan pangkalan data baharu apabila anda mula-mula memulakan Patroni. Tetapi oleh kerana kami sudah mempunyai pangkalan data sedia, kami hanya mengalih keluar bahagian ini daripada konfigurasi.

Apabila kami mula memasang Patroni pada kluster PostgreSQL yang sedia ada dan menjalankannya, kami menghadapi masalah baharu: kedua-dua pelayan bermula sebagai pemimpin. Patroni tidak tahu apa-apa tentang keadaan awal kluster dan cuba memulakan kedua-dua pelayan sebagai dua kluster berasingan dengan nama yang sama. Untuk menyelesaikan masalah ini, anda perlu memadamkan direktori dengan data pada hamba:

rm -rf /var/lib/postgresql/

Ini perlu dilakukan hanya pada hamba!

Apabila replika bersih disambungkan, Patroni membuat ketua sandaran asas dan memulihkannya kepada replika, dan kemudian mengejar keadaan semasa mengikut log wal.

Satu lagi kesukaran yang kami hadapi ialah semua kluster PostgreSQL dinamakan utama secara lalai. Apabila setiap kluster tidak mengetahui apa-apa tentang yang lain, ini adalah perkara biasa. Tetapi apabila anda ingin menggunakan Patroni, maka semua kluster mesti mempunyai nama yang unik. Penyelesaiannya ialah menukar nama kluster dalam konfigurasi PostgreSQL.

ujian beban

Kami telah melancarkan ujian yang mensimulasikan pengalaman pengguna pada papan. Apabila beban mencapai nilai purata harian kami, kami mengulangi ujian yang sama, kami mematikan satu contoh dengan pemimpin PostgreSQL. Failover automatik berfungsi seperti yang kami jangkakan: Patroni menukar ketua, Consul-template mengemas kini konfigurasi PgBouncer dan menghantar arahan untuk memuat semula. Menurut graf kami di Grafana, jelas bahawa terdapat kelewatan selama 20-30 saat dan sedikit ralat daripada pelayan yang berkaitan dengan sambungan ke pangkalan data. Ini adalah keadaan biasa, nilai sedemikian boleh diterima untuk failover kami dan pastinya lebih baik daripada masa henti perkhidmatan.

Membawa Patroni ke pengeluaran

Hasilnya, kami membuat rancangan berikut:

  • Gunakan templat Konsul ke pelayan PgBouncer dan lancarkan;
  • Kemas kini PostgreSQL kepada versi 11.2;
  • Tukar nama kluster;
  • Memulakan Kluster Patroni.

Pada masa yang sama, skim kami membolehkan kami membuat mata pertama hampir pada bila-bila masa, kami boleh mengalih keluar setiap PgBouncer daripada kerja secara bergilir-gilir dan menggunakan serta menjalankan templat konsul padanya. Jadi kami lakukan.

Untuk penggunaan pantas, kami menggunakan Ansible, kerana kami telah menguji semua buku permainan pada persekitaran ujian, dan masa pelaksanaan skrip penuh adalah dari 1,5 hingga 2 minit untuk setiap serpihan. Kami boleh melancarkan semuanya secara bergilir-gilir ke setiap serpihan tanpa menghentikan perkhidmatan kami, tetapi kami perlu mematikan setiap PostgreSQL selama beberapa minit. Dalam kes ini, pengguna yang datanya berada pada serpihan ini tidak dapat berfungsi sepenuhnya pada masa ini, dan ini tidak boleh diterima untuk kami.

Jalan keluar dari keadaan ini ialah penyelenggaraan yang dirancang, yang berlaku setiap 3 bulan. Ini adalah tetingkap untuk kerja berjadual, apabila kami menutup sepenuhnya perkhidmatan kami dan menaik taraf keadaan pangkalan data kami. Terdapat satu minggu lagi untuk tetingkap seterusnya, dan kami memutuskan untuk menunggu dan membuat persediaan lebih lanjut. Semasa masa menunggu, kami juga memastikan diri kami sendiri: untuk setiap serpihan PostgreSQL, kami menaikkan replika ganti sekiranya berlaku kegagalan untuk menyimpan data terkini, dan menambah contoh baharu untuk setiap serpihan, yang sepatutnya menjadi replika baharu dalam gugusan Patroni, supaya tidak melaksanakan arahan untuk memadam data . Semua ini membantu meminimumkan risiko ralat.
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Kami memulakan semula perkhidmatan kami, semuanya berfungsi sebagaimana mestinya, pengguna terus bekerja, tetapi pada graf kami mendapati beban yang luar biasa tinggi pada pelayan Konsul.
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Mengapa kita tidak melihat ini dalam persekitaran ujian? Masalah ini menggambarkan dengan baik bahawa adalah perlu untuk mengikuti Infrastruktur sebagai prinsip kod dan memperhalusi keseluruhan infrastruktur, daripada persekitaran ujian kepada pengeluaran. Jika tidak, sangat mudah untuk mendapatkan masalah yang kita dapat. Apa yang berlaku? Konsul mula-mula muncul pada pengeluaran, dan kemudian pada persekitaran ujian, akibatnya, pada persekitaran ujian, versi Konsul adalah lebih tinggi daripada pada pengeluaran. Hanya dalam salah satu keluaran, kebocoran CPU telah diselesaikan apabila bekerja dengan templat konsul. Oleh itu, kami hanya mengemas kini Konsul, sekali gus menyelesaikan masalah itu.

Mulakan semula kluster Patroni

Walau bagaimanapun, kami mendapat masalah baru, yang kami tidak mengesyaki. Apabila mengemas kini Konsul, kami hanya mengalih keluar nod Konsul daripada kluster menggunakan arahan cuti konsul β†’ Patroni menyambung ke pelayan Konsul yang lain β†’ semuanya berfungsi. Tetapi apabila kami mencapai contoh terakhir kluster Konsul dan menghantar arahan cuti konsul kepadanya, semua kluster Patroni hanya dimulakan semula, dan dalam log kami melihat ralat berikut:

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>

Kelompok Patroni tidak dapat mendapatkan maklumat tentang kelompoknya dan dimulakan semula.

Untuk mencari penyelesaian, kami menghubungi pengarang Patroni melalui isu di github. Mereka mencadangkan penambahbaikan pada fail konfigurasi kami:

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

Kami dapat meniru masalah pada persekitaran ujian dan menguji pilihan ini di sana, tetapi malangnya ia tidak berfungsi.

Masalahnya masih belum selesai. Kami merancang untuk mencuba penyelesaian berikut:

  • Gunakan ejen Konsul pada setiap contoh kluster Patroni;
  • Betulkan isu dalam kod.

Kami faham di mana ralat berlaku: masalahnya mungkin adalah penggunaan tamat masa lalai, yang tidak ditindih melalui fail konfigurasi. Apabila pelayan Konsul terakhir dialih keluar daripada kluster, keseluruhan kluster Konsul digantung selama lebih daripada satu saat, kerana ini, Patroni tidak boleh mendapatkan status kluster dan memulakan semula keseluruhan kluster sepenuhnya.

Nasib baik, kami tidak menemui sebarang ralat lagi.

Keputusan menggunakan Patroni

Selepas kejayaan pelancaran Patroni, kami menambah replika tambahan dalam setiap kluster. Kini dalam setiap kluster terdapat kemiripan kuorum: satu ketua dan dua replika, untuk jaring keselamatan sekiranya otak berpecah semasa bertukar.
Kluster Failover PostgreSQL + Patroni. Pengalaman pelaksanaan

Patroni telah mengusahakan pengeluaran selama lebih daripada tiga bulan. Selama ini, dia sudah berjaya membantu kami. Baru-baru ini, ketua salah satu kluster meninggal dunia dalam AWS, failover automatik berfungsi dan pengguna terus berfungsi. Patroni memenuhi tugas utamanya.

Ringkasan kecil penggunaan Patroni:

  • Kemudahan perubahan konfigurasi. Ia cukup untuk menukar konfigurasi pada satu contoh dan ia akan ditarik ke seluruh kelompok. Jika but semula diperlukan untuk menggunakan konfigurasi baharu, maka Patroni akan memberitahu anda. Patroni boleh memulakan semula keseluruhan kluster dengan satu arahan, yang juga sangat mudah.
  • Failover automatik berfungsi dan telah berjaya membantu kami.
  • Kemas kini PostgreSQL tanpa masa henti aplikasi. Anda mesti mengemas kini replika kepada versi baharu dahulu, kemudian menukar ketua dalam kelompok Patroni dan mengemas kini ketua lama. Dalam kes ini, ujian yang diperlukan bagi failover automatik berlaku.

Sumber: www.habr.com

Tambah komen