ProxySQL jest jednym z najlepszych serwerów proxy dla MySQL. Wprowadził wiele opcji dla administratorów baz danych. Umożliwiło to kształtowanie ruchu bazy danych poprzez opóźnianie, buforowanie lub przepisywanie zapytań w locie. Można go również wykorzystać do stworzenia środowiska, w którym przełączanie awaryjne nie będzie miało wpływu na aplikacje i będzie dla nich niewidoczne. Omówiliśmy już najważniejsze funkcje ProxySQL w poprzednich wpisach na blogu:
- Jak używać ClusterControl i ProxySQL do buforowania zapytań
- Jak zbudować zaporę SQL z ClusterControl i ProxySQL
- Jak wdrożyć klaster ProxySQL
- Jak łatwo wdrożyć środowisko replikacji MySQL za pomocą ProxySQL w celu zapewnienia wysokiej dostępności
Mamy nawet samouczek dotyczący ProxySQL pokazujący, jak można go używać w konfiguracjach MySQL i MariaDB.
Całkiem niedawno został wydany ProxySQL 2.0.3, będący poprawką dla serii 2.0. Błędy są naprawiane i wydaje się, że linia 2.0 zaczyna zdobywać trakcję, na jaką zasługuje. W tym wpisie na blogu chcielibyśmy omówić główne zmiany wprowadzone w ProxySQL 2.0.
Przyczynowe odczyty przy użyciu GTID
Każdy, kto miał do czynienia z opóźnieniem replikacji i borykał się ze scenariuszami odczytu po zapisie, na które wpływa opóźnienie replikacji, z pewnością będzie bardzo zadowolony z tej funkcji. Jak dotąd w środowiskach replikacji MySQL jedynym sposobem zapewnienia przyczynowych odczytów było odczytanie z mastera (i nie ma znaczenia, czy używasz replikacji asynchronicznej, czy półsynchronicznej). Inną opcją było wybranie Galery, która od zawsze miała opcję wymuszania odczytów przyczynowych (najpierw było to wsrep-causal-reads, a teraz jest to wsrep-sync-wait). Całkiem niedawno (w wersji 8.0.14) replikacja MySQL Group zyskała podobną funkcjonalność. Jednak regularne powielanie samo w sobie nie poradzi sobie z tym problemem. Na szczęście, ProxySQL jest tutaj i daje nam możliwość zdefiniowania na podstawie reguły dla zapytania, które grupy hostów odczytywane, które pasują do tej reguły zapytania, powinny być spójne. Implementacja zawiera czytnik binlogów ProxySQL i może współpracować z formatem ROW binlog dla MySQL 5.7 i nowszych. Obsługiwane jest tylko Oracle MySQL ze względu na brak wymaganych funkcji w MariaDB. Ta funkcja i jej szczegóły techniczne zostały wyjaśnione na oficjalnym blogu ProxySQL.
SSL dla połączeń frontendowych
ProxySQL zawsze posiadał wsparcie dla backendowego połączenia SSL, ale brakowało mu szyfrowania SSL dla połączeń przychodzących od klientów. Nie było to aż tak wielkim problemem, biorąc pod uwagę zalecany wzorzec wdrażania, polegający na umieszczeniu ProxySQL w węzłach aplikacji i użyciu bezpiecznego gniazda Unix do łączenia aplikacji z serwerem proxy. Jest to nadal rekomendacja, zwłaszcza jeśli używasz ProxySQL do buforowania zapytań (gniazdy Unix są szybsze niż połączenie TCP, nawet lokalne, a z cache dobrze jest unikać wprowadzania zbędnych opóźnień). Dobre jest to, że w ProxySQL 2.0 jest teraz wybór, ponieważ wprowadzono obsługę SSL dla połączeń przychodzących. Możesz go łatwo włączyć, ustawiając mysql-have_ssl na „true”. Włączenie SSL nie ma niedopuszczalnego wpływu na wydajność. W przeciwieństwie do tego, jak wynika z oficjalnego bloga ProxySQL, spadek wydajności jest bardzo niski.
Natywna obsługa klastra Galera
Galera Cluster jest obsługiwany przez ProxySQL prawie od samego początku, ale do tej pory odbywało się to za pośrednictwem zewnętrznego skryptu, który (zwykle) był wywoływany z wewnętrznego harmonogramu ProxySQL. Do skryptu należało upewnienie się, że konfiguracja ProxySQL jest poprawna, program zapisujący (lub program zapisujący) został poprawnie wykryty i skonfigurowany w grupie hostów pisarzy. Skrypt był w stanie wykryć różne stany, jakie może mieć węzeł Galera (podstawowy, niepodstawowy, zsynchronizowany, dawca/desynchronizacja, dołączający, dołączony) i odpowiednio oznaczyć węzeł jako dostępny lub nie. Głównym problemem jest to, że oryginalny scenariusz nigdy nie był pomyślany jako coś innego niż dowód koncepcji napisany w Bash. Jednak jako że był rozpowszechniany wraz z ProxySQL, zaczął być ulepszany, modyfikowany przez zewnętrznych autorów. Inni (jak Percona) zajęli się tworzeniem własnych skryptów dołączonych do ich oprogramowania. Niektóre poprawki zostały wprowadzone w skrypcie z repozytorium ProxySQL, niektóre zostały wprowadzone do wersji skryptu Percona. Doprowadziło to do zamieszania i chociaż wszystkie powszechnie używane skrypty obsługiwały 95% przypadków użycia, żaden z popularnych nie obejmował tak naprawdę wszystkich różnych sytuacji i zmiennych, z których może korzystać klaster Galera. Na szczęście ProxySQL 2.0 posiada natywną obsługę Galera Cluster. To sprawia, że ProxySQL obsługuje wewnętrzną replikację MySQL, MySQL Group Replication, a teraz Galera Cluster. Sposób, w jaki to się robi, jest bardzo podobny. Chcielibyśmy omówić konfigurację tej funkcji, ponieważ na pierwszy rzut oka może być niejasna.
Podobnie jak w przypadku replikacji MySQL i replikacji grupowej MySQL, w ProxySQL utworzono tabelę:
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)
Istnieje wiele ustawień do skonfigurowania i będziemy je przeglądać jeden po drugim. Przede wszystkim istnieją cztery grupy hostów:
- Writer_hostgroup — będzie zawierać wszystkie programy do zapisu (z read_only=0) aż do ustawienia „max_writers”. Domyślnie jest to tylko jeden pisarz
- Backup_writer_hostgroup - zawiera pozostałych pisarzy (read_only=0), które pozostały po dodaniu „max_writers” do writer_hostgroup
- Reader_hostgroup - zawiera czytniki (read_only=1), może również zawierać zapasowe zapisy, zgodnie z ustawieniem „writer_is_also_reader”
- Offline_hostgroup - zawiera węzły, które zostały uznane za nieużyteczne (zarówno w trybie offline, jak i w stanie uniemożliwiającym obsługę ruchu)
Następnie mamy pozostałe ustawienia:
- Aktywny - czy wpis w mysql_galera_hostgroups jest aktywny czy nie
- Max_writers - ile najwyżej węzłów można umieścić w grupie writer_hostgroup
- Writer_is_also_reader - jeśli jest ustawiony na 0, pisarze (tylko do odczytu=0) nie zostaną umieszczeni w grupie host_reader. Jeśli jest ustawiony na 1, pisarze (tylko do odczytu=0) zostaną umieszczone w grupie czytelnik_hosta. Jeśli ustawiono na 2, węzły z grupy backup_writer_hostgroup zostaną umieszczone w grupie reader_hostgroup. Ten jest nieco skomplikowany, dlatego w dalszej części tego wpisu na blogu przedstawimy przykład
- Max_transactions_behind — na podstawie wsrep_local_recv_queue, maksymalnej dopuszczalnej kolejki. Jeśli kolejka na węźle przekroczy max_transactions_behind dany węzeł zostanie oznaczony jako SHUNNED i nie będzie dostępny dla ruchu
Główną niespodzianką może być obsługa czytników, która różni się od działania skryptu zawartego w ProxySQL. Przede wszystkim należy pamiętać, że ProxySQL używa read_only=1 do decydowania, czy node jest czytnikiem, czy nie. Jest to powszechne w konfiguracjach replikacji, nie tak powszechne w Galera. Dlatego najprawdopodobniej będziesz chciał użyć ustawienia „writer_is_also_reader”, aby skonfigurować sposób dodawania czytelników do grupy reader_hostgroup. Rozważmy trzy węzły Galera, wszystkie mają read_only=0. Mamy również max_writers=1, ponieważ chcemy skierować wszystkie zapisy do jednego węzła. Skonfigurowaliśmy mysql_galera_hostgroups w następujący sposób:
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)
Przejdźmy przez wszystkie opcje:
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)
Ten wynik jest inny niż w skryptach - tam pozostałe węzły zostałyby oznaczone jako czytniki. W tym przypadku, biorąc pod uwagę, że nie chcemy, aby pisarze byli czytelnikami i biorąc pod uwagę, że nie ma węzła z tylko do odczytu=1, nie zostaną skonfigurowane żadne czytniki. Jeden pisarz (zgodnie z max_writers), pozostałe węzły w grupie 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)
Tutaj chcemy, aby nasi pisarze działali jako czytelnicy, dlatego wszyscy (aktywni i zapasowi) zostaną umieszczeni w grupie reader_hostgroup.
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)
Jest to ustawienie dla tych, którzy nie chcą, aby ich aktywny pisarz obsługiwał odczyty. W tym przypadku do odczytów zostaną użyte tylko węzły z grupy backup_writer_hostgroup. Pamiętaj również, że liczba czytelników zmieni się, jeśli ustawisz max_writers na inną wartość. Gdybyśmy ustawili ją na 3, nie byłoby żadnych zapisujących kopii zapasowych (wszystkie węzły znalazłyby się w grupie hostów zapisujących), więc znowu nie byłoby żadnych węzłów w grupie hostów odczytujących.
Oczywiście będziesz chciał skonfigurować reguły zapytań zgodnie z konfiguracją grupy hostów. Nie będziemy tutaj przechodzić przez ten proces, możesz sprawdzić jak można to zrobić na blogu ProxySQL. Jeśli chcesz przetestować, jak to działa w środowisku Docker, mamy blog, który opisuje, jak uruchomić klaster Galera i ProxySQL 2.0 w Dockerze.
Inne zmiany
To, co opisaliśmy powyżej, to najważniejsze ulepszenia w ProxySQL 2.0. Istnieje wiele innych, zgodnie z dziennikiem zmian. Warto wspomnieć o ulepszeniach związanych z pamięcią podręczną zapytań (na przykład dodanie PROXYSQL FLUSH QUERY CACHE) i zmianach, które pozwalają ProxySQL polegać na super_read_only do określania mastera i slave'a w konfiguracji replikacji.
Mamy nadzieję, że ten krótki przegląd zmian w ProxySQL 2.0 pomoże Ci określić, której wersji ProxySQL powinieneś użyć. Pamiętaj, że gałąź 1.4, nawet jeśli nie otrzyma żadnych nowych funkcji, nadal jest utrzymywana.