Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Dalam artikel ini saya akan memberi tahu Anda bagaimana kami mendekati masalah toleransi kesalahan PostgreSQL, mengapa ini menjadi penting bagi kami dan apa yang terjadi pada akhirnya.

Kami memiliki layanan yang sarat muatan: 2,5 juta pengguna di seluruh dunia, 50 ribu+ pengguna aktif setiap hari. Server berlokasi di Amazone di satu wilayah Irlandia: 100+ server berbeda terus bekerja, hampir 50 di antaranya memiliki database.

Seluruh backend adalah aplikasi Java stateful monolitik besar yang menjaga koneksi soket web secara konstan dengan klien. Ketika beberapa pengguna bekerja di papan yang sama pada waktu yang sama, mereka semua melihat perubahan secara real time, karena kami menulis setiap perubahan ke database. Kami memiliki sekitar 10 ribu permintaan per detik ke database kami. Pada beban puncak di Redis, kami menulis 80-100 ribu permintaan per detik.
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Mengapa kami beralih dari Redis ke PostgreSQL

Awalnya, layanan kami bekerja dengan Redis, penyimpanan nilai kunci yang menyimpan semua data di RAM server.

Kelebihan Redis:

  1. Kecepatan respons tinggi, karena semuanya disimpan dalam memori;
  2. Kemudahan pencadangan dan replikasi.

Kontra Redis bagi kami:

  1. Tidak ada transaksi nyata. Kami mencoba mensimulasikannya pada tingkat aplikasi kami. Sayangnya, hal ini tidak selalu berhasil dengan baik dan memerlukan penulisan kode yang sangat rumit.
  2. Jumlah data dibatasi oleh jumlah memori. Seiring bertambahnya jumlah data, memori akan bertambah, dan, pada akhirnya, kita akan menemukan karakteristik instans yang dipilih, yang di AWS memerlukan penghentian layanan kami untuk mengubah jenis instans.
  3. Penting untuk terus mempertahankan tingkat latensi yang rendah, karena. kami memiliki jumlah permintaan yang sangat besar. Tingkat penundaan optimal bagi kami adalah 17-20 ms. Pada level 30-40 ms, kami mendapat respons panjang terhadap permintaan dari aplikasi kami dan penurunan layanan. Sayangnya, hal ini terjadi pada kami pada bulan September 2018, ketika salah satu instance dengan Redis karena alasan tertentu menerima latensi 2 kali lebih banyak dari biasanya. Untuk mengatasi masalah ini, kami menghentikan layanan pada tengah hari karena pemeliharaan tidak terjadwal dan mengganti instance Redis yang bermasalah.
  4. Sangat mudah untuk mendapatkan ketidakkonsistenan data bahkan dengan kesalahan kecil dalam kode dan kemudian menghabiskan banyak waktu menulis kode untuk memperbaiki data ini.

Kami mempertimbangkan kekurangannya dan menyadari bahwa kami perlu beralih ke sesuatu yang lebih nyaman, dengan transaksi normal dan lebih sedikit ketergantungan pada latensi. Melakukan penelitian, menganalisis banyak opsi dan memilih PostgreSQL.

Kami telah berpindah ke database baru selama 1,5 tahun dan hanya memindahkan sebagian kecil datanya, jadi sekarang kami bekerja secara bersamaan dengan Redis dan PostgreSQL. Informasi lebih lanjut tentang tahapan pemindahan dan peralihan data antar database telah dijelaskan artikel rekan saya.

Saat pertama kali kami mulai berpindah, aplikasi kami bekerja langsung dengan database dan mengakses master Redis dan PostgreSQL. Cluster PostgreSQL terdiri dari master dan replika dengan replikasi asinkron. Seperti inilah skema databasenya:
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Menerapkan PgBouncer

Saat kami berpindah, produknya juga berkembang: jumlah pengguna dan jumlah server yang bekerja dengan PostgreSQL meningkat, dan kami mulai kekurangan koneksi. PostgreSQL membuat proses terpisah untuk setiap koneksi dan menggunakan sumber daya. Anda dapat menambah jumlah koneksi hingga titik tertentu, jika tidak, ada kemungkinan kinerja database menjadi kurang optimal. Pilihan ideal dalam situasi seperti ini adalah memilih manajer koneksi yang akan berdiri di depan pangkalan.

