sql >> Databáze >  >> RDS >> Mysql

Database-Aware Load Balancing:Jak migrovat z HAProxy na ProxySQL

HAProxy a ProxySQL jsou oba velmi oblíbené nástroje pro vyrovnávání zátěže ve světě MySQL, ale mezi oběma těmito proxy je významný rozdíl. Nebudeme zde zabíhat do podrobností, více o HAProxy si můžete přečíst v HAProxy Tutorial a ProxySQL v ProxySQL Tutorial. Nejdůležitější rozdíl je v tom, že ProxySQL je SQL-aware proxy, analyzuje provoz a rozumí protokolu MySQL a jako takový jej lze použít pro pokročilé tvarování provozu - můžete blokovat dotazy, přepisovat je, směrovat je na konkrétní hostitele, ukládat do mezipaměti oni a mnoho dalších. Na druhé straně HAProxy je velmi jednoduchý, ale účinný proxy server vrstvy 4 a vše, co dělá, je posílat pakety na backend. ProxySQL lze použít k provedení rozdělení čtení a zápisu - rozumí SQL a lze jej nakonfigurovat tak, aby detekoval, zda je dotaz SELECT nebo ne, a podle toho je směroval:SELECTy do všech uzlů, ostatní dotazy pouze na master. Tato funkce není dostupná v HAProxy, které musí používat dva samostatné porty a dva samostatné backendy pro master a slave – rozdělení čtení a zápisu musí být provedeno na straně aplikace.

Proč migrovat na ProxySQL?

Na základě rozdílů, které jsme vysvětlili výše, bychom řekli, že hlavním důvodem, proč byste mohli chtít přejít z HAProxy na ProxySQL, je nedostatek rozdělení čtení a zápisu v HAProxy. Pokud používáte cluster databází MySQL a nezáleží na tom, zda se jedná o asynchronní replikaci nebo Galera Cluster, pravděpodobně budete chtít oddělit čtení od zápisů. Pro replikaci MySQL by to byl samozřejmě jediný způsob, jak využít váš databázový cluster, protože zápisy musí být vždy odesílány hlavnímu serveru. Pokud tedy nemůžete provést rozdělení čtení a zápisu, můžete dotazy posílat pouze masteru. Pro Galera rozdělení čtení a zápisu není nutností, ale rozhodně dobré. Jistě, můžete nakonfigurovat všechny uzly Galera jako jeden backend v HAProxy a posílat provoz do všech z nich způsobem kruhového provozu, ale to může vést k tomu, že zápisy z více uzlů budou ve vzájemném konfliktu, což povede k uváznutí a poklesu výkonu. Také jsme viděli problémy a chyby v clusteru Galera, pro které, dokud nebyly opraveny, bylo řešením přesměrovat všechny zápisy do jednoho uzlu. Nejlepším postupem je tedy posílat všechny zápisy do jednoho uzlu Galera, protože to vede ke stabilnějšímu chování a lepšímu výkonu.

Dalším velmi dobrým důvodem pro migraci na ProxySQL je potřeba mít lepší kontrolu nad provozem. S HAProxy nemůžete nic dělat - pouze posílá provoz na své backendy. S ProxySQL můžete utvářet svůj provoz pomocí pravidel dotazů (párování provozu pomocí regulárních výrazů, uživatele, schématu, zdrojového hostitele a mnoha dalších). OLAP SELECT můžete přesměrovat na analytický slave (platí pro replikaci i Galera). Svůj master můžete zbavit přesměrováním některých SELECTů mimo něj. Můžete implementovat SQL firewall. K některým dotazům můžete přidat zpoždění, můžete dotazy zabíjet, pokud trvají déle než předem definovanou dobu. Dotazy můžete přepsat a přidat tipy pro optimalizaci. To vše není možné s HAProxy.

Jak migrovat z HAProxy na ProxySQL?

Nejprve se podívejme na následující topologii...

Topologie ClusterControl MySQL MySQL Replication Cluster v ClusterControl

Máme zde replikační cluster skládající se z hlavního a dvou podřízených. Máme nasazeny dva HAProxy uzly, každý používá dva backendy - na portu 3307 pro master (zápis) a 3308 pro všechny uzly (čtení). Keepalived se používá k poskytování virtuální IP přes tyto dvě instance HAProxy – pokud jedna z nich selže, použije se jiná. Naše aplikace se připojuje přímo k VIP, přes něj k jedné z HAProxy instancí. Předpokládejme, že naše aplikace (budeme používat Sysbench) nemůže provést rozdělení čtení a zápisu, proto se musíme připojit k backendu „writer“. V důsledku toho je většina zátěže na našem masteru (10.0.0.101).

