ProxySQL adalah proxy SQL yang cerdas dan berkinerja tinggi yang mendukung MySQL, MariaDB, dan ClickHouse. Baru-baru ini, ProxySQL 2.0 telah menjadi GA dan hadir dengan fitur-fitur baru yang menarik seperti pembacaan konsisten GTID, SSL frontend, Galera, dan dukungan asli Replikasi Grup MySQL.
Relatif mudah untuk menjalankan ProxySQL sebagai wadah Docker. Kami sebelumnya telah menulis tentang cara menjalankan ProxySQL di Kubernetes sebagai wadah pembantu atau sebagai layanan Kubernetes, yang didasarkan pada ProxySQL 1.x. Dalam posting blog ini, kita akan menggunakan versi baru ProxySQL 2.x yang menggunakan pendekatan berbeda untuk konfigurasi Galera Cluster.
ProxySQL 2.x Gambar Docker
Kami telah merilis container image Docker ProxySQL 2.0 baru dan tersedia di Docker Hub. README menyediakan sejumlah contoh konfigurasi khususnya untuk Galera dan Replikasi MySQL, sebelum dan sesudah v2.x. Baris konfigurasi dapat didefinisikan dalam file teks dan dipetakan ke jalur container di /etc/proxysql.cnf untuk dimuat ke layanan ProxySQL.
Tag "terbaru" gambar masih menunjuk ke 1.x hingga ProxySQL 2.0 resmi menjadi GA (kami belum melihat blog/artikel rilis resmi dari tim ProxySQL). Artinya, setiap kali Anda menginstal gambar ProxySQL menggunakan tag terbaru dari Somenines, Anda masih akan mendapatkan versi 1.x dengannya. Perhatikan contoh konfigurasi baru yang juga mengaktifkan statistik web ProxySQL (diperkenalkan pada 1.4.4 tetapi masih dalam versi beta) - dasbor sederhana yang merangkum keseluruhan konfigurasi dan status ProxySQL itu sendiri.
Dukungan ProxySQL 2.x untuk Galera Cluster
Mari kita bicara tentang dukungan asli Galera Cluster secara lebih rinci. Tabel mysql_galera_hostgroups baru terdiri dari bidang berikut:
- writer_hostgroup : ID hostgroup yang akan berisi semua anggota yang merupakan penulis (read_only=0).
- backup_writer_hostgroup : Jika cluster berjalan dalam mode multi-penulis (yaitu ada beberapa node dengan read_only=0) dan max_writers diatur ke jumlah yang lebih kecil dari jumlah total node, node tambahan dipindahkan ke hostgroup penulis cadangan ini.
- reader_hostgroup : ID hostgroup yang akan berisi semua anggota yang merupakan pembaca (yaitu node yang memiliki read_only=1)
- offline_hostgroup : Saat pemantauan ProxySQL menentukan host menjadi OFFLINE, host akan dipindahkan ke offline_hostgroup.
- aktif : nilai boolean (0 atau 1) untuk mengaktifkan grup host
- max_writers : Mengontrol jumlah maksimum node yang diizinkan di grup host penulis, seperti yang disebutkan sebelumnya, node tambahan akan dipindahkan ke grup backup_writer_host.
- penulis_is_juga_pembaca : Ketika 1, sebuah node di writer_hostgroup juga akan ditempatkan di reader_hostgroup sehingga akan digunakan untuk membaca. Jika disetel ke 2, node dari backup_writer_hostgroup akan ditempatkan di reader_hostgroup, bukan node di writer_hostgroup.
- max_transactions_behind : menentukan jumlah maksimum set tulis yang dapat diantrekan oleh node dalam cluster sebelum node DIHENTIKAN untuk mencegah pembacaan yang basi (ini ditentukan dengan menanyakan variabel wsrep_local_recv_queue Galera).
- komentar : Bidang teks yang dapat digunakan untuk tujuan apa pun yang ditentukan oleh pengguna
Berikut adalah contoh konfigurasi untuk mysql_galera_hostgroups dalam format tabel:
Admin> select * from mysql_galera_hostgroups\G
*************************** 1. row ***************************
writer_hostgroup: 10
backup_writer_hostgroup: 20
reader_hostgroup: 30
offline_hostgroup: 9999
active: 1
max_writers: 1
writer_is_also_reader: 2
max_transactions_behind: 20
comment:
ProxySQL melakukan pemeriksaan kesehatan Galera dengan memantau status/variabel MySQL berikut:
- hanya baca - Jika ON, maka ProxySQL akan mengelompokkan host yang ditentukan ke dalam reader_hostgroup kecuali jika writer_is_also_reader adalah 1.
- wsrep_desync - Jika AKTIF, ProxySQL akan menandai node sebagai tidak tersedia, memindahkannya ke offline_hostgroup.
- wsrep_reject_queries - Jika variabel ini AKTIF, ProxySQL akan menandai node sebagai tidak tersedia, memindahkannya ke offline_hostgroup (berguna dalam situasi pemeliharaan tertentu).
- wsrep_sst_donor_rejects_queries - Jika variabel ini AKTIF, ProxySQL akan menandai node sebagai tidak tersedia saat node Galera berfungsi sebagai donor SST, memindahkannya ke offline_hostgroup.
- wsrep_local_state - Jika status ini mengembalikan selain 4 (4 berarti Disinkronkan), ProxySQL akan menandai node sebagai tidak tersedia dan memindahkannya ke offline_hostgroup.
- wsrep_local_recv_queue - Jika status ini lebih tinggi dari max_transactions_behind, node akan dijauhi.
- wsrep_cluster_status - Jika status ini mengembalikan selain Primer, ProxySQL akan menandai node sebagai tidak tersedia dan memindahkannya ke offline_hostgroup.
Karena itu, dengan menggabungkan parameter baru ini di mysql_galera_hostgroups bersama dengan mysql_query_rules, ProxySQL 2.x memiliki fleksibilitas untuk menyesuaikan dengan lebih banyak kasus penggunaan Galera. Misalnya, seseorang dapat memiliki grup host penulis tunggal, multi-penulis, dan multi-pembaca yang didefinisikan sebagai grup host tujuan dari aturan kueri, dengan kemampuan untuk membatasi jumlah penulis dan kontrol yang lebih baik pada perilaku pembacaan yang basi.
Bandingkan ini dengan ProxySQL 1.x, di mana pengguna harus secara eksplisit menentukan penjadwal untuk memanggil skrip eksternal untuk melakukan pemeriksaan kesehatan backend dan memperbarui status server database. Ini memerlukan beberapa penyesuaian pada skrip (pengguna harus memperbarui pengguna/kata sandi/porta admin ProxySQL) ditambah itu bergantung pada alat tambahan (klien MySQL) untuk terhubung ke antarmuka admin ProxySQL.
Berikut adalah contoh konfigurasi penjadwal skrip health check Galera dalam format tabel untuk ProxySQL 1.x:
Admin> select * from scheduler\G
*************************** 1. row ***************************
id: 1
active: 1
interval_ms: 2000
filename: /usr/share/proxysql/tools/proxysql_galera_checker.sh
arg1: 10
arg2: 20
arg3: 1
arg4: 1
arg5: /var/lib/proxysql/proxysql_galera_checker.log
comment:
Selain itu, karena utas penjadwal ProxySQL mengeksekusi skrip apa pun secara independen, ada banyak versi skrip pemeriksaan kesehatan yang tersedia di luar sana. Semua instans ProxySQL yang disebarkan oleh ClusterControl menggunakan skrip default yang disediakan oleh paket penginstal ProxySQL.
Di ProxySQL 2.x, variabel max_writers dan writer_is_also_reader dapat menentukan bagaimana ProxySQL mengelompokkan server MySQL backend secara dinamis dan akan secara langsung memengaruhi distribusi koneksi dan perutean kueri. Misalnya, pertimbangkan server backend MySQL berikut:
Admin> select hostgroup_id, hostname, status, weight from mysql_servers;
+--------------+--------------+--------+--------+
| hostgroup_id | hostname | status | weight |
+--------------+--------------+--------+--------+
| 10 | DB1 | ONLINE | 1 |
| 10 | DB2 | ONLINE | 1 |
| 10 | DB3 | ONLINE | 1 |
+--------------+--------------+--------+--------+
Bersama dengan definisi grup host Galera berikut:
Admin> select * from mysql_galera_hostgroups\G
*************************** 1. row ***************************
writer_hostgroup: 10
backup_writer_hostgroup: 20
reader_hostgroup: 30
offline_hostgroup: 9999
active: 1
max_writers: 1
writer_is_also_reader: 2
max_transactions_behind: 20
comment:
Mengingat semua host aktif dan berjalan, ProxySQL kemungkinan besar akan mengelompokkan host seperti di bawah ini:
Mari kita lihat satu per satu:
Konfigurasi | Deskripsi |
---|---|
writer_is_also_reader=0 |
|
writer_is_also_reader=1 |
|
writer_is_also_reader=2 |
|
Dengan konfigurasi ini, seseorang dapat memiliki berbagai pilihan tujuan grup host untuk memenuhi beban kerja tertentu. Penulisan "Hotspot" dapat dikonfigurasi untuk pergi ke hanya satu server untuk mengurangi konflik multi-master, penulisan yang tidak bertentangan dapat didistribusikan secara merata pada master lain, sebagian besar pembacaan dapat didistribusikan secara merata di semua server MySQL atau non-penulis, pembacaan kritis dapat diteruskan ke server terbaru dan pembacaan analitis dapat diteruskan ke replika slave.
Penerapan ProxySQL untuk Galera Cluster
Dalam contoh ini, misalkan kita sudah memiliki Cluster Galera tiga node yang di-deploy oleh ClusterControl seperti yang ditunjukkan pada diagram berikut:
Aplikasi Wordpress kami berjalan di Docker sementara database Wordpress dihosting di Galera Cluster kami yang berjalan di server bare-metal. Kami memutuskan untuk menjalankan wadah ProxySQL bersama wadah Wordpress kami untuk memiliki kontrol yang lebih baik pada perutean kueri basis data Wordpress dan sepenuhnya memanfaatkan infrastruktur klaster basis data kami. Karena rasio baca-tulis sekitar 80%-20%, kami ingin mengonfigurasi ProxySQL ke:
- Teruskan semua penulisan ke satu simpul Galera (kurangi konflik, fokus pada penulisan)
- Seimbangkan semua pembacaan ke dua node Galera lainnya (distribusi yang lebih baik untuk sebagian besar beban kerja)
Pertama, buat file konfigurasi ProxySQL di dalam host Docker sehingga kami dapat memetakannya ke dalam wadah kami:
$ mkdir /root/proxysql-docker
$ vim /root/proxysql-docker/proxysql.cnf
Kemudian, salin baris berikut (kami akan menjelaskan baris konfigurasi lebih jauh ke bawah):
datadir="/var/lib/proxysql"
admin_variables=
{
admin_credentials="admin:admin"
mysql_ifaces="0.0.0.0:6032"
refresh_interval=2000
web_enabled=true
web_port=6080
stats_credentials="stats:admin"
}
mysql_variables=
{
threads=4
max_connections=2048
default_query_delay=0
default_query_timeout=36000000
have_compress=true
poll_timeout=2000
interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
default_schema="information_schema"
stacksize=1048576
server_version="5.1.30"
connect_timeout_server=10000
monitor_history=60000
monitor_connect_interval=200000
monitor_ping_interval=200000
ping_interval_server_msec=10000
ping_timeout_server=200
commands_stats=true
sessions_sort=true
monitor_username="proxysql"
monitor_password="proxysqlpassword"
monitor_galera_healthcheck_interval=2000
monitor_galera_healthcheck_timeout=800
}
mysql_galera_hostgroups =
(
{
writer_hostgroup=10
backup_writer_hostgroup=20
reader_hostgroup=30
offline_hostgroup=9999
max_writers=1
writer_is_also_reader=1
max_transactions_behind=30
active=1
}
)
mysql_servers =
(
{ address="db1.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="db2.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="db3.cluster.local" , port=3306 , hostgroup=10, max_connections=100 }
)
mysql_query_rules =
(
{
rule_id=100
active=1
match_pattern="^SELECT .* FOR UPDATE"
destination_hostgroup=10
apply=1
},
{
rule_id=200
active=1
match_pattern="^SELECT .*"
destination_hostgroup=30
apply=1
},
{
rule_id=300
active=1
match_pattern=".*"
destination_hostgroup=10
apply=1
}
)
mysql_users =
(
{ username = "wordpress", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 },
{ username = "sbtest", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 }
)
Sekarang, mari kita kunjungi beberapa bagian konfigurasi paling banyak. Pertama, kita mendefinisikan konfigurasi hostgroup Galera seperti di bawah ini:
mysql_galera_hostgroups =
(
{
writer_hostgroup=10
backup_writer_hostgroup=20
reader_hostgroup=30
offline_hostgroup=9999
max_writers=1
writer_is_also_reader=1
max_transactions_behind=30
active=1
}
)
Hostgroup 10 akan menjadi writer_hostgroup, hostgroup 20 untuk backup_writer dan hostgroup 30 untuk pembaca. Kami menetapkan max_writers ke 1 sehingga kami dapat memiliki grup host penulis tunggal untuk grup host 10 tempat semua penulisan harus dikirim. Kemudian, kita mendefinisikan writer_is_also_reader menjadi 1 yang akan menjadikan semua node Galera sebagai reader juga, cocok untuk query yang dapat didistribusikan secara merata ke semua node. Hostgroup 9999 dicadangkan untuk offline_hostgroup jika ProxySQL mendeteksi node Galera yang tidak beroperasi.
Kemudian, kami mengkonfigurasi server MySQL kami dengan default ke hostgroup 10:
mysql_servers =
(
{ address="db1.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="db2.cluster.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="db3.cluster.local" , port=3306 , hostgroup=10, max_connections=100 }
)
Dengan konfigurasi di atas, ProxySQL akan "melihat" hostgroup kami seperti di bawah ini:
Kemudian, kami mendefinisikan perutean kueri melalui aturan kueri. Berdasarkan persyaratan kami, semua bacaan harus dikirim ke semua node Galera kecuali penulis (hostgroup 20) dan yang lainnya diteruskan ke hostgroup 10 untuk penulis tunggal:
mysql_query_rules =
(
{
rule_id=100
active=1
match_pattern="^SELECT .* FOR UPDATE"
destination_hostgroup=10
apply=1
},
{
rule_id=200
active=1
match_pattern="^SELECT .*"
destination_hostgroup=20
apply=1
},
{
rule_id=300
active=1
match_pattern=".*"
destination_hostgroup=10
apply=1
}
)
Terakhir, kami mendefinisikan pengguna MySQL yang akan melewati ProxySQL:
mysql_users =
(
{ username = "wordpress", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 },
{ username = "sbtest", password = "passw0rd", default_hostgroup = 10, transaction_persistent = 0, active = 1 }
)
Kami menyetel transaction_persistent ke 0 sehingga semua koneksi yang berasal dari pengguna ini akan menghormati aturan kueri untuk perutean baca dan tulis. Jika tidak, koneksi akan berakhir mengenai satu grup host yang mengalahkan tujuan penyeimbangan beban. Jangan lupa untuk membuat pengguna tersebut terlebih dahulu di semua server MySQL. Untuk pengguna ClusterControl, Anda dapat menggunakan fitur Kelola -> Skema dan Pengguna untuk membuat pengguna tersebut.
Kami sekarang siap untuk memulai wadah kami. Kita akan memetakan file konfigurasi ProxySQL sebagai bind mount saat memulai wadah ProxySQL. Dengan demikian, perintah run akan menjadi:
$ docker run -d \
--name proxysql2 \
--hostname proxysql2 \
--publish 6033:6033 \
--publish 6032:6032 \
--publish 6080:6080 \
--restart=unless-stopped \
-v /root/proxysql/proxysql.cnf:/etc/proxysql.cnf \
severalnines/proxysql:2.0
Terakhir, ubah database Wordpress yang mengarah ke ProxySQL container port 6033, misalnya:
$ docker run -d \
--name wordpress \
--publish 80:80 \
--restart=unless-stopped \
-e WORDPRESS_DB_HOST=proxysql2:6033 \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_HOST=passw0rd \
wordpress
Pada titik ini, arsitektur kita terlihat seperti ini:
Jika Anda ingin wadah ProxySQL menjadi persisten, petakan /var/lib/proxysql/ ke volume Docker atau ikat mount, misalnya:
$ docker run -d \
--name proxysql2 \
--hostname proxysql2 \
--publish 6033:6033 \
--publish 6032:6032 \
--publish 6080:6080 \
--restart=unless-stopped \
-v /root/proxysql/proxysql.cnf:/etc/proxysql.cnf \
-v proxysql-volume:/var/lib/proxysql \
severalnines/proxysql:2.0
Ingatlah bahwa menjalankan dengan penyimpanan persisten seperti di atas akan membuat /root/proxysql/proxysql.cnf kita menjadi usang pada restart kedua. Ini karena konfigurasi multi-layer ProxySQL di mana jika /var/lib/proxysql/proxysql.db ada, ProxySQL akan melewatkan opsi pemuatan dari file konfigurasi dan memuat apa pun yang ada di database SQLite sebagai gantinya (kecuali jika Anda memulai layanan proxysql dengan --initial bendera). Karena itu, manajemen konfigurasi ProxySQL berikutnya harus dilakukan melalui konsol admin ProxySQL pada port 6032, daripada menggunakan file konfigurasi.
Pemantauan
Log proses ProxySQL secara default masuk ke syslog dan Anda dapat melihatnya dengan menggunakan perintah buruh pelabuhan standar:
$ docker ps
$ docker logs proxysql2
Untuk memverifikasi grup host saat ini, kueri tabel runtime_mysql_servers:
$ docker exec -it proxysql2 mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt='Admin> '
Admin> select hostgroup_id,hostname,status from runtime_mysql_servers;
+--------------+--------------+--------+
| hostgroup_id | hostname | status |
+--------------+--------------+--------+
| 10 | 192.168.0.21 | ONLINE |
| 30 | 192.168.0.21 | ONLINE |
| 30 | 192.168.0.22 | ONLINE |
| 30 | 192.168.0.23 | ONLINE |
| 20 | 192.168.0.22 | ONLINE |
| 20 | 192.168.0.23 | ONLINE |
+--------------+--------------+--------+
Jika penulis yang dipilih turun, itu akan ditransfer ke offline_hostgroup (HID 9999):
Admin> select hostgroup_id,hostname,status from runtime_mysql_servers;
+--------------+--------------+--------+
| hostgroup_id | hostname | status |
+--------------+--------------+--------+
| 10 | 192.168.0.22 | ONLINE |
| 9999 | 192.168.0.21 | ONLINE |
| 30 | 192.168.0.22 | ONLINE |
| 30 | 192.168.0.23 | ONLINE |
| 20 | 192.168.0.23 | ONLINE |
+--------------+--------------+--------+
Perubahan topologi di atas dapat digambarkan dalam diagram berikut:
Kami juga telah mengaktifkan UI statistik web dengan admin-web_enabled=true. Untuk mengakses UI web, cukup buka host Docker di port 6080, misalnya:http://192.168.0.200:8060 dan Anda akan diminta dengan nama pengguna/kata sandi muncul. Masukkan kredensial seperti yang didefinisikan di bawah admin-stats_credentials dan Anda akan melihat halaman berikut:
Dengan memonitor tabel pool koneksi MySQL, kita bisa mendapatkan gambaran distribusi koneksi untuk semua hostgroup:
Admin> select hostgroup, srv_host, status, ConnUsed, MaxConnUsed, Queries from stats.stats_mysql_connection_pool order by srv_host;
+-----------+--------------+--------+----------+-------------+---------+
| hostgroup | srv_host | status | ConnUsed | MaxConnUsed | Queries |
+-----------+--------------+--------+----------+-------------+---------+
| 20 | 192.168.0.23 | ONLINE | 5 | 24 | 11458 |
| 30 | 192.168.0.23 | ONLINE | 0 | 0 | 0 |
| 20 | 192.168.0.22 | ONLINE | 2 | 24 | 11485 |
| 30 | 192.168.0.22 | ONLINE | 0 | 0 | 0 |
| 10 | 192.168.0.21 | ONLINE | 32 | 32 | 9746 |
| 30 | 192.168.0.21 | ONLINE | 0 | 0 | 0 |
+-----------+--------------+--------+----------+-------------+---------+
Output di atas menunjukkan bahwa hostgroup 30 tidak memproses apa pun karena aturan kueri kami tidak mengonfigurasi grup host ini sebagai grup host tujuan.
Statistik yang terkait dengan node Galera dapat dilihat di tabel mysql_server_galera_log:
Admin> select * from mysql_server_galera_log order by time_start_us desc limit 3\G
*************************** 1. row ***************************
hostname: 192.168.0.23
port: 3306
time_start_us: 1552992553332489
success_time_us: 2045
primary_partition: YES
read_only: NO
wsrep_local_recv_queue: 0
wsrep_local_state: 4
wsrep_desync: NO
wsrep_reject_queries: NO
wsrep_sst_donor_rejects_queries: NO
error: NULL
*************************** 2. row ***************************
hostname: 192.168.0.22
port: 3306
time_start_us: 1552992553329653
success_time_us: 2799
primary_partition: YES
read_only: NO
wsrep_local_recv_queue: 0
wsrep_local_state: 4
wsrep_desync: NO
wsrep_reject_queries: NO
wsrep_sst_donor_rejects_queries: NO
error: NULL
*************************** 3. row ***************************
hostname: 192.168.0.21
port: 3306
time_start_us: 1552992553329013
success_time_us: 2715
primary_partition: YES
read_only: NO
wsrep_local_recv_queue: 0
wsrep_local_state: 4
wsrep_desync: NO
wsrep_reject_queries: NO
wsrep_sst_donor_rejects_queries: NO
error: NULL
Kumpulan hasil mengembalikan status variabel/status MySQL terkait untuk setiap simpul Galera untuk stempel waktu tertentu. Dalam konfigurasi ini, kami mengonfigurasi pemeriksaan kesehatan Galera untuk dijalankan setiap 2 detik (monitor_galera_healthcheck_interval=2000). Oleh karena itu, waktu failover maksimum adalah sekitar 2 detik jika terjadi perubahan topologi pada cluster.
Referensi
- Dukungan Galera Asli ProxySQL
- HA dan solusi pengelompokan:ProxySQL sebagai router cerdas untuk Galera dan Replikasi Grup
- Gambar ProxySQL Docker oleh Somenines
- Cara Memantau ProxySQL dengan Prometheus dan ClusterControl