Kami memiliki dua opsi untuk manajer koneksi: Pgpool dan PgBouncer. Tapi yang pertama tidak mendukung mode transaksional bekerja dengan database, jadi kami memilih PgBouncer.

Kami telah menyiapkan skema kerja berikut: aplikasi kami mengakses satu PgBouncer, di belakangnya terdapat master PostgreSQL, dan di belakang setiap master terdapat satu replika dengan replikasi asinkron.
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Pada saat yang sama, kami tidak dapat menyimpan seluruh jumlah data di PostgreSQL dan kecepatan bekerja dengan database penting bagi kami, jadi kami mulai melakukan sharding PostgreSQL di tingkat aplikasi. Skema yang dijelaskan di atas relatif mudah untuk ini: saat menambahkan shard PostgreSQL baru, cukup memperbarui konfigurasi PgBouncer dan aplikasi dapat segera bekerja dengan shard baru.

Kegagalan PgBouncer

Skema ini berfungsi hingga satu-satunya instance PgBouncer mati. Kami berada di AWS, tempat semua instans berjalan pada perangkat keras yang mati secara berkala. Dalam kasus seperti ini, instance hanya berpindah ke perangkat keras baru dan berfungsi kembali. Hal ini terjadi dengan PgBouncer, namun menjadi tidak tersedia. Akibat musim gugur ini adalah tidak tersedianya layanan kami selama 25 menit. AWS merekomendasikan penggunaan redundansi sisi pengguna untuk situasi seperti itu, yang belum diterapkan di negara kita pada saat itu.

Setelah itu, kami dengan serius memikirkan tentang toleransi kesalahan klaster PgBouncer dan PostgreSQL, karena situasi serupa dapat terjadi pada instans mana pun di akun AWS kami.

Kami membangun skema toleransi kesalahan PgBouncer sebagai berikut: semua server aplikasi mengakses Network Load Balancer, di belakangnya terdapat dua PgBouncer. Setiap PgBouncer melihat master PostgreSQL yang sama dari setiap shard. Jika kerusakan instans AWS terjadi lagi, semua lalu lintas dialihkan melalui PgBouncer lain. Failover Network Load Balancer disediakan oleh AWS.

Skema ini memudahkan penambahan server PgBouncer baru.
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Buat Klaster Failover PostgreSQL

Saat memecahkan masalah ini, kami mempertimbangkan opsi yang berbeda: failover yang ditulis sendiri, repmgr, AWS RDS, Patroni.

Naskah yang ditulis sendiri

Mereka dapat memantau pekerjaan master dan, jika gagal, mempromosikan replika ke master dan memperbarui konfigurasi PgBouncer.

Keuntungan dari pendekatan ini adalah kesederhanaan maksimalnya, karena Anda menulis skrip sendiri dan memahami dengan tepat cara kerjanya.

Cons:

  • Masternya mungkin tidak mati, malah mungkin terjadi kegagalan jaringan. Failover, tanpa menyadarinya, akan mempromosikan replika tersebut ke master, sementara master lama akan terus bekerja. Hasilnya, kita akan mendapatkan dua server yang berperan sebagai master dan kita tidak akan tahu server mana yang memiliki data terkini. Situasi ini juga disebut split-brain;
  • Kami dibiarkan tanpa tanggapan. Dalam konfigurasi kami, master dan satu replika, setelah beralih, replika maju ke master dan kami tidak lagi memiliki replika, jadi kami harus menambahkan replika baru secara manual;
  • Kami memerlukan pemantauan tambahan terhadap operasi failover, sementara kami memiliki 12 shard PostgreSQL, yang berarti kami harus memantau 12 cluster. Dengan bertambahnya jumlah shard, Anda juga harus ingat untuk memperbarui failover.

Failover yang ditulis sendiri terlihat sangat rumit dan membutuhkan dukungan yang tidak sepele. Dengan satu cluster PostgreSQL, ini akan menjadi opsi termudah, tetapi tidak berskala, sehingga tidak cocok untuk kami.

Repmgr

Manajer Replikasi untuk klaster PostgreSQL, yang dapat mengelola pengoperasian klaster PostgreSQL. Pada saat yang sama, ia tidak memiliki failover otomatis, jadi untuk pekerjaan Anda perlu menulis "pembungkus" Anda sendiri di atas solusi yang sudah jadi. Jadi semuanya bisa menjadi lebih rumit dibandingkan dengan skrip yang ditulis sendiri, jadi kami bahkan tidak mencoba Repmgr.