Jaké by byly kroky k migraci na ProxySQL? Zamysleme se nad tím na chvíli. Nejprve musíme nasadit a nakonfigurovat ProxySQL. Budeme muset přidat servery do ProxySQL, vytvořit požadované monitorovací uživatele a vytvořit správná pravidla dotazů. Nakonec budeme muset nasadit Keepalived nad ProxySQL, vytvořit další virtuální IP a poté zajistit co nejplynulejší přechod naší aplikace z HAProxy na ProxySQL.

Pojďme se podívat, jak toho můžeme dosáhnout...

Jak nainstalovat ProxySQL

ProxySQL lze nainstalovat mnoha způsoby. Můžete použít úložiště, buď ze samotného ProxySQL (https://repo.proxysql.com), nebo pokud náhodou používáte Percona XtraDB Cluster, můžete také nainstalovat ProxySQL z úložiště Percona, i když to může vyžadovat nějakou další konfiguraci, protože se spoléhá na CLI admin nástroje vytvořené pro PXC. Vzhledem k tomu, že mluvíme o replikaci, jejich použití může věci jen zkomplikovat. Nakonec můžete také nainstalovat binární soubory ProxySQL poté, co si je stáhnete z ProxySQL GitHub. V současné době existují dvě stabilní verze, 1.4.xa 2.0.x. Mezi ProxySQL 1.4 a ProxySQL 2.0 jsou rozdíly z hlediska funkcí, pro tento blog se budeme držet větve 1.4.x, protože je lépe testovaná a sada funkcí nám stačí.

Použijeme úložiště ProxySQL a nasadíme ProxySQL na dva další uzly:10.0.0.103 a 10.0.0.104.

Nejprve nainstalujeme ProxySQL pomocí oficiálního úložiště. Zajistíme také instalaci MySQL klienta (použijeme jej pro konfiguraci ProxySQL). Mějte prosím na paměti, že proces, kterým procházíme, není na úrovni výroby. Pro produkční verzi budete chtít alespoň změnit výchozí přihlašovací údaje pro administrativního uživatele. Budete také chtít zkontrolovat konfiguraci a ujistit se, že je v souladu s vašimi očekáváními a požadavky.

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

Nyní, když byl ProxySQL spuštěn, použijeme CLI ke konfiguraci ProxySQL.

mysql -uadmin -padmin -P6032 -h127.0.0.1

Nejprve definujeme backendové servery a replikační hostitelské skupiny:

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)

Máme tři servery, také jsme definovali, že ProxySQL by měl používat hostitelskou skupinu 10 pro master (uzel s read_only=0) a hostitelskou skupinu 20 pro slave (read_only=1).

Jako další krok musíme přidat monitorovacího uživatele na MySQL uzly, aby je ProxySQL mohl monitorovat. Půjdeme s výchozími nastaveními, v ideálním případě změníte přihlašovací údaje v 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)

Musíme tedy vytvořit uživatele „monitor“ s heslem „monitor“. K tomu budeme muset provést následující grant na hlavním serveru MySQL:

mysql> create user [email protected]'%' identified by 'monitor';
Query OK, 0 rows affected (0.56 sec)

Zpět k ProxySQL – musíme nakonfigurovat uživatele, které bude naše aplikace používat pro přístup k MySQL a pravidlům dotazů, která nám mají poskytnout rozdělení pro čtení a zápis.

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)

Vezměte prosím na vědomí, že jsme použili heslo v prostém textu a při jeho hašování se budeme spoléhat na ProxySQL. Z důvodu bezpečnosti byste zde měli explicitně zadat hash hesla MySQL.

Nakonec musíme použít všechny změny.

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)

Chceme také načíst hašovaná hesla z běhového prostředí:hesla ve formátu prostého textu jsou hašována při načtení do běhové konfigurace, aby bylo hašované na disku, musíme je načíst z běhového prostředí a poté uložit na 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)

To je ono, pokud jde o ProxySQL. Před provedením dalších kroků byste měli zkontrolovat, zda se můžete připojit k proxy z vašich aplikačních serverů.

[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

V našem případě vše vypadá dobře. Nyní je čas nainstalovat Keepalived.

Udržovaná instalace

Instalace je celkem jednoduchá (alespoň na Ubuntu 16.04, které jsme použili):

apt install keepalived

Poté musíte vytvořit konfigurační soubory pro oba servery:

Hlavní udržovací uzel:

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
}

Záložní udržovací uzel:

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

To je ono, můžete začít udržovat naživu na obou uzlech:

service keepalived start

V protokolech byste měli vidět informaci, že jeden z uzlů vstoupil do stavu MASTER a že na tomto uzlu byl vyvolán VIP.

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

Jak můžete vidět, na uzlu 10.0.0.103 byl zřízen VIP (10.0.0.112). Nyní můžeme uzavřít přesun provozu ze starého nastavení do nového.

