PostgreSQL dan catat pengaturan konsistensi untuk setiap koneksi tertentu

Terjemahan artikel ini disiapkan khusus untuk siswa kursus "Database" . Apakah menarik untuk dikembangkan ke arah ini? Kami mengundang Anda ke Open Doors Day , di mana kami berbicara secara rinci tentang program, fitur format online, kompetensi, dan prospek karier yang menunggu lulusan setelah pelatihan.



PostgreSQL dan catat pengaturan konsistensi untuk setiap koneksi tertentu
Di Compose, kita harus berurusan dengan banyak basis data, yang memberi kita kesempatan untuk mengetahui lebih banyak tentang fungsi dan kelemahannya. Ketika kita belajar untuk menyukai fitur-fitur fungsional dari basis data baru, kita kadang-kadang mulai berpikir tentang seberapa bagusnya jika fungsi-fungsi serupa hadir dalam alat yang lebih matang yang telah kita kerjakan sejak lama. Salah satu fitur baru yang ingin dilihat PostgreSQL adalah konsistensi penulisan kustom di seluruh cluster. Dan ternyata, kami sudah memilikinya, dan hari ini kami ingin berbagi dengan Anda informasi tentang bagaimana Anda dapat menggunakannya.


Mengapa saya membutuhkan ini?


Bagaimana kelakuan kluster tergantung pada aplikasi Anda. Ambil, misalnya, aplikasi untuk membayar tagihan. Anda akan membutuhkan 100% konsistensi di cluster, jadi Anda harus mengaktifkan komit sinkron sehingga database Anda menunggu semua perubahan dibuat. Namun, jika aplikasi Anda adalah jejaring sosial yang tumbuh cepat, maka Anda mungkin akan lebih suka 100% konsistensi dengan respons yang cepat. Untuk mencapai ini, Anda bisa menggunakan komit asinkron di kluster Anda.


Temui kompromi


Anda harus berkompromi antara konsistensi data dan kinerja. PostgreSQL langkah dari konsistensi, karena konfigurasi default dalam hal ini dapat diprediksi dan tanpa kejutan yang tidak terduga. Dan sekarang kita akan berkenalan dengan kompromi.


Kompromi 1: Kinerja


Jika cluster PostgreSQL tidak memerlukan konsistensi, itu mungkin berfungsi secara tidak sinkron. Rekaman dilakukan kepada pemimpin cluster, dan pembaruan akan dikirim ke replika-nya setelah beberapa milidetik. Ketika diperlukan konsistensi untuk cluster PostgreSQL, itu harus bekerja secara sinkron. Catatan akan dibuat di pemimpin gugus, yang akan mengirim pembaruan ke replika dan menunggu konfirmasi bahwa semua orang membuat catatan sebelum mengirim konfirmasi kepada klien yang memprakarsai catatan bahwa itu berhasil. Perbedaan praktis antara pendekatan ini adalah bahwa metode asinkron membutuhkan dua lompatan jaringan, sedangkan metode sinkron memerlukan empat.


Kompromi 2: Konsistensi


Hasil jika terjadi kegagalan pemimpin dalam dua pendekatan ini juga akan berbeda. Jika pekerjaan dilakukan secara tidak sinkron, maka ketika kesalahan tersebut terjadi, tidak semua catatan akan dilakukan oleh replika. Berapa banyak yang akan hilang? Tergantung pada aplikasi itu sendiri dan efisiensi replikasi. Menulis replikasi akan mencegah replika menjadi pemimpin jika jumlah informasi di dalamnya adalah 1 MB lebih sedikit dari pada pemimpin, yaitu, hingga 1 MB catatan berpotensi hilang selama operasi asinkron.


Dalam mode sinkron, ini tidak terjadi. Jika pemimpin gagal, semua replika diperbarui, karena catatan apa pun yang dikonfirmasi pada pemimpin harus dikonfirmasi dalam replika. Ini dia - koherensi.


Masuk akal untuk menggunakan perilaku sinkron dalam aplikasi untuk membayar tagihan, di mana konsistensi memiliki keuntungan yang jelas dalam menemukan kompromi antara konsistensi dan kinerja. Hal terpenting untuk aplikasi semacam itu adalah data yang valid. Sekarang ingat tentang jejaring sosial, di mana tugas utamanya adalah untuk menjaga perhatian pengguna, menanggapi permintaan secepat mungkin. Dalam hal ini, kinerja dengan lompatan jaringan yang lebih sedikit dan komitmen menunggu yang lebih sedikit akan menjadi prioritas. Namun, tradeoff antara kinerja dan konsistensi bukan satu-satunya yang dipikirkan.


Kompromi 3: Kegagalan


Sangat penting untuk memahami bagaimana perilaku cluster selama kegagalan. Pertimbangkan situasi di mana satu atau lebih replika gagal. Ketika komit diproses secara tidak sinkron, pemimpin akan terus berfungsi, yaitu, menerima dan memproses catatan tanpa menunggu replika yang hilang. Ketika replika kembali ke kluster, mereka menyusul pemimpin. Dengan replikasi sinkron, jika replika tidak merespons, maka pemimpin tidak akan punya pilihan dan dia akan terus menunggu konfirmasi komit sampai replika kembali ke cluster dan dapat menerima dan mengkonfirmasi catatan.


Satu koneksi per transaksi?


Setiap aplikasi memerlukan jenis khusus kombinasi konsistensi dan kinerja. Kecuali tentu saja itu adalah aplikasi penagihan kami, yang kami pikir benar-benar konsisten, atau aplikasi jejaring sosial kami yang hampir fana. Dalam semua kasus lain, akan ada kalanya beberapa operasi harus sinkron dan beberapa asinkron. Anda mungkin tidak ingin sistem menunggu sampai pesan yang dikirim ke obrolan dilakukan, tetapi jika pembayaran dilakukan dalam aplikasi yang sama, Anda harus menunggu.