AWSRDS

Mendukung semua yang kami perlukan, mengetahui cara membuat cadangan, dan memelihara kumpulan koneksi. Ia memiliki peralihan otomatis: ketika master mati, replika menjadi master baru, dan AWS mengubah catatan dns ke master baru, sedangkan replika dapat ditempatkan di AZ yang berbeda.

Kerugiannya termasuk kurangnya penyesuaian yang baik. Sebagai contoh penyesuaian: instance kami memiliki batasan untuk koneksi tcp, yang sayangnya tidak dapat dilakukan di RDS:

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

Selain itu, harga AWS RDS hampir dua kali lebih mahal dibandingkan harga instans reguler, yang merupakan alasan utama untuk mengabaikan solusi ini.

Patroni

Ini adalah template python untuk mengelola PostgreSQL dengan dokumentasi yang baik, failover otomatis, dan kode sumber di github.

Kelebihan Patroni:

  • Setiap parameter konfigurasi dijelaskan, cara kerjanya jelas;
  • Failover otomatis berfungsi dengan baik;
  • Ditulis dengan python, dan karena kita sendiri banyak menulis dengan python, akan lebih mudah bagi kita untuk mengatasi masalah dan bahkan mungkin membantu pengembangan proyek;
  • Mengelola PostgreSQL sepenuhnya, memungkinkan Anda mengubah konfigurasi pada semua node cluster sekaligus, dan jika cluster perlu di-restart untuk menerapkan konfigurasi baru, maka ini dapat dilakukan lagi menggunakan Patroni.

Cons:

  • Dari dokumentasi tidak jelas bagaimana cara bekerja dengan PgBouncer dengan benar. Walaupun sulit untuk menyebutnya minus, karena tugas Patroni adalah mengelola PostgreSQL, dan bagaimana koneksi ke Patroni akan berjalan sudah menjadi masalah kita;
  • Ada sedikit contoh implementasi Patroni dalam volume besar, sementara banyak contoh implementasi dari awal.

Hasilnya, kami memilih Patroni untuk membuat kluster failover.

Proses Implementasi Patroni

Sebelum Patroni, kami memiliki 12 shard PostgreSQL dalam konfigurasi satu master dan satu replika dengan replikasi asinkron. Server aplikasi mengakses database melalui Network Load Balancer, di belakangnya terdapat dua instance dengan PgBouncer, dan di belakangnya terdapat semua server PostgreSQL.
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Untuk mengimplementasikan Patroni, kami perlu memilih konfigurasi cluster penyimpanan terdistribusi. Patroni bekerja dengan sistem penyimpanan konfigurasi terdistribusi seperti dll, Zookeeper, Konsul. Kami hanya memiliki cluster Konsul lengkap di pasar, yang berfungsi bersama dengan Vault dan kami tidak menggunakannya lagi. Alasan bagus untuk mulai menggunakan Konsul untuk tujuan yang dimaksudkan.

Bagaimana Patroni bekerja dengan Konsul

Kami memiliki cluster Konsul, yang terdiri dari tiga node, dan cluster Patroni, yang terdiri dari pemimpin dan replika (di Patroni, master disebut pemimpin cluster, dan budak disebut replika). Setiap instance cluster Patroni terus-menerus mengirimkan informasi tentang status cluster ke Konsul. Oleh karena itu, dari Konsul Anda selalu dapat mengetahui konfigurasi cluster Patroni saat ini dan siapa pemimpinnya saat ini.

Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Untuk menghubungkan Patroni ke Konsul, cukup mempelajari dokumentasi resmi, yang menyatakan bahwa Anda perlu menentukan host dalam format http atau https, tergantung cara kami bekerja dengan Konsul, dan skema koneksi, opsional:

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

Kelihatannya sederhana, tapi di sinilah jebakannya dimulai. Dengan Konsul, kami bekerja melalui koneksi aman melalui https dan konfigurasi koneksi kami akan terlihat seperti ini:

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

Tapi itu tidak berhasil. Saat startup, Patroni tidak dapat terhubung ke Konsul, karena tetap mencoba melalui http.

