PostgreSQL dan pengaturan konsistensi penulisan khusus koneksi

Terjemahan artikel disiapkan khusus untuk mahasiswa kursus tersebut "Database". Tertarik untuk mengembangkan ke arah ini? Kami mengundang Anda untuk Hari terbuka, dimana kami membahas secara detail tentang program, fitur format online, kompetensi dan prospek karir yang menanti lulusan setelah pelatihan.

PostgreSQL dan pengaturan konsistensi penulisan khusus koneksi

PostgreSQL dan pengaturan konsistensi penulisan khusus koneksi
Di Compose, kami menangani banyak database, yang memberi kami kesempatan untuk lebih memahami fungsi dan kekurangannya. Saat kita mulai menyukai fitur-fitur database baru, terkadang kita mulai berpikir betapa menyenangkannya jika fitur serupa hadir di alat yang lebih matang yang telah lama kita gunakan. Salah satu fitur baru yang ingin saya lihat di PostgreSQL adalah konsistensi penulisan yang dapat dikonfigurasi untuk koneksi di seluruh cluster. Dan ternyata, kami sudah memilikinya, dan hari ini kami ingin berbagi dengan Anda informasi tentang cara menggunakannya.

Mengapa saya membutuhkannya?

Perilaku cluster bergantung pada aplikasi Anda. Ambil contoh, aplikasi pembayaran tagihan. Anda memerlukan konsistensi XNUMX% di seluruh cluster, jadi Anda harus mengaktifkan penerapan sinkron sehingga database Anda menunggu semua perubahan dilakukan. Namun, jika aplikasi Anda adalah jejaring sosial yang berkembang pesat, Anda mungkin lebih memilih respons cepat daripada konsistensi XNUMX%. Untuk mencapai hal ini, Anda dapat menggunakan penerapan asinkron di klaster Anda.

Temui kompromi

Anda harus membuat trade-off antara konsistensi data dan kinerja. PostgreSQL menjauh dari konsistensi karena konfigurasi default dapat diprediksi dan tanpa kejutan yang tidak terduga. Sekarang mari kita lihat komprominya.

Pengorbanan 1: Kinerja

Jika klaster PostgreSQL tidak memerlukan konsistensi, klaster tersebut dapat berjalan secara asinkron. Penulisan dilakukan ke pemimpin klaster, dan pembaruan akan dikirim ke replikanya beberapa milidetik kemudian. Ketika klaster PostgreSQL memerlukan konsistensi, klaster tersebut harus berjalan secara sinkron. Penulisan akan dilakukan ke pemimpin klaster, yang akan mengirimkan pembaruan ke replika dan menunggu konfirmasi bahwa masing-masing replika telah ditulis sebelum mengirimkan konfirmasi ke klien yang memulai penulisan bahwa penulisan berhasil. Perbedaan praktis antara pendekatan ini adalah bahwa metode asinkron memerlukan dua hop jaringan, sedangkan metode sinkron memerlukan empat hop jaringan.

Pengorbanan 2: Konsistensi

Akibat jika terjadi kegagalan pemimpin pada kedua pendekatan ini juga akan berbeda. Jika pekerjaan dilakukan secara asinkron, maka jika kesalahan seperti itu terjadi, tidak semua rekaman akan dilakukan oleh replika. Berapa banyak yang akan hilang? Tergantung pada aplikasi itu sendiri dan efisiensi replikasi. Replikasi penulisan akan mencegah replika menjadi pemimpin jika jumlah informasi di dalamnya 1 MB lebih sedikit daripada di pemimpin, artinya, hingga 1 MB catatan berpotensi hilang selama operasi asinkron.

Hal ini tidak terjadi dalam mode sinkron. Jika pemimpin gagal, semua replika diperbarui, karena setiap penulisan yang dikonfirmasi pada pemimpin harus dikonfirmasi pada replika. Ini adalah konsistensi.

Perilaku sinkron masuk akal dalam aplikasi penagihan dimana konsistensi memiliki keuntungan yang jelas dalam trade-off antara konsistensi dan kinerja. Hal terpenting untuk aplikasi semacam itu adalah data yang valid. Sekarang pikirkan tentang jejaring sosial yang tugas utamanya adalah menjaga perhatian pengguna dengan menanggapi permintaan secepat mungkin. Dalam hal ini, performa dengan lompatan jaringan yang lebih sedikit dan waktu tunggu yang lebih sedikit untuk penerapan akan menjadi prioritas. Namun, trade-off antara kinerja dan konsistensi bukanlah satu-satunya hal yang harus Anda pikirkan.

Pengorbanan 3: Kerusakan

Sangat penting untuk memahami bagaimana sebuah cluster berperilaku selama kegagalan. Pertimbangkan situasi ketika satu atau lebih replika gagal. Ketika penerapan diproses secara asinkron, pemimpin akan terus berfungsi, yaitu menerima dan memproses penulisan, tanpa menunggu replika yang hilang. Ketika replika kembali ke cluster, mereka mengejar pemimpinnya. Dengan replikasi sinkron, jika replika tidak merespons, maka pemimpin tidak punya pilihan dan akan terus menunggu konfirmasi penerapan hingga replika kembali ke klaster dan dapat menerima serta melakukan penulisan.

Satu koneksi per transaksi?

Setiap aplikasi memerlukan jenis kombinasi konsistensi dan kinerja yang berbeda. Kecuali, tentu saja, itu adalah aplikasi pembayaran tagihan kami, yang kami bayangkan sepenuhnya konsisten, atau aplikasi jejaring sosial kami yang hampir bersifat sementara. Dalam kasus lainnya, akan ada saatnya beberapa operasi harus sinkron dan beberapa harus asinkron. Anda mungkin tidak ingin sistem menunggu hingga pesan yang dikirim ke obrolan selesai, tetapi jika pembayaran diproses dalam aplikasi yang sama, Anda harus menunggu.