Přepnutí provozu na nastavení ProxySQL

Existuje mnoho metod, jak to udělat, většinou záleží na konkrétním prostředí. Pokud náhodou používáte DNS k udržování domény směřující k vašemu HAProxy VIP, , stačí tam provést změnu a postupně, časem všechna spojení přesměrují na nový VIP. Můžete také provést změnu ve své aplikaci, zejména pokud jsou podrobnosti připojení pevně zakódovány – jakmile změnu zavedete, uzly se začnou připojovat k novému nastavení. Bez ohledu na to, jak to uděláte, bylo by skvělé otestovat nové nastavení, než provedete globální přechod. Určitě jste to otestovali ve svém pracovním prostředí, ale není špatný nápad vybrat si hrst aplikačních serverů a přesměrovat je na nový proxy a sledovat, jak vypadají z hlediska výkonu. Níže je uveden jednoduchý příklad s využitím iptables, které mohou být užitečné pro testování.

Na hostitelích ProxySQL přesměrujte provoz z hostitele 10.0.0.11 a portu 3307 na hostitele 10.0.0.112 a 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

V závislosti na vaší aplikaci budete možná muset restartovat webový server nebo jiné služby (pokud vaše aplikace vytváří stálý fond připojení k databázi) nebo jen počkat, až budou otevřena nová připojení k ProxySQL. Můžete ověřit, že ProxySQL přijímá provoz:

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                                          |
+-----------+--------+--------+-----------+---------+---------+-----------------------------------------------------------------------------+

To bylo vše, přesunuli jsme provoz z HAProxy do nastavení ProxySQL. Provedlo to několik kroků, ale rozhodně je to proveditelné s velmi malým přerušením služby.

Jak migrovat z HAProxy na ProxySQL pomocí ClusterControl?

V předchozí části jsme vysvětlili, jak ručně nasadit nastavení ProxySQL a poté do něj migrovat. V této části bychom rádi vysvětlili, jak dosáhnout stejného cíle pomocí ClusterControl. Počáteční nastavení je naprosto stejné, proto musíme pokračovat v nasazení ProxySQL.

Nasazení ProxySQL pomocí ClusterControl

Nasazení ProxySQL v ClusterControl je otázkou několika kliknutí.

Nasazení ProxySQL v ClusterControl

Museli jsme vybrat IP nebo název hostitele uzlu, předat přihlašovací údaje pro administrátora CLI a uživatele pro monitorování MySQL. Rozhodli jsme se použít stávající MySQL a předali jsme přístupové údaje pro uživatele ‚sbtest‘@‘%‘, které v aplikaci používáme. Vybrali jsme, které uzly chceme použít v nástroji pro vyrovnávání zatížení, také jsme zvýšili maximální zpoždění replikace (pokud je tento práh překročen, ProxySQL nepošle provoz tomuto slave zařízení) z výchozích 10 sekund na 100, protože již trpíme replikací. zpoždění. Po krátké chvíli budou do clusteru přidány uzly ProxySQL.

Nasazení Keepalived pro ProxySQL pomocí ClusterControl

Když byly přidány uzly ProxySQL, je čas nasadit Keepalived.

Udržováno pomocí ProxySQL v ClusterControl

Jediné, co jsme museli udělat, je vybrat, které uzly ProxySQL chceme nasadit Keepalived, virtuální IP a rozhraní, ke kterému bude VIP vázán. Po dokončení nasazení přepneme provoz na nové nastavení pomocí jedné z metod uvedených výše v části „Přepnutí provozu na nastavení ProxySQL“.

Monitorování provozu proxy SQL v ClusterControl

To, že se provoz přepnul na ProxySQL, si můžeme ověřit pohledem na graf zátěže – jak vidíte, zátěž je mnohem více rozložena mezi uzly v clusteru. Můžete to také vidět na grafu níže, který ukazuje rozložení dotazů v clusteru.

ProxySQL Dashboard v ClusterControl

A konečně řídicí panel ProxySQL také ukazuje, že provoz je distribuován mezi všechny uzly v clusteru:

ProxySQL Dashboard v ClusterControl

Doufáme, že z tohoto příspěvku na blogu budete mít užitek, jak můžete vidět, s ClusterControl nasazení nové architektury zabere jen okamžik a vyžaduje jen několik kliknutí, aby věci fungovaly. Dejte nám vědět o svých zkušenostech s takovými migracemi.


  1. Výukový program ovládání Activex ListView-01

  2. Pamatujte na instance RAC v Perf Tools

  3. Vytvořte tabulku v postupu

  4. Světový den zálohování:4 zajímavá fakta o ztrátě dat, která byste měli vědět