Kode sumber Patroni membantu mengatasi masalah tersebut. Untung itu ditulis dengan python. Ternyata parameter host tidak diurai dengan cara apa pun, dan protokol harus ditentukan dalam skema. Seperti inilah blok konfigurasi kerja 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 penyimpanan untuk konfigurasi. Sekarang kita perlu memahami bagaimana PgBouncer akan mengubah konfigurasinya ketika mengubah pemimpin di cluster Patroni. Tidak ada jawaban untuk pertanyaan ini di dokumentasi, karena. di sana, pada prinsipnya, pekerjaan dengan PgBouncer tidak dijelaskan.

Untuk mencari solusi, kami menemukan sebuah artikel (sayangnya saya tidak ingat judulnya) yang tertulis bahwa template Konsul banyak membantu dalam memasangkan PgBouncer dan Patroni. Hal ini mendorong kami untuk menyelidiki cara kerja template Konsul.

Ternyata template Konsul terus memantau konfigurasi cluster PostgreSQL di Konsul. Saat pemimpin berubah, ia memperbarui konfigurasi PgBouncer dan mengirimkan perintah untuk memuat ulang.

Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Kelebihan besar dari templat adalah ia disimpan sebagai kode, jadi ketika menambahkan pecahan baru, cukup membuat komit baru dan memperbarui templat secara otomatis, mendukung prinsip Infrastruktur sebagai kode.

Arsitektur baru dengan Patroni

Hasilnya, kami mendapat skema kerja berikut:
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Semua server aplikasi mengakses penyeimbang β†’ ada dua contoh PgBouncer di belakangnya β†’ pada setiap contoh, templat Konsul diluncurkan, yang memantau status setiap cluster Patroni dan memantau relevansi konfigurasi PgBouncer, yang mengirimkan permintaan ke pemimpin saat ini dari setiap cluster.

Pengujian manual

Kami menjalankan skema ini sebelum meluncurkannya pada lingkungan pengujian kecil dan memeriksa pengoperasian peralihan otomatis. Mereka membuka papan, memindahkan stiker, dan saat itu juga mereka β€œmembunuh” pemimpin cluster. Di AWS, hal ini semudah mematikan instance melalui konsol.

Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Stiker itu kembali dalam waktu 10-20 detik, dan kemudian mulai bergerak normal lagi. Ini berarti cluster Patroni bekerja dengan benar: ia mengubah pemimpinnya, mengirimkan informasi ke Konsul, dan templat Konsul segera mengambil informasi ini, mengganti konfigurasi PgBouncer dan mengirimkan perintah untuk memuat ulang.

Bagaimana cara bertahan di bawah beban tinggi dan meminimalkan waktu henti?

Semuanya bekerja dengan sempurna! Namun ada pertanyaan baru: Bagaimana cara kerjanya di bawah beban tinggi? Bagaimana cara meluncurkan segala sesuatu dalam produksi dengan cepat dan aman?

Lingkungan pengujian tempat kami melakukan pengujian beban membantu kami menjawab pertanyaan pertama. Ini benar-benar identik dengan produksi dalam hal arsitektur dan telah menghasilkan data pengujian yang volumenya kira-kira sama dengan produksi. Kami memutuskan untuk β€œmembunuh” salah satu master PostgreSQL selama pengujian dan melihat apa yang terjadi. Namun sebelum itu, penting untuk memeriksa pengguliran otomatis, karena pada lingkungan ini kami memiliki beberapa pecahan PostgreSQL, jadi kami akan mendapatkan pengujian skrip konfigurasi yang sangat baik sebelum produksi.

Kedua tugas tersebut terlihat ambisius, tetapi kami memiliki PostgreSQL 9.6. Bisakah kita segera mengupgrade ke 11.2?

Kami memutuskan untuk melakukannya dalam 2 langkah: pertama tingkatkan ke 11.2, lalu luncurkan Patroni.

Pembaruan PostgreSQL

Untuk memperbarui versi PostgreSQL dengan cepat, gunakan opsi ini -k, di mana tautan keras dibuat pada disk dan tidak perlu menyalin data Anda. Pada basis 300-400 GB, pembaruan memerlukan waktu 1 detik.

Kami memiliki banyak pecahan, jadi pembaruan perlu dilakukan secara otomatis. Untuk melakukan ini, kami menulis buku pedoman Ansible yang menangani seluruh proses pembaruan 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='

