Mengapa Anda memerlukan replikasi semi-sinkron?

Halo semua. Vladislav Rodin menghubungi kami. Saat ini saya mengajar kursus Arsitektur Perangkat Lunak dan Arsitektur Perangkat Lunak Stres Tinggi di OTUS. Untuk mengantisipasi dimulainya alur kursus baru "Arsitek Beban Tinggi" Saya memutuskan untuk menulis materi singkat asli yang ingin saya bagikan kepada Anda.

Mengapa Anda memerlukan replikasi semi-sinkron?

pengenalan

Karena fakta bahwa HDD hanya dapat melakukan sekitar 400-700 operasi per detik (yang tidak dapat dibandingkan dengan rps tipikal pada sistem beban tinggi), database disk klasik adalah penghambat arsitektur. Oleh karena itu, perlu adanya perhatian khusus terhadap pola penskalaan penyimpanan ini.

Saat ini, ada 2 pola penskalaan database: replikasi dan sharding. Sharding memungkinkan Anda menskalakan operasi penulisan dan, sebagai hasilnya, mengurangi rps per penulisan per server di cluster Anda. Replikasi memungkinkan Anda melakukan hal yang sama, tetapi dengan operasi baca. Pola inilah yang dikhususkan untuk artikel ini.

replikasi

Jika Anda melihat replikasi pada tingkat yang sangat tinggi, masalahnya sederhana: Anda memiliki satu server, ada data di dalamnya, dan server ini tidak dapat lagi mengatasi beban membaca data ini. Anda menambahkan beberapa server lagi, menyinkronkan data di semua server, dan pengguna dapat membaca dari server mana pun di cluster Anda.

Meskipun tampak sederhana, ada beberapa opsi untuk mengklasifikasikan berbagai implementasi skema ini:

  • Berdasarkan peran dalam cluster (master-master atau master-slave)
  • Berdasarkan objek yang dikirim (berbasis baris, berbasis pernyataan, atau campuran)
  • Menurut mekanisme sinkronisasi node

Hari ini kita akan membahas poin 3.

Bagaimana komit transaksi terjadi?

Topik ini tidak terkait langsung dengan replikasi; artikel terpisah dapat ditulis tentangnya, tetapi karena membaca lebih lanjut tidak ada gunanya tanpa memahami mekanisme penerapan transaksi, izinkan saya mengingatkan Anda tentang hal-hal paling mendasar. Komitmen transaksi terjadi dalam 3 tahap:

  1. Mencatat transaksi ke log database.
  2. Menggunakan transaksi di mesin database.
  3. Mengembalikan konfirmasi kepada klien bahwa transaksi berhasil diterapkan.

Dalam database yang berbeda, algoritme ini mungkin memiliki perbedaan: misalnya, di mesin InnoDB di database MySQL terdapat 2 log: satu untuk replikasi (log biner), dan yang lainnya untuk memelihara ACID (undo/redo log), sedangkan di PostgreSQL ada satu log yang menjalankan kedua fungsi tersebut (tulis log depan = WAL). Namun apa yang disajikan di atas justru merupakan konsep umum, yang memungkinkan nuansa seperti itu tidak diperhitungkan.

Replikasi sinkron (sinkronisasi).

Mari tambahkan logika untuk mereplikasi perubahan yang diterima pada algoritma penerapan transaksi:

  1. Mencatat transaksi ke log database.
  2. Menggunakan transaksi di mesin database.
  3. Mengirim data ke semua replika.
  4. Menerima konfirmasi dari semua replika bahwa transaksi telah selesai.
  5. Mengembalikan konfirmasi kepada klien bahwa transaksi berhasil diterapkan.

Dengan pendekatan ini kita mendapatkan sejumlah kelemahan:

  • klien menunggu perubahan diterapkan ke semua replika.
  • seiring bertambahnya jumlah node dalam cluster, kami mengurangi kemungkinan keberhasilan operasi penulisan.

Jika semuanya kurang lebih jelas dengan poin pertama, maka alasan poin kedua layak untuk dijelaskan. Jika selama replikasi sinkron kami tidak menerima respons dari setidaknya satu node, kami mengembalikan transaksi tersebut. Jadi, dengan meningkatkan jumlah node dalam cluster, Anda meningkatkan kemungkinan kegagalan operasi penulisan.

