ProxySQL is een van de beste proxy's die er zijn voor MySQL. Het introduceerde een groot aantal opties voor databasebeheerders. Het maakte het mogelijk om het databaseverkeer vorm te geven door queries on-the-fly uit te stellen, te cachen of te herschrijven. Het kan ook worden gebruikt om een omgeving te creëren waarin failovers geen invloed hebben op applicaties en voor hen transparant zijn. We hebben de belangrijkste ProxySQL-functies al behandeld in eerdere blogposts:
- ClusterControl en ProxySQL gebruiken voor cachequery's
- Een SQL-firewall bouwen met ClusterControl en ProxySQL
- Een ProxySQL-cluster implementeren
- Een MySQL-replicatieomgeving eenvoudig implementeren met ProxySQL voor hoge beschikbaarheid
We hebben zelfs een tutorial over ProxySQL die laat zien hoe het kan worden gebruikt in MySQL- en MariaDB-configuraties.
Vrij recent is ProxySQL 2.0.3 uitgebracht, een patch-release voor de 2.0-serie. Bugs worden verholpen en de 2.0-lijn lijkt de grip te krijgen die het verdient. In deze blogpost willen we de belangrijkste wijzigingen bespreken die in ProxySQL 2.0 zijn geïntroduceerd.
Causale uitlezingen met GTID
Iedereen die te maken heeft gehad met replicatievertraging en worstelde met read-after-write-scenario's die worden beïnvloed door de replicatievertraging, zal zeker erg blij zijn met deze functie. Tot dusver was in MySQL-replicatieomgevingen de enige manier om causale reads te garanderen, het lezen van de master (en het maakt niet uit of u asynchrone of semi-synchrone replicatie gebruikt). Een andere optie was om voor Galera te gaan, die een optie had voor het afdwingen van causale reads sinds, zoals altijd (eerst was het wsrep-causal-reads en nu is het wsrep-sync-wait). Vrij recent (in 8.0.14) kreeg MySQL Group-replicatie een vergelijkbare functie. Regelmatige replicatie op zichzelf kan dit probleem echter niet oplossen. Gelukkig is ProxySQL hier en het brengt ons een optie om per queryregel te definiëren met welke hostgroep leest die overeenkomen met die queryregel, consistent zou moeten zijn. De implementatie wordt geleverd met ProxySQL binlog-lezer en het kan werken met het ROW binlog-formaat voor MySQL 5.7 en nieuwer. Alleen Oracle MySQL wordt ondersteund vanwege een gebrek aan vereiste functionaliteit in MariaDB. Deze functie en de technische details zijn uitgelegd op de officiële ProxySQL-blog.
SSL voor frontend-verbindingen
ProxySQL had altijd ondersteuning voor backend SSL-verbindingen, maar het ontbrak SSL-codering voor de verbindingen die van clients komen. Dit was niet zo'n groot probleem, aangezien het aanbevolen implementatiepatroon was om ProxySQL op applicatieknooppunten te plaatsen en een veilige Unix-socket te gebruiken om verbinding te maken van de app met de proxy. Dit is nog steeds een aanbeveling, vooral als je ProxySQL gebruikt voor cachequery's (Unix-sockets zijn sneller dan de TCP-verbinding, zelfs lokale en met cache is het goed om onnodige latentie te voorkomen). Wat goed is, is dat er met ProxySQL 2.0 nu een keuze is, omdat het SSL-ondersteuning voor inkomende verbindingen heeft geïntroduceerd. Je kunt het eenvoudig inschakelen door mysql-have_ssl in te stellen op 'true'. Het inschakelen van SSL heeft geen onaanvaardbare invloed op de prestaties. In tegenstelling, volgens de resultaten van de officiële ProxySQL-blog, is de prestatiedaling erg laag.
Native ondersteuning voor Galera Cluster
Galera Cluster wordt bijna sinds het begin ondersteund door ProxySQL, maar tot nu toe werd het gedaan via het externe script dat (meestal) is aangeroepen vanuit de interne planner van ProxySQL. Het was aan het script om ervoor te zorgen dat de ProxySQL-configuratie correct was, de schrijver (of schrijvers) correct werd gedetecteerd en geconfigureerd in de hostgroep van de schrijvers. Het script was in staat om de verschillende statussen te detecteren die Galera-knooppunt kan hebben (primair, niet-primair, gesynchroniseerd, Donor/Desync, Joining, Joined) en markeerde het knooppunt dienovereenkomstig als beschikbaar of niet. Het belangrijkste probleem is dat het originele script nooit bedoeld was als iets anders dan het proof of concept geschreven in Bash. Maar toen het samen met ProxySQL werd gedistribueerd, begon het te worden verbeterd, aangepast door externe bijdragers. Anderen (zoals Percona) hebben gekeken naar het maken van hun eigen scripts, gebundeld met hun software. Sommige fixes zijn geïntroduceerd in het script vanuit de ProxySQL-repository, sommige zijn geïntroduceerd in de Percona-versie van het script. Dit leidde tot verwarring en hoewel alle veelgebruikte scripts 95% van de use-cases afhandelden, dekte geen van de populaire scripts echt alle verschillende situaties en variabelen die Galera-cluster uiteindelijk zou kunnen gebruiken. Gelukkig wordt de ProxySQL 2.0 geleverd met native ondersteuning voor Galera Cluster. Hierdoor ondersteunt ProxySQL intern MySQL-replicatie, MySQL Group-replicatie en nu Galera Cluster. De manier waarop het wordt gedaan, lijkt erg op elkaar. We willen de configuratie van deze functie bespreken, omdat deze op het eerste gezicht misschien niet duidelijk is.
Net als bij MySQL-replicatie en MySQL Group-replicatie, is er een tabel gemaakt in ProxySQL:
mysql> show create table mysql_galera_hostgroups\G
*************************** 1. row ***************************
table: mysql_galera_hostgroups
Create Table: CREATE TABLE mysql_galera_hostgroups (
writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY,
backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL,
reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0),
offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0),
active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1,
max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1,
writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0,
max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0,
comment VARCHAR,
UNIQUE (reader_hostgroup),
UNIQUE (offline_hostgroup),
UNIQUE (backup_writer_hostgroup))
1 row in set (0.00 sec)
Er zijn talloze instellingen om te configureren en we zullen ze één voor één bespreken. Allereerst zijn er vier hostgroepen:
- Writer_hostgroup - deze bevat alle schrijvers (met alleen-lezen=0) tot de instelling 'max_schrijvers'. Standaard is het maar één schrijver
- Backup_writer_hostgroup - het bevat resterende schrijvers (read_only=0) die overblijven nadat 'max_writers' is toegevoegd aan writer_hostgroup
- Reader_hostgroup - het bevat lezers (read_only=1), het kan ook back-upschrijvers bevatten, volgens de instelling 'writer_is_also_reader'
- Offline_hostgroup - het bevat knooppunten die als onbruikbaar werden beschouwd (offline of in een staat die het onmogelijk maakt om verkeer te verwerken)
Dan hebben we de overige instellingen:
- Actief - of het item in mysql_galera_hostgroups actief is of niet
- Max_writers - hoeveel nodes kunnen er maximaal in de writer_hostgroup worden geplaatst
- Writer_is_also_reader - indien ingesteld op 0, worden schrijvers (read_only=0) niet in reader_hostgroup geplaatst. Indien ingesteld op 1, worden schrijvers (read_only=0) in reader_hostgroup geplaatst. Indien ingesteld op 2, worden knooppunten van backup_writer_hostgroup in reader_hostgroup geplaatst. Deze is een beetje ingewikkeld, daarom zullen we later in deze blogpost een voorbeeld geven
- Max_transactions_behind - gebaseerd op wsrep_local_recv_queue, de maximale wachtrij die acceptabel is. Als de wachtrij op het knooppunt max_transactions_behind overschrijdt, wordt het gegeven knooppunt gemarkeerd als GESLAAGD en is het niet beschikbaar voor het verkeer
De grootste verrassing is misschien de omgang met de lezers, wat anders is dan hoe het script in ProxySQL werkte. Allereerst, wat u in gedachten moet houden, is het feit dat ProxySQL read_only=1 gebruikt om te beslissen of node een lezer is of niet. Dit is gebruikelijk in replicatie-instellingen, niet zo gebruikelijk in Galera. Daarom wilt u hoogstwaarschijnlijk de instelling 'writer_is_also_reader' gebruiken om te configureren hoe lezers moeten worden toegevoegd aan de reader_hostgroep. Laten we eens kijken naar drie Galera-knooppunten, die allemaal read_only=0 hebben. We hebben ook max_writers=1 omdat we alle schrijfbewerkingen naar één knooppunt willen leiden. We hebben mysql_galera_hostgroups als volgt geconfigureerd:
SELECT * FROM mysql_galera_hostgroups\G
*************************** 1. row ***************************
writer_hostgroup: 10
backup_writer_hostgroup: 30
reader_hostgroup: 20
offline_hostgroup: 40
active: 1
max_writers: 1
writer_is_also_reader: 0
max_transactions_behind: 0
comment: NULL
1 row in set (0.00 sec)
Laten we alle opties doornemen:
writer_is_also_reader=0
mysql> SELECT hostgroup_id, hostname FROM runtime_mysql_servers;
+--------------+------------+
| hostgroup_id | hostname |
+--------------+------------+
| 10 | 10.0.0.103 |
| 30 | 10.0.0.101 |
| 30 | 10.0.0.102 |
+--------------+------------+
3 rows in set (0.00 sec)
Dit resultaat is anders dan je zou zien in de scripts - daar zou je resterende knooppunten hebben gemarkeerd als lezers. Hier, aangezien we niet willen dat schrijvers lezers zijn en aangezien er geen knooppunt is met read_only=1, zullen er geen lezers worden geconfigureerd. Eén schrijver (volgens max_writers), resterende knooppunten in backup_writer_hostgroup.
writer_is_also_reader=1
mysql> SELECT hostgroup_id, hostname FROM runtime_mysql_servers;
+--------------+------------+
| hostgroup_id | hostname |
+--------------+------------+
| 10 | 10.0.0.103 |
| 20 | 10.0.0.101 |
| 20 | 10.0.0.102 |
| 20 | 10.0.0.103 |
| 30 | 10.0.0.101 |
| 30 | 10.0.0.102 |
+--------------+------------+
6 rows in set (0.00 sec)
Hier willen we dat onze schrijvers als lezers optreden, daarom worden ze allemaal (actief en back-up) in de reader_hostgroep geplaatst.
writer_is_also_reader=2
mysql> SELECT hostgroup_id, hostname FROM runtime_mysql_servers;
+--------------+------------+
| hostgroup_id | hostname |
+--------------+------------+
| 10 | 10.0.0.103 |
| 20 | 10.0.0.101 |
| 20 | 10.0.0.102 |
| 30 | 10.0.0.101 |
| 30 | 10.0.0.102 |
+--------------+------------+
5 rows in set (0.00 sec)
Dit is een instelling voor degenen die niet willen dat hun actieve schrijver het lezen afhandelt. In dit geval worden alleen nodes van backup_writer_hostgroup gebruikt voor reads. Houd er ook rekening mee dat het aantal lezers zal veranderen als u max_writers op een andere waarde instelt. Als we het op 3 zouden zetten, zouden er geen back-upschrijvers zijn (alle knooppunten zouden in de schrijver-hostgroep terechtkomen), dus nogmaals, er zouden geen knooppunten in de lezer-hostgroep zijn.
Natuurlijk wilt u de queryregels dienovereenkomstig configureren voor de configuratie van de hostgroep. We zullen dit proces hier niet doorlopen, u kunt controleren hoe het kan in de ProxySQL-blog. Als je wilt testen hoe het werkt in een Docker-omgeving, hebben we een blog waarin wordt beschreven hoe je Galera-cluster en ProxySQL 2.0 op Docker kunt draaien.
Andere wijzigingen
Wat we hierboven beschreven, zijn de meest opvallende verbeteringen in ProxySQL 2.0. Er zijn er nog veel meer, volgens de changelog. Het vermelden waard zijn verbeteringen rond querycache (bijvoorbeeld toevoeging van PROXYSQL FLUSH QUERY CACHE) en wijziging waardoor ProxySQL kan vertrouwen op super_read_only om master en slaves te bepalen in replicatie-instellingen.
We hopen dat dit korte overzicht van de wijzigingen in ProxySQL 2.0 u zal helpen bepalen welke versie van de ProxySQL u moet gebruiken. Houd er rekening mee dat vertakking 1.4, zelfs als het geen nieuwe functies krijgt, nog steeds wordt onderhouden.