Penting untuk dicatat di sini bahwa sebelum memulai pemutakhiran, Anda harus melakukannya dengan parameter --memeriksauntuk memastikan Anda dapat meningkatkan. Skrip kami juga melakukan penggantian konfigurasi selama durasi peningkatan. Skrip kami selesai dalam 30 detik, yang merupakan hasil luar biasa.

Luncurkan Patroni

Untuk mengatasi masalah kedua, lihat saja konfigurasi Patroni. Repositori resmi memiliki contoh konfigurasi dengan initdb, yang bertanggung jawab untuk menginisialisasi database baru saat Anda pertama kali memulai Patroni. Namun karena kami sudah memiliki database yang sudah jadi, kami cukup menghapus bagian ini dari konfigurasi.

Ketika kami mulai menginstal Patroni pada cluster PostgreSQL yang sudah ada dan menjalankannya, kami mengalami masalah baru: kedua server dimulai sebagai yang terdepan. Patroni tidak mengetahui apa pun tentang keadaan awal cluster dan mencoba memulai kedua server sebagai dua cluster terpisah dengan nama yang sama. Untuk mengatasi masalah ini, Anda perlu menghapus direktori dengan data di slave:

rm -rf /var/lib/postgresql/

Hal ini perlu dilakukan hanya pada budak!

Ketika replika bersih tersambung, Patroni membuat pemimpin basebackup dan mengembalikannya ke replika, lalu mengejar status saat ini sesuai dengan log wal.

Kesulitan lain yang kami temui adalah semua cluster PostgreSQL diberi nama main secara default. Jika setiap cluster tidak mengetahui apa pun tentang cluster lainnya, hal ini normal. Namun bila ingin menggunakan Patroni, maka semua cluster harus memiliki nama yang unik. Solusinya adalah dengan mengubah nama cluster pada konfigurasi PostgreSQL.

tes beban

Kami telah meluncurkan pengujian yang menyimulasikan pengalaman pengguna di papan. Ketika beban mencapai nilai rata-rata harian kami, kami mengulangi pengujian yang sama persis, kami mematikan satu instance dengan pemimpin PostgreSQL. Kegagalan otomatis berfungsi seperti yang kami harapkan: Patroni mengubah pemimpin, templat Konsul memperbarui konfigurasi PgBouncer dan mengirim perintah untuk memuat ulang. Berdasarkan grafik kami di Grafana, terlihat jelas bahwa terdapat penundaan 20-30 detik dan sejumlah kecil kesalahan dari server terkait dengan koneksi ke database. Ini adalah situasi normal, nilai seperti itu dapat diterima untuk failover kami dan tentunya lebih baik daripada waktu henti layanan.

Membawa Patroni ke produksi

Hasilnya, kami membuat rencana berikut:

  • Terapkan templat Konsul ke server PgBouncer dan luncurkan;
  • Pembaruan PostgreSQL ke versi 11.2;
  • Ubah nama cluster;
  • Memulai Klaster Patroni.

Pada saat yang sama, skema kami memungkinkan kami untuk membuat poin pertama hampir kapan saja, kami dapat menghapus setiap PgBouncer dari pekerjaan secara bergantian dan menerapkan serta menjalankan templat konsultasi di atasnya. Jadi kami melakukannya.

Untuk penerapan cepat, kami menggunakan Ansible, karena kami telah menguji semua playbook di lingkungan pengujian, dan waktu eksekusi skrip lengkap adalah 1,5 hingga 2 menit untuk setiap shard. Kami dapat meluncurkan semuanya secara bergantian ke setiap shard tanpa menghentikan layanan kami, namun kami harus mematikan setiap PostgreSQL selama beberapa menit. Dalam kasus ini, pengguna yang datanya ada di shard ini tidak dapat berfungsi sepenuhnya saat ini, dan hal ini tidak dapat kami terima.

Jalan keluar dari situasi ini adalah pemeliharaan terencana yang dilakukan setiap 3 bulan sekali. Ini adalah jendela untuk pekerjaan terjadwal, saat kami sepenuhnya mematikan layanan dan meningkatkan instance database kami. Masih ada satu minggu lagi hingga jendela berikutnya, dan kami memutuskan untuk menunggu dan mempersiapkan lebih lanjut. Selama waktu tunggu, kami juga mengamankan diri kami sendiri: untuk setiap shard PostgreSQL, kami membuat replika cadangan jika terjadi kegagalan dalam menyimpan data terbaru, dan menambahkan instance baru untuk setiap shard, yang akan menjadi replika baru di cluster Patroni, agar tidak menjalankan perintah untuk menghapus data. Semua ini membantu meminimalkan risiko kesalahan.
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Kami memulai kembali layanan kami, semuanya berjalan sebagaimana mestinya, pengguna terus bekerja, tetapi pada grafik kami melihat beban tinggi yang tidak normal di server Konsul.
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Mengapa kita tidak melihat ini di lingkungan pengujian? Masalah ini menggambarkan dengan baik bahwa perlunya mengikuti prinsip Infrastruktur sebagai kode dan menyempurnakan seluruh infrastruktur, mulai dari lingkungan pengujian hingga produksi. Jika tidak, sangat mudah untuk mendapatkan masalah yang kita hadapi. Apa yang telah terjadi? Konsul pertama kali muncul di produksi, dan kemudian di lingkungan pengujian, akibatnya, di lingkungan pengujian, versi Konsul lebih tinggi daripada di produksi. Hanya dalam salah satu rilis, kebocoran CPU teratasi saat bekerja dengan templat konsul. Oleh karena itu, kami cukup memperbarui Konsul, sehingga menyelesaikan masalah.

Mulai ulang klaster Patroni

Namun, kami mendapat masalah baru, yang bahkan tidak kami duga. Saat mengupdate Konsul, kita cukup menghapus node Konsul dari cluster menggunakan perintah cuti konsul β†’ Patroni terhubung ke server Konsul lain β†’ semuanya berfungsi. Namun ketika kami mencapai instance terakhir dari cluster Konsul dan mengirimkan perintah cuti konsul ke sana, semua cluster Patroni langsung dimulai ulang, dan di log kami melihat kesalahan 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>

Kluster Patroni tidak dapat mengambil informasi tentang klusternya dan memulai ulang.

Untuk mencari solusinya, kami menghubungi penulis Patroni melalui masalah di github. Mereka menyarankan perbaikan pada file konfigurasi kami:

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

Kami dapat mereplikasi masalah pada lingkungan pengujian dan menguji opsi ini di sana, namun sayangnya opsi tersebut tidak berhasil.

Masalahnya masih belum terselesaikan. Kami berencana untuk mencoba solusi berikut:

  • Gunakan Agen Konsul pada setiap instance cluster Patroni;
  • Perbaiki masalah pada kode.

Kami memahami di mana kesalahan terjadi: masalahnya mungkin adalah penggunaan batas waktu default, yang tidak diganti melalui file konfigurasi. Ketika server Konsul terakhir dihapus dari cluster, seluruh cluster Konsul hang selama lebih dari satu detik, karena itu, Patroni tidak bisa mendapatkan status cluster dan me-restart seluruh cluster sepenuhnya.

Untungnya, kami tidak menemukan kesalahan lagi.

Hasil penggunaan Patroni

Setelah peluncuran Patroni berhasil, kami menambahkan replika tambahan di setiap cluster. Sekarang di setiap cluster ada kemiripan kuorum: satu pemimpin dan dua replika, untuk jaring pengaman jika terjadi split-brain saat berpindah.
Klaster Failover PostgreSQL + Patroni. Pengalaman implementasi

Patroni telah mengerjakan produksi selama lebih dari tiga bulan. Selama ini, dia sudah berhasil membantu kami. Baru-baru ini, pemimpin salah satu klaster meninggal di AWS, failover otomatis berfungsi dan pengguna terus bekerja. Patroni memenuhi tugas utamanya.

Ringkasan kecil penggunaan Patroni:

  • Kemudahan perubahan konfigurasi. Cukup mengubah konfigurasi pada satu instance dan itu akan ditarik ke seluruh cluster. Jika reboot diperlukan untuk menerapkan konfigurasi baru, Patroni akan memberi tahu Anda. Patroni dapat memulai ulang seluruh cluster dengan satu perintah, yang juga sangat nyaman.
  • Failover otomatis berfungsi dan telah berhasil membantu kami.
  • Pembaruan PostgreSQL tanpa downtime aplikasi. Anda harus memperbarui replika ke versi baru terlebih dahulu, lalu mengubah pemimpin di klaster Patroni dan memperbarui pemimpin lama. Dalam hal ini, pengujian failover otomatis yang diperlukan terjadi.

Sumber: www.habr.com

Tambah komentar