Semua keputusan ini tentu saja dibuat oleh pengembang aplikasi. Membuat keputusan yang tepat tentang kapan menggunakan setiap pendekatan akan membantu Anda mendapatkan hasil maksimal dari klaster Anda. Penting bagi pengembang untuk dapat beralih di antara keduanya pada tingkat SQL untuk koneksi dan transaksi.

Memastikan kontrol dalam praktik

Secara default, PostgreSQL memberikan konsistensi. Ini dikontrol oleh parameter server synchronous_commit. Secara default, ini ada di posisinya on, tetapi ia memiliki tiga opsi lain: local, remote_write ΠΈΠ»ΠΈ off.

Saat mengatur parameter ke off semua penerapan sinkron dihentikan, bahkan pada sistem lokal. Parameter lokal menentukan mode sinkron untuk sistem lokal, tetapi penulisan ke replika dilakukan secara asinkron. Remote_write bahkan lebih jauh lagi: penulisan ke replika dilakukan secara asinkron, namun dikembalikan ketika replika telah menerima penulisan namun belum menuliskannya ke disk.

Dengan mempertimbangkan berbagai pilihan yang tersedia, kita memilih suatu perilaku dan mengingatnya on – ini adalah rekaman sinkron, kami akan memilih local untuk penerapan asinkron melalui jaringan, dan membiarkan penerapan lokal tetap sinkron.

Sekarang, kami akan memberi tahu Anda cara menyiapkannya sebentar lagi, tetapi bayangkan kami yang menyiapkannya synchronous_commit Π² local untuk server. Kami bertanya-tanya apakah mungkin mengubah parameternya synchronous_commit dengan cepat, dan ternyata hal tersebut tidak hanya bisa dilakukan, bahkan ada dua cara untuk melakukannya. Yang pertama adalah mengatur sesi koneksi Anda sebagai berikut:

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

Semua penulisan berikutnya dalam sesi ini akan mengakui penulisan ke replika sebelum mengembalikan hasil positif ke klien yang terhubung. Kecuali tentu saja Anda mengubah pengaturannya synchronous_commit lagi. Anda dapat menghilangkan sebagian SESSION dalam perintah karena akan berada dalam nilai default.

Metode kedua bagus jika Anda hanya ingin memastikan Anda mendapatkan replikasi sinkron untuk satu transaksi. Di banyak database generasi NoSQL, konsep transaksi tidak ada, tetapi di PostgreSQL ada. Dalam hal ini Anda memulai transaksi dan kemudian mengaturnya synchronous_commit Π² on sebelum mengeksekusi entri untuk transaksi. COMMIT akan melakukan transaksi menggunakan nilai parameter apa pun synchronous_commit, yang disetel pada saat itu, meskipun yang terbaik adalah menyetel variabel terlebih dahulu untuk memastikan pengembang lain memahami bahwa penulisan tidak dilakukan secara asinkron.

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

Semua transaksi yang dilakukan sekarang akan dikonfirmasi sebagai ditulis ke replika sebelum database mengembalikan respons positif ke klien yang terhubung.

Konfigurasi PostgreSQL

Sebelumnya, kami membayangkan sistem PostgreSQL dengan synchronous_commit, dipasang di local. Untuk menjadikannya realistis di sisi server, Anda perlu mengatur dua opsi konfigurasi server. Satu parameter lagi synchronous_standby_names akan datang dengan sendirinya kapan synchronous_commit akan masuk on. Ini menentukan replika mana yang memenuhi syarat untuk penerapan sinkron, dan kami akan mengaturnya *, yang berarti semua replika terlibat. Nilai-nilai ini biasanya dikonfigurasikan file konfigurasi dengan menambahkan:

synchronous_commit = local  
synchronous_standby_names='*'

Dengan mengatur parameternya synchronous_commit ke dalam makna local, kami membuat sistem di mana disk lokal tetap sinkron, tetapi penerapan replika jaringan tidak sinkron secara default. Kecuali, tentu saja, kami memutuskan untuk membuat penerapan ini sinkron, seperti yang ditunjukkan di atas.

Jika Anda telah mengikuti perkembangannya Proyek Gubernur, Anda mungkin telah memperhatikan beberapa perubahan terkini (1, 2), yang memungkinkan pengguna Gubernur menguji parameter ini dan memantau konsistensinya.

Beberapa kata lagi...

Seminggu yang lalu, saya akan memberi tahu Anda bahwa tidak mungkin menyempurnakan PostgreSQL dengan begitu baik. Saat itulah Kurt, anggota tim platform Compose, menegaskan bahwa peluang seperti itu ada. Dia menenangkan keberatan saya dan menemukannya di dokumentasi PostgreSQL berikut ini:

PostgreSQL dan pengaturan konsistensi penulisan khusus koneksi

Pengaturan ini dapat diubah kapan saja. Perilaku transaksi apa pun ditentukan oleh pengaturan yang berlaku pada saat penerapan. Oleh karena itu, beberapa transaksi mungkin dan berguna untuk dilakukan secara sinkron dan untuk transaksi lainnya secara asinkron. Misalnya saja untuk memaksanya multistatement transaksi untuk membuat komit secara asinkron ketika nilai default parameter berlawanan, ditetapkan SET LOCAL synchronous_commit TO OFF dalam sebuah transaksi.

Dengan modifikasi kecil pada file konfigurasi ini, kami memberi pengguna kendali atas konsistensi dan kinerjanya.

Sumber: www.habr.com

Tambah komentar