HAProxy dan ProxySQL keduanya adalah penyeimbang beban yang sangat populer di dunia MySQL, tetapi ada perbedaan yang signifikan antara kedua proxy tersebut. Kami tidak akan membahas detailnya di sini, Anda dapat membaca lebih lanjut tentang HAProxy di Tutorial HAProxy dan ProxySQL di Tutorial ProxySQL. Perbedaan yang paling penting adalah bahwa ProxySQL adalah proxy SQL-aware, mem-parsing lalu lintas dan memahami protokol MySQL dan, dengan demikian, dapat digunakan untuk pembentukan lalu lintas tingkat lanjut - Anda dapat memblokir kueri, menulis ulang, mengarahkannya ke host tertentu, cache mereka dan banyak lagi. HAProxy, di sisi lain, adalah proxy layer 4 yang sangat sederhana namun efisien dan yang dilakukannya hanyalah mengirim paket ke backend. ProxySQL dapat digunakan untuk melakukan pemisahan baca-tulis - ia memahami SQL dan dapat dikonfigurasi untuk mendeteksi apakah kueri adalah SELECT atau tidak dan merutekannya sesuai:SELECT ke semua node, kueri lain untuk dikuasai saja. Fitur ini tidak tersedia di HAProxy, yang harus menggunakan dua port terpisah dan dua backend terpisah untuk master dan slave - pemisahan baca-tulis harus dilakukan di sisi aplikasi.
Mengapa Bermigrasi ke ProxySQL?
Berdasarkan perbedaan yang kami jelaskan di atas, kami dapat mengatakan bahwa alasan utama mengapa Anda mungkin ingin beralih dari HAProxy ke ProxySQL adalah karena kurangnya pemisahan baca-tulis di HAProxy. Jika Anda menggunakan cluster database MySQL, dan tidak masalah apakah itu replikasi asinkron atau Galera Cluster, Anda mungkin ingin dapat memisahkan pembacaan dari penulisan. Untuk replikasi MySQL, jelas, ini akan menjadi satu-satunya cara untuk memanfaatkan cluster database Anda karena penulisan selalu harus dikirim ke master. Oleh karena itu jika tidak dapat melakukan split read-write, Anda hanya dapat mengirimkan query ke master saja. Bagi Galera, read-write split bukanlah hal yang harus dimiliki, tetapi jelas merupakan hal yang baik untuk dimiliki. Tentu, Anda dapat mengonfigurasi semua node Galera sebagai satu backend di HAProxy dan mengirim lalu lintas ke semuanya secara round-robin, tetapi ini dapat mengakibatkan penulisan dari beberapa node saling bertentangan, yang menyebabkan kebuntuan dan penurunan kinerja. Kami juga telah melihat masalah dan bug dalam kluster Galera, yang hingga masalah tersebut diperbaiki, solusinya adalah mengarahkan semua penulisan ke satu node. Oleh karena itu, praktik terbaik adalah mengirim semua penulisan ke satu node Galera karena ini mengarah pada perilaku yang lebih stabil dan kinerja yang lebih baik.
Alasan lain yang sangat bagus untuk migrasi ke ProxySQL adalah kebutuhan untuk memiliki kontrol yang lebih baik atas lalu lintas. Dengan HAProxy Anda tidak dapat melakukan apa pun - ia hanya mengirimkan lalu lintas ke backendnya. Dengan ProxySQL Anda dapat membentuk lalu lintas menggunakan aturan kueri (mencocokkan lalu lintas menggunakan ekspresi reguler, pengguna, skema, host sumber, dan banyak lagi). Anda dapat mengarahkan OLAP SELECT ke analytics slave (berlaku untuk replikasi dan Galera). Anda dapat menurunkan master Anda dengan mengalihkan beberapa SELECT darinya. Anda dapat menerapkan firewall SQL. Anda dapat menambahkan penundaan ke beberapa kueri, Anda dapat mematikan kueri jika membutuhkan lebih dari waktu yang ditentukan sebelumnya. Anda dapat menulis ulang kueri untuk menambahkan petunjuk pengoptimal. Semua itu tidak mungkin dilakukan dengan HAProxy.
Bagaimana Cara Bermigrasi Dari HAProxy ke ProxySQL?
Pertama, mari kita perhatikan topologi berikut...
ClusterControl MySQL Topologi Kluster Replikasi MySQL di ClusterControlKami memiliki di sini cluster replikasi yang terdiri dari master dan dua budak. Kami memiliki dua node HAProxy yang digunakan, masing-masing menggunakan dua backend - pada port 3307 untuk master (menulis) dan 3308 untuk semua node (membaca). Keepalive digunakan untuk menyediakan IP Virtual di dua instance HAProxy tersebut - jika salah satu dari mereka gagal, yang lain akan digunakan. Aplikasi kami terhubung langsung ke VIP, melaluinya ke salah satu instans HAProxy. Mari kita asumsikan aplikasi kita (kita akan menggunakan Sysbench) tidak dapat melakukan pemisahan baca-tulis oleh karena itu kita harus terhubung ke backend "penulis". Akibatnya, sebagian besar beban ada di master kita (10.0.0.101).
Apa langkah-langkah untuk bermigrasi ke ProxySQL? Mari kita pikirkan sejenak. Pertama, kita harus men-deploy dan mengkonfigurasi ProxySQL. Kita harus menambahkan server ke ProxySQL, membuat pengguna pemantauan yang diperlukan dan membuat aturan kueri yang tepat. Terakhir, kita harus men-deploy Keepalive di atas ProxySQL, membuat IP Virtual lain, lalu memastikan peralihan yang mulus untuk aplikasi kita dari HAProxy ke ProxySQL .
Mari kita lihat bagaimana kita bisa mencapainya...
Cara Memasang ProxySQL
Seseorang dapat menginstal ProxySQL dengan banyak cara. Anda dapat menggunakan repositori, baik dari ProxySQL itu sendiri (https://repo.proxysql.com) atau jika Anda menggunakan Percona XtraDB Cluster, Anda juga dapat menginstal ProxySQL dari repositori Percona meskipun mungkin memerlukan beberapa konfigurasi tambahan karena bergantung pada CLI alat admin dibuat untuk PXC. Mengingat kita berbicara tentang replikasi, menggunakannya mungkin hanya membuat segalanya lebih kompleks. Terakhir, Anda juga dapat menginstal binari ProxySQL setelah Anda mengunduhnya dari ProxySQL GitHub. Saat ini ada dua versi stabil, 1.4.x dan 2.0.x. Ada perbedaan antara ProxySQL 1.4 dan ProxySQL 2.0 dalam hal fitur, untuk blog ini kami akan tetap menggunakan cabang 1.4.x, karena lebih baik diuji dan set fitur sudah cukup bagi kami.
Kami akan menggunakan repositori ProxySQL dan kami akan menerapkan ProxySQL pada dua node tambahan:10.0.0.103 dan 10.0.0.104.
Pertama, kita akan menginstal ProxySQL menggunakan repositori resmi. Kami juga akan memastikan bahwa klien MySQL diinstal (kami akan menggunakannya untuk mengkonfigurasi ProxySQL). Harap diingat bahwa proses yang kami lalui bukanlah tingkat produksi. Untuk produksi, Anda setidaknya ingin mengubah kredensial default untuk pengguna administratif. Anda juga ingin meninjau konfigurasi dan memastikannya sesuai dengan harapan dan persyaratan Anda.
apt-get install -y lsb-release
wget -O - 'https://repo.proxysql.com/ProxySQL/repo_pub_key' | apt-key add -
echo deb https://repo.proxysql.com/ProxySQL/proxysql-1.4.x/$(lsb_release -sc)/ ./ | tee /etc/apt/sources.list.d/proxysql.list
apt-get -y update
apt-get -y install proxysql
service proxysql start
Sekarang, karena ProxySQL telah dimulai, kita akan menggunakan CLI untuk mengonfigurasi ProxySQL.
mysql -uadmin -padmin -P6032 -h127.0.0.1
Pertama, kita akan mendefinisikan server backend dan grup host replikasi:
mysql> INSERT INTO mysql_servers (hostgroup_id, hostname) VALUES (10, '10.0.0.101'), (20, '10.0.0.102'), (20, '10.0.0.103');
Query OK, 3 rows affected (0.91 sec)
mysql> INSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup) VALUES (10, 20);
Query OK, 1 row affected (0.00 sec)
Kami memiliki tiga server, kami juga mendefinisikan bahwa ProxySQL harus menggunakan hostgroup 10 untuk master (node dengan read_only=0) dan hostgroup 20 untuk slave (read_only=1).
Sebagai langkah selanjutnya, kita perlu menambahkan pengguna pemantau pada node MySQL sehingga ProxySQL dapat memantaunya. Kami akan menggunakan default, idealnya Anda akan mengubah kredensial di ProxySQL.
mysql> SHOW VARIABLES LIKE 'mysql-monitor_username';
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| mysql-monitor_username | monitor |
+------------------------+---------+
1 row in set (0.00 sec)
mysql> SHOW VARIABLES LIKE 'mysql-monitor_password';
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| mysql-monitor_password | monitor |
+------------------------+---------+
1 row in set (0.00 sec)
Jadi, kita perlu membuat 'monitor' pengguna dengan kata sandi 'monitor'. Untuk melakukan itu, kita perlu menjalankan grant berikut di server master MySQL:
mysql> create user [email protected]'%' identified by 'monitor';
Query OK, 0 rows affected (0.56 sec)
Kembali ke ProxySQL - kita harus mengonfigurasi pengguna yang akan digunakan aplikasi kita untuk mengakses MySQL dan aturan kueri, yang dimaksudkan untuk memberi kita pemisahan baca-tulis.
mysql> INSERT INTO mysql_users (username, password, default_hostgroup) VALUES ('sbtest', 'sbtest', 10);
Query OK, 1 row affected (0.34 sec)
mysql> INSERT INTO mysql_query_rules (rule_id,active,match_digest,destination_hostgroup,apply) VALUES (100, 1, '^SELECT.*FOR UPDATE$',10,1), (200,1,'^SELECT',20,1), (300,1,'.*',10,1);
Query OK, 3 rows affected (0.01 sec)
Harap dicatat bahwa kami menggunakan kata sandi dalam teks biasa dan kami akan mengandalkan ProxySQL untuk melakukan hash. Demi keamanan, Anda harus secara eksplisit memberikan hash kata sandi MySQL di sini.
Terakhir, kita perlu menerapkan semua perubahan.
mysql> LOAD MYSQL SERVERS TO RUNTIME;
Query OK, 0 rows affected (0.02 sec)
mysql> LOAD MYSQL USERS TO RUNTIME;
Query OK, 0 rows affected (0.01 sec)
mysql> LOAD MYSQL QUERY RULES TO RUNTIME;
Query OK, 0 rows affected (0.01 sec)
mysql> SAVE MYSQL SERVERS TO DISK;
Query OK, 0 rows affected (0.07 sec)
mysql> SAVE MYSQL QUERY RULES TO DISK;
Query OK, 0 rows affected (0.02 sec)
Kami juga ingin memuat kata sandi hash dari runtime:kata sandi teks biasa di-hash ketika dimuat ke dalam konfigurasi runtime, untuk menyimpannya di disk kita perlu memuatnya dari runtime dan kemudian menyimpannya di disk:
mysql> SAVE MYSQL USERS FROM RUNTIME;
Query OK, 0 rows affected (0.00 sec)
mysql> SAVE MYSQL USERS TO DISK;
Query OK, 0 rows affected (0.02 sec)
Ini dia ketika datang ke ProxySQL. Sebelum melakukan langkah lebih lanjut, Anda harus memeriksa apakah Anda dapat terhubung ke proxy dari server aplikasi Anda.
[email protected]:~# mysql -h 10.0.0.103 -usbtest -psbtest -P6033 -e "SELECT * FROM sbtest.sbtest4 LIMIT 1\G"
mysql: [Warning] Using a password on the command line interface can be insecure.
*************************** 1. row ***************************
id: 1
k: 50147
c: 68487932199-96439406143-93774651418-41631865787-96406072701-20604855487-25459966574-28203206787-41238978918-19503783441
pad: 22195207048-70116052123-74140395089-76317954521-98694025897
Dalam kasus kami, semuanya terlihat bagus. Sekarang saatnya menginstal Keepalive.
Instalasi tetap berjalan
Instalasi cukup sederhana (setidaknya di Ubuntu 16.04, yang kami gunakan):
apt install keepalived
Kemudian Anda harus membuat file konfigurasi untuk kedua server:
Node master yang tetap hidup:
vrrp_script chk_haproxy {
script "killall -0 haproxy" # verify the pid existance
interval 2 # check every 2 seconds
weight 2 # add 2 points of prio if OK
}
vrrp_instance VI_HAPROXY {
interface eth1 # interface to monitor
state MASTER
virtual_router_id 52 # Assign one ID for this route
priority 101
unicast_src_ip 10.0.0.103
unicast_peer {
10.0.0.104
}
virtual_ipaddress {
10.0.0.112 # the virtual IP
}
track_script {
chk_haproxy
}
# notify /usr/local/bin/notify_keepalived.sh
}
Cadangan simpul yang disimpan:
vrrp_script chk_haproxy {
script "killall -0 haproxy" # verify the pid existance
interval 2 # check every 2 seconds
weight 2 # add 2 points of prio if OK
}
vrrp_instance VI_HAPROXY {
interface eth1 # interface to monitor
state MASTER
virtual_router_id 52 # Assign one ID for this route
priority 100
unicast_src_ip 10.0.0.103
unicast_peer {
10.0.0.104
}
virtual_ipaddress {
10.0.0.112 # the virtual IP
}
track_script {
chk_haproxy
}
# notify /usr/local/bin/notify_keepalived.sh
Ini dia, Anda dapat mulai tetap hidup di kedua node:
service keepalived start
Anda akan melihat informasi di log bahwa salah satu node memasuki status MASTER dan VIP telah dibawa ke node tersebut.
May 7 09:52:11 vagrant systemd[1]: Starting Keepalive Daemon (LVS and VRRP)...
May 7 09:52:11 vagrant Keepalived[26686]: Starting Keepalived v1.2.24 (08/06,2018)
May 7 09:52:11 vagrant Keepalived[26686]: Opening file '/etc/keepalived/keepalived.conf'.
May 7 09:52:11 vagrant Keepalived[26696]: Starting Healthcheck child process, pid=26697
May 7 09:52:11 vagrant Keepalived[26696]: Starting VRRP child process, pid=26698
May 7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Initializing ipvs
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: Registering Kernel netlink reflector
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: Registering Kernel netlink command channel
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: Registering gratuitous ARP shared channel
May 7 09:52:11 vagrant systemd[1]: Started Keepalive Daemon (LVS and VRRP).
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: Unable to load ipset library
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: Unable to initialise ipsets
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: Opening file '/etc/keepalived/keepalived.conf'.
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: Using LinkWatch kernel netlink reflector...
May 7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Registering Kernel netlink reflector
May 7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Registering Kernel netlink command channel
May 7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Opening file '/etc/keepalived/keepalived.conf'.
May 7 09:52:11 vagrant Keepalived_healthcheckers[26697]: Using LinkWatch kernel netlink reflector...
May 7 09:52:11 vagrant Keepalived_vrrp[26698]: pid 26701 exited with status 256
May 7 09:52:12 vagrant Keepalived_vrrp[26698]: VRRP_Instance(VI_HAPROXY) Transition to MASTER STATE
May 7 09:52:13 vagrant Keepalived_vrrp[26698]: pid 26763 exited with status 256
May 7 09:52:13 vagrant Keepalived_vrrp[26698]: VRRP_Instance(VI_HAPROXY) Entering MASTER STATE
May 7 09:52:15 vagrant Keepalived_vrrp[26698]: pid 26806 exited with status 256
[email protected]:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:ee:87:c4 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:feee:87c4/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:fc:ac:21 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.103/24 brd 10.0.0.255 scope global eth1
valid_lft forever preferred_lft forever
inet 10.0.0.112/32 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fefc:ac21/64 scope link
valid_lft forever preferred_lft forever
Seperti yang Anda lihat, pada node 10.0.0.103 VIP (10.0.0.112) telah dinaikkan. Sekarang kita dapat menyimpulkan dengan memindahkan lalu lintas dari penyiapan lama ke penyiapan baru.
Mengalihkan Lalu Lintas ke Pengaturan ProxySQL
Ada banyak metode tentang cara melakukannya, sebagian besar tergantung pada lingkungan khusus Anda. Jika Anda menggunakan DNS untuk mempertahankan domain yang menunjuk ke HAProxy VIP Anda, , Anda dapat membuat perubahan di sana dan, secara bertahap, seiring waktu, semua koneksi akan mengarah kembali ke VIP baru. Anda juga dapat membuat perubahan di aplikasi Anda, terutama jika detail koneksi di-hardcode - setelah Anda meluncurkan perubahan, node akan mulai terhubung ke pengaturan baru. Tidak peduli bagaimana Anda melakukannya, akan sangat bagus untuk menguji pengaturan baru sebelum Anda melakukan peralihan global. Anda benar-benar mengujinya di lingkungan pementasan Anda, tetapi bukan ide yang buruk untuk memilih beberapa server aplikasi dan mengarahkannya ke proxy baru, memantau tampilannya dari segi kinerja. Di bawah ini adalah contoh sederhana menggunakan iptables, yang dapat berguna untuk pengujian.
Pada host ProxySQL, alihkan lalu lintas dari host 10.0.0.11 dan port 3307 ke host 10.0.0.112 dan port 6033:
iptables -t nat -A OUTPUT -p tcp -d 10.0.0.111 --dport 3307 -j DNAT --to-destination 10.0.0.112:6033
Bergantung pada aplikasi Anda, Anda mungkin perlu memulai ulang server web atau layanan lain (jika aplikasi Anda membuat kumpulan koneksi konstan ke database) atau tunggu saja saat koneksi baru akan dibuka terhadap ProxySQL. Anda dapat memverifikasi bahwa ProxySQL menerima lalu lintas:
mysql> show processlist;
+-----------+--------+--------+-----------+---------+---------+-----------------------------------------------------------------------------+
| SessionID | user | db | hostgroup | command | time_ms | info |
+-----------+--------+--------+-----------+---------+---------+-----------------------------------------------------------------------------+
| 12 | sbtest | sbtest | 20 | Sleep | 0 | |
| 13 | sbtest | sbtest | 10 | Query | 0 | DELETE FROM sbtest23 WHERE id=49957 |
| 14 | sbtest | sbtest | 10 | Query | 59 | DELETE FROM sbtest11 WHERE id=50185 |
| 15 | sbtest | sbtest | 20 | Query | 59 | SELECT c FROM sbtest8 WHERE id=46054 |
| 16 | sbtest | sbtest | 20 | Query | 0 | SELECT DISTINCT c FROM sbtest27 WHERE id BETWEEN 50115 AND 50214 ORDER BY c |
| 17 | sbtest | sbtest | 10 | Query | 0 | DELETE FROM sbtest32 WHERE id=50084 |
| 18 | sbtest | sbtest | 10 | Query | 26 | DELETE FROM sbtest28 WHERE id=34611 |
| 19 | sbtest | sbtest | 10 | Query | 16 | DELETE FROM sbtest4 WHERE id=50151 |
+-----------+--------+--------+-----------+---------+---------+-----------------------------------------------------------------------------+
Itu saja, kami telah memindahkan lalu lintas dari HAProxy ke pengaturan ProxySQL. Butuh beberapa langkah, tetapi pasti bisa dilakukan dengan gangguan yang sangat kecil pada layanan.
Bagaimana Cara Migrasi Dari HAProxy ke ProxySQL Menggunakan ClusterControl?
Di bagian sebelumnya kami menjelaskan cara menerapkan pengaturan ProxySQL secara manual dan kemudian bermigrasi ke dalamnya. Di bagian ini kami ingin menjelaskan bagaimana mencapai tujuan yang sama menggunakan ClusterControl. Penyiapan awal persis sama oleh karena itu kita perlu melanjutkan penerapan ProxySQL.
Menyebarkan ProxySQL Menggunakan ClusterControl
Penerapan ProxySQL di ClusterControl hanya dengan beberapa klik.
Menyebarkan ProxySQL di ClusterControlKami harus memilih IP atau nama host node, memberikan kredensial untuk pengguna administratif CLI dan pengguna pemantauan MySQL. Kami memutuskan untuk menggunakan MySQL yang ada dan kami memberikan detail akses untuk pengguna 'sbtest'@'%' yang kami gunakan dalam aplikasi. Kami memilih node mana yang ingin kami gunakan di penyeimbang beban, kami juga meningkatkan jeda replikasi maksimum (jika ambang batas itu dilewati, ProxySQL tidak akan mengirim lalu lintas ke budak itu) dari default 10 detik menjadi 100 karena kami sudah menderita replikasi ketinggalan. Setelah beberapa saat, node ProxySQL akan ditambahkan ke cluster.
Menyebarkan Keepalive untuk ProxySQL Menggunakan ClusterControl
Ketika node ProxySQL telah ditambahkan, saatnya untuk menerapkan Keepalive.
Dipertahankan dengan ProxySQL di ClusterControlYang harus kami lakukan adalah memilih node ProxySQL mana yang kami ingin Keepalive gunakan, IP virtual, dan antarmuka yang akan diikat VIP. Saat penerapan selesai, kami akan mengalihkan lalu lintas ke penyiapan baru menggunakan salah satu metode yang disebutkan di bagian “Mengalihkan lalu lintas ke penyiapan ProxySQL” di atas.
Memantau Lalu Lintas ProxySQL di ClusterControlKami dapat memverifikasi bahwa lalu lintas telah beralih ke ProxySQL dengan melihat grafik beban - seperti yang Anda lihat, beban jauh lebih didistribusikan di seluruh node dalam cluster. Anda juga dapat melihatnya pada grafik di bawah ini, yang menunjukkan distribusi kueri di seluruh cluster.
Dasbor ProxySQL di ClusterControlTerakhir, dasbor ProxySQL juga menunjukkan bahwa lalu lintas didistribusikan ke semua node dalam cluster:
Dasbor ProxySQL di ClusterControlKami harap Anda akan mendapat manfaat dari posting blog ini, seperti yang Anda lihat, dengan ClusterControl menerapkan arsitektur baru hanya membutuhkan beberapa saat dan hanya membutuhkan beberapa klik untuk menjalankannya. Beri tahu kami tentang pengalaman Anda dalam migrasi semacam itu.