Bisakah kita menunggu konfirmasi hanya dari persentase node tertentu saja, misalnya dari 51% (kuorum)? Ya, kami bisa, tetapi dalam versi klasik, konfirmasi dari semua node diperlukan, karena ini adalah cara kami memastikan konsistensi data yang lengkap di cluster, yang merupakan keuntungan yang tidak diragukan lagi dari jenis replikasi ini.

Replikasi asinkron (asinkron).

Mari kita modifikasi algoritma sebelumnya. Kami akan mengirimkan data ke replika “suatu saat nanti”, dan “suatu saat nanti” perubahan akan diterapkan pada replika:

  1. Mencatat transaksi ke log database.
  2. Menggunakan transaksi di mesin database.
  3. Mengembalikan konfirmasi kepada klien bahwa transaksi berhasil diterapkan.
  4. Mengirim data ke replika dan menerapkan perubahan pada replika tersebut.

Pendekatan ini mengarah pada fakta bahwa cluster bekerja dengan cepat, karena kami tidak membiarkan klien menunggu data mencapai replika dan bahkan dikomit.

Namun kondisi dumping data ke replika “suatu saat nanti” dapat mengakibatkan hilangnya suatu transaksi, dan hilangnya transaksi yang dikonfirmasi oleh pengguna, karena jika data tidak sempat untuk direplikasi, maka akan ada konfirmasi ke klien. tentang keberhasilan operasi yang dikirim, dan node tempat perubahan tiba, HDD rusak, kami kehilangan transaksi, yang dapat menyebabkan konsekuensi yang sangat tidak menyenangkan.

Replikasi semisinkron

Akhirnya kita sampai pada replikasi semi-sinkron. Jenis replikasi ini tidak begitu terkenal atau sangat umum, namun cukup menarik karena dapat menggabungkan keunggulan replikasi sinkron dan asinkron.

Mari kita coba menggabungkan 2 pendekatan sebelumnya. Kami tidak akan mempertahankan klien dalam waktu lama, namun kami mengharuskan data direplikasi:

  1. Mencatat transaksi ke log database.
  2. Menggunakan transaksi di mesin database.
  3. Mengirim data ke replika.
  4. Menerima konfirmasi dari replika bahwa perubahan telah diterima (akan diterapkan “suatu saat nanti”).
  5. Mengembalikan konfirmasi kepada klien bahwa transaksi berhasil diterapkan.

Harap dicatat bahwa dengan algoritma ini, kerugian transaksi hanya terjadi jika node yang menerima perubahan dan node replika gagal. Kemungkinan kegagalan tersebut dianggap rendah, dan risiko ini dapat diterima.

Namun dengan pendekatan ini, ada kemungkinan risiko pembacaan bayangan. Bayangkan skenario berikut: pada langkah 4, kita tidak menerima konfirmasi dari replika mana pun. Kami harus mengembalikan transaksi ini dan tidak mengembalikan konfirmasi kepada klien. Karena data diterapkan pada langkah 2, terdapat jeda waktu antara akhir langkah 2 dan pengembalian transaksi, di mana transaksi paralel dapat melihat perubahan yang seharusnya tidak ada dalam database.

Replikasi semisinkronisasi tanpa kehilangan

Jika Anda berpikir sedikit, Anda dapat membalikkan langkah-langkah algoritme dan memperbaiki masalah pembacaan hantu dalam skenario ini:

  1. Mencatat transaksi ke log database.
  2. Mengirim data replika.
  3. Menerima konfirmasi dari replika bahwa perubahan telah diterima (akan diterapkan “suatu saat nanti”).
  4. Menggunakan transaksi di mesin database.
  5. Mengembalikan konfirmasi kepada klien bahwa transaksi berhasil diterapkan.

Sekarang kami melakukan perubahan hanya jika perubahan tersebut telah direplikasi.

Keluaran

Seperti biasa, tidak ada solusi ideal; yang ada adalah serangkaian solusi, yang masing-masing memiliki kelebihan dan kekurangannya sendiri dan cocok untuk menyelesaikan berbagai kelas permasalahan. Hal ini sepenuhnya berlaku untuk memilih mekanisme untuk menyinkronkan data dalam database yang direplikasi. Serangkaian keunggulan yang dimiliki replikasi semi-sinkron cukup kuat dan menarik sehingga dapat dianggap layak untuk diperhatikan, meskipun prevalensinya rendah.

Itu saja. Sampai jumpa di kursus!

Sumber: www.habr.com

Tambah komentar