Berurusan dengan transaksi besar selalu menjadi kendala di Galera Cluster. Cara kerja sertifikasi writeset Galera menyebabkan masalah saat transaksi panjang atau saat satu baris sering dimodifikasi pada banyak node. Akibatnya, transaksi harus dibatalkan dan dicoba lagi yang menyebabkan penurunan kinerja. Untungnya, masalah ini telah diatasi di Galera 4, rilis baru Galera dari Codership. Pustaka ini digunakan di MariaDB 10.4, jadi menginstal MariaDB 10.4 cara termudah untuk menguji fitur yang baru diperkenalkan. Dalam posting blog ini kita akan melihat bagaimana replikasi streaming dapat digunakan untuk mengurangi masalah yang dulunya merupakan masalah standar di versi Galera sebelumnya.
Kami akan menggunakan tiga node klaster MariaDB Galera versi 10.4.6, yang hadir dengan versi Galera 26.4.2.
MariaDB [(none)]> show global status like 'wsrep_provider%';
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| wsrep_provider_capabilities | :MULTI_MASTER:CERTIFICATION:PARALLEL_APPLYING:TRX_REPLAY:ISOLATION:PAUSE:CAUSAL_READS:INCREMENTAL_WRITESET:UNORDERED:PREORDERED:STREAMING:NBO: |
| wsrep_provider_name | Galera |
| wsrep_provider_vendor | Codership Oy <[email protected]> |
| wsrep_provider_version | 26.4.2(r4498) |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.001 sec)
Ada tiga titik nyeri utama yang harus dihadapi oleh replikasi streaming:
- Transaksi panjang
- Transaksi besar
- Titik populer di tabel
Mari kita pertimbangkan satu per satu dan lihat bagaimana replikasi streaming dapat membantu kita menanganinya, tetapi pertama-tama mari kita fokus pada sertifikasi writeset - penyebab utama munculnya masalah tersebut.
Sertifikasi Writeset di Galera Cluster
Cluster Galera terdiri dari beberapa node yang dapat ditulisi. Setiap transaksi yang dieksekusi di cluster Galera membentuk writeset. Setiap writeset harus dikirim ke semua node dalam cluster untuk sertifikasi - sebuah proses yang memastikan bahwa semua node dapat menerapkan transaksi yang diberikan. Writeset harus dieksekusi di semua node cluster sehingga jika ada konflik, transaksi tidak dapat dilakukan. Apa alasan khas mengapa transaksi tidak dapat dilakukan? Nah, tiga poin yang kami sebutkan tadi:
- Transaksi lama - semakin lama waktu transaksi, kemungkinan besar sementara itu node lain akan mengeksekusi pembaruan yang pada akhirnya akan bertentangan dengan writeset dan mencegahnya lulus sertifikasi
- Transaksi besar - pertama-tama, transaksi besar juga lebih lama dari yang kecil, sehingga memicu masalah pertama. Masalah kedua, terkait erat dengan transaksi besar, adalah volume perubahan. Lebih banyak baris akan diperbarui, kemungkinan besar bahwa beberapa penulisan di node lain akan mengakibatkan konflik dan seluruh transaksi harus dibatalkan.
- Hot spot dalam tabel - kemungkinan besar baris yang diberikan akan diperbarui, kemungkinan besar pembaruan tersebut akan terjadi secara bersamaan pada beberapa node yang mengakibatkan beberapa transaksi dibatalkan
Masalah utama di sini adalah bahwa Galera tidak memperkenalkan penguncian pada node selain node awal, di mana transaksi dibuka. Proses sertifikasi didasarkan pada harapan bahwa jika satu node dapat melakukan transaksi, yang lain juga dapat melakukannya. Memang benar, tetapi, seperti yang telah kita diskusikan, ada beberapa kasus di mana kemungkinan terjadinya hal ini berkurang secara signifikan.
Di Galera 4, dengan replikasi streaming, perilaku telah berubah dan semua kunci diambil di semua node. Transaksi akan dibagi menjadi beberapa bagian dan setiap bagian akan disertifikasi di semua node. Setelah baris sertifikasi berhasil akan dikunci pada semua node dalam cluster. Ada beberapa variabel yang mengatur bagaimana tepatnya hal ini dilakukan - wsrep_trx_fragment_size dan wsrep_trx_fragment_unit menentukan seberapa besar ukuran fragmen dan bagaimana seharusnya didefinisikan. Ini adalah kontrol yang sangat halus:Anda dapat mendefinisikan unit fragmen sebagai byte, pernyataan, atau baris yang memungkinkan untuk menjalankan sertifikasi untuk setiap baris yang dimodifikasi dalam transaksi. Mari kita lihat bagaimana Anda bisa mendapatkan keuntungan dari replikasi streaming di kehidupan nyata.
Bekerja dengan Replikasi Streaming
Mari kita pertimbangkan skenario berikut. Kami memiliki transaksi untuk dijalankan yang membutuhkan waktu setidaknya 30 detik:
BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Kemudian, saat sedang berjalan, kita akan mengeksekusi SQL yang menyentuh baris yang sama. Ini akan dieksekusi pada node lain:
BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Apa hasilnya?
Transaksi pertama dibatalkan segera setelah transaksi kedua dijalankan:
MariaDB [sbtest]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Query OK, 0 rows affected (0.001 sec)
Query OK, 667 rows affected (0.020 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (0.010 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (0.009 sec)
Rows matched: 667 Changed: 667 Warnings: 0
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Query OK, 0 rows affected (0.001 sec)
Transaksi pada node kedua berhasil:
MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)
Query OK, 7 rows affected (0.002 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 7 rows affected (0.001 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 0 rows affected (0.004 sec)
Yang bisa kita lakukan untuk menghindarinya adalah dengan menggunakan replikasi streaming untuk transaksi pertama. Kami akan meminta Galera untuk mensertifikasi setiap perubahan baris:
MariaDB [sbtest]> BEGIN; SET SESSION wsrep_trx_fragment_size=1 ; SET SESSION wsrep_trx_fragment_unit='rows' ; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT; SET SESSION wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.001 sec)
Query OK, 0 rows affected (0.000 sec)
Query OK, 0 rows affected (0.000 sec)
Query OK, 667 rows affected (1.757 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (1.708 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (1.685 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Seperti yang Anda lihat, kali ini bekerja dengan baik. Pada simpul kedua:
MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)
Query OK, 7 rows affected (33.942 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 7 rows affected (0.001 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 0 rows affected (0.026 sec)
Yang menarik, Anda dapat melihat bahwa UPDATE membutuhkan waktu hampir 34 detik untuk dieksekusi - ini disebabkan oleh fakta bahwa transaksi awal, melalui replikasi streaming, mengunci semua baris yang dimodifikasi pada semua node dan transaksi kedua kami harus menunggu yang pertama selesai meskipun kedua transaksi dijalankan pada node yang berbeda.
Ini pada dasarnya ketika datang ke replikasi streaming. Bergantung pada persyaratan dan lalu lintas, Anda dapat menggunakannya dengan cara yang tidak terlalu ketat - kami mensertifikasi setiap baris tetapi Anda dapat mengubahnya ke setiap baris ke-n atau setiap pernyataan. Anda bahkan dapat memutuskan volume data yang akan disertifikasi. Ini harus cukup untuk memenuhi persyaratan lingkungan Anda.
Ada beberapa hal lagi yang kami ingin Anda ingat dan ingat. Pertama-tama, replikasi streaming bukanlah solusi yang harus digunakan secara default. Inilah alasan mengapa, secara default, dinonaktifkan. Kasus penggunaan yang disarankan adalah memutuskan secara manual transaksi yang akan mendapat manfaat dari replikasi streaming dan mengaktifkannya di tingkat sesi. Inilah alasan mengapa contoh kami diakhiri dengan:
SET SESSION wsrep_trx_fragment_size=0;
Pernyataan ini (mengatur wsrep_trx_fragment_size ke 0) menonaktifkan replikasi streaming untuk sesi saat ini.
Hal lain yang perlu diingat - jika Anda menggunakan replikasi streaming, itu akan menggunakan tabel 'wsrep_streaming_log' dalam skema 'mysql' untuk menyimpan data streaming secara terus-menerus. Dengan menggunakan tabel ini, Anda bisa mendapatkan beberapa ide tentang data yang sedang ditransfer di seluruh cluster menggunakan replikasi streaming.
Akhirnya, kinerja. Ini juga salah satu alasan mengapa Anda tidak ingin menggunakan replikasi streaming sepanjang waktu. Alasan utama untuk itu adalah penguncian - dengan replikasi streaming Anda harus mendapatkan kunci baris di semua node. Ini membutuhkan waktu untuk mendapatkan kunci dan, jika Anda harus mengembalikan transaksi, itu juga akan memberi tekanan pada semua node untuk melakukan rollback. Kami menjalankan pengujian yang sangat cepat terhadap dampak kinerja yang dimiliki replikasi streaming. Lingkungan ini benar-benar merupakan pengujian, jadi jangan menganggap hasil tersebut sama pada perangkat keras tingkat produksi, lebih baik Anda melihat apa dampaknya.
Kami menguji empat skenario:
- Baseline, atur wsrep_trx_fragment_size=0 global;
- setel wsrep_trx_fragment_unit='baris' global; setel global wsrep_trx_fragment_size=1;
- mengatur wsrep_trx_fragment_unit='pernyataan' global; setel global wsrep_trx_fragment_size=1;
- mengatur wsrep_trx_fragment_unit='pernyataan' global; atur wsrep_trx_fragment_size=5 global;
Kami menggunakan sysbench r/w test:
sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --events=0 --time=300 --mysql-host=10.0.0.141 --mysql-user=sbtest --mysql-password=sbtest --mysql-port=3306 --tables=32 --report-interval=1 --skip-trx=off --table-size=100000 --db-ps-mode=disable run
Hasilnya adalah:
- Transaksi:82,91 per detik, kueri:1658,27 per detik. (100%)
- Transaksi:54,72 per detik, kueri:1094,43 per detik. (66%)
- Transaksi:54,76 per detik, kueri:1095,18 per detik. (66%)
- Transaksi:70,93 per detik, kueri:1.418,55 per detik. (86%)
Seperti yang Anda lihat, dampaknya signifikan, performa turun bahkan hingga 33%.
Kami harap Anda menemukan posting blog ini informatif dan memberi Anda beberapa wawasan tentang replikasi streaming yang disertakan dengan Galera 4 dan MariaDB 10.4. Kami mencoba membahas kasus penggunaan dan potensi kelemahan yang terkait dengan teknologi baru ini.