Semua keputusan ini, tentu saja, dibuat oleh pengembang aplikasi. Keputusan yang tepat tentang kapan menerapkan pendekatan ini atau itu akan membantu untuk memaksimalkan cluster. Penting bahwa pengembang dapat beralih di antara mereka di tingkat SQL untuk koneksi dan untuk transaksi.


Memberikan kontrol dalam praktik


Secara default, PostgreSQL menyediakan konsistensi. Ini dikendalikan oleh parameter server syncous_commit. Secara default on , tetapi memiliki tiga opsi lain: local , remote_write atau tidak off .


Ketika parameter diatur ke off , semua komit sinkron dihentikan, bahkan di sistem lokal. Parameter di lokal menentukan mode sinkron untuk sistem lokal, tetapi menulis ke replika tidak sinkron. Remote_write melangkah lebih jauh: menulis ke replika dibuat secara tidak sinkron, tetapi dikembalikan ketika replika menerima catatan tetapi tidak menuliskannya ke disk.


Mempertimbangkan berbagai pilihan yang tersedia, kami memilih perilaku dan, mengingat bahwa on adalah catatan sinkron, kami memilih local untuk melakukan asinkron pada jaringan, sementara meninggalkan lokal melakukan sinkron.


Sekarang, kami akan memberi tahu Anda cara mengonfigurasikan ini dalam sekejap, tetapi bayangkan bahwa kami mengatur synchronous_commit ke local untuk server. Kami bertanya pada diri sendiri apakah mungkin untuk mengubah parameter synchronous_commit dengan cepat, dan ternyata itu tidak hanya mungkin, bahkan ada dua cara untuk melakukan ini. Yang pertama adalah mengatur sesi koneksi Anda sebagai berikut:


 SET SESSION synchronous_commit TO ON; // Your writes go here 

Semua catatan selanjutnya dalam sesi ini akan mengkonfirmasi operasi penulisan untuk replika sebelum mengembalikan hasil positif ke klien yang terhubung. Kecuali, tentu saja, Anda mengubah pengaturan synchronous_commit lagi. Anda dapat menghilangkan bagian SESSION dari perintah karena itu akan menjadi nilai default.


Cara kedua baik ketika Anda hanya ingin memastikan Anda mendapatkan replikasi sinkron untuk satu transaksi. Di banyak basis data NoSQL, konsep transaksi tidak ada, tetapi ada di PostgreSQL. Dalam hal ini, Anda memulai transaksi, dan kemudian setel synchronous_commit ke on sebelum menulis ke transaksi. COMMIT transaksi menggunakan nilai parameter synchronous_commit apa pun yang ditetapkan pada saat itu, meskipun yang terbaik adalah mengatur variabel terlebih dahulu untuk memastikan bahwa pengembang lain memahami bahwa catatan tidak asinkron.


 BEGIN; SET LOCAL synchronous_commit TO ON; // Your writes go here COMMIT; 

Semua komitmen transaksi sekarang akan dikonfirmasikan sebagai ditulis ke replika bahkan sebelum database mengembalikan respons positif kepada klien yang terhubung.


Penyiapan postgreSQL


Sebelum itu, kami membayangkan sistem PostgreSQL dengan synchronous_commit diatur ke local . Agar ini nyata di sisi server, Anda perlu mengatur dua parameter konfigurasi server. Parameter synchronous_standby_names lain akan mengambil alih ketika synchronous_commit on . Ini menentukan replika mana yang memenuhi syarat untuk melakukan sinkron, dan kami akan mengaturnya ke * , yang berarti bahwa semua replika diaktifkan. Nilai-nilai ini biasanya dikonfigurasi dalam file konfigurasi dengan menambahkan:


 synchronous_commit = local synchronous_standby_names='*' 

Dengan mengatur parameter synchronous_commit ke local , kami membuat sistem di mana drive lokal tetap sinkron, tetapi komit replika jaringan asinkron secara default. Kecuali, tentu saja, kami memutuskan untuk membuat ini sinkron, seperti yang ditunjukkan di atas.


Jika Anda mengikuti pengembangan proyek Governor , Anda mungkin telah memperhatikan beberapa perubahan terbaru ( 1 , 2 ), yang memungkinkan pengguna Governor untuk menguji parameter ini dan mengontrol konsistensi mereka.


Beberapa kata lagi ...


Hanya seminggu yang lalu, saya akan memberi tahu Anda bahwa PostgreSQL tidak bisa disempurnakan dengan begitu halus. Saat itulah Kurt, anggota tim platform Compose, bersikeras bahwa ada kesempatan seperti itu. Dia menenangkan keberatan saya dan menemukan yang berikut ini dalam dokumentasi PostgreSQL:



Parameter ini dapat diubah kapan saja. Perilaku untuk setiap transaksi ditentukan oleh pengaturan yang berlaku saat melakukan. Oleh karena itu, dimungkinkan dan bermanfaat bagi komitmen untuk berkomitmen secara sinkron untuk beberapa transaksi, dan secara tidak sinkron untuk yang lain. Misalnya, untuk memaksa satu transaksi multistatement untuk melakukan asynchronous ketika nilai default parameter adalah sebaliknya, set SET LOCAL synchronous_commit TO OFF dalam transaksi.


Dengan modifikasi kecil dalam file konfigurasi ini, kami memberi pengguna kemampuan untuk mengontrol konsistensi dan kinerja mereka.

Source: https://habr.com/ru/post/id472364/


All Articles