Vyřizování velkých transakcí bylo v Galera Cluster vždy problémem. Způsob, jakým funguje certifikace sady zápisů Galera, způsobuje potíže, když jsou transakce dlouhé nebo když se jeden řádek často upravuje na více uzlech. V důsledku toho musí být transakce vráceny zpět a opakovány, což způsobí pokles výkonu. Naštěstí byl tento problém vyřešen v Galeře 4, novém vydání Galery od Codership. Tato knihovna se používá v MariaDB 10.4, takže instalace MariaDB 10.4 je nejjednodušší způsob testování nově zavedených funkcí. V tomto příspěvku na blogu se podíváme na to, jak lze streamovací replikaci použít ke zmírnění problémů, které bývaly standardním problémem v předchozích verzích Galery.
Použijeme tři uzly clusteru MariaDB Galera verze 10.4.6, který je dodáván s verzí Galera 26.4.2.
MariaDB [(none)]> show global status like 'wsrep_provider%';
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| wsrep_provider_capabilities | :MULTI_MASTER:CERTIFICATION:PARALLEL_APPLYING:TRX_REPLAY:ISOLATION:PAUSE:CAUSAL_READS:INCREMENTAL_WRITESET:UNORDERED:PREORDERED:STREAMING:NBO: |
| wsrep_provider_name | Galera |
| wsrep_provider_vendor | Codership Oy <[email protected]> |
| wsrep_provider_version | 26.4.2(r4498) |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.001 sec)
Existují tři hlavní problémy, se kterými se má streamingová replikace vypořádat:
- Dlouhé transakce
- Velké transakce
- Žhavá místa v tabulkách
Podívejme se na ně jeden po druhém a podívejme se, jak nám může replikace streamování pomoci se s nimi vypořádat, ale nejprve se zaměřme na certifikaci sady zápisů – hlavní příčinu těchto problémů, které se objevují.
Writeset Certification v Galera Cluster
Cluster Galera se skládá z více zapisovatelných uzlů. Každá transakce provedená na clusteru Galera tvoří sadu zápisů. Každá sada zápisů musí být odeslána všem uzlům v clusteru k certifikaci - proces, který zajišťuje, že všechny uzly mohou použít danou transakci. Zápisové sady musí být provedeny na všech uzlech clusteru, takže pokud dojde ke konfliktu, transakci nelze potvrdit. Jaké jsou typické důvody, proč nelze transakci potvrdit? No, tři body, které jsme uvedli dříve:
- Dlouhé transakce – déle transakce trvá, je pravděpodobnější, že mezitím jiný uzel provede aktualizace, které budou nakonec v konfliktu se sadou zápisů a zabrání mu projít certifikací.
- Velké transakce – za prvé, velké transakce jsou také delší než malé, takže to vyvolává první problém. Druhý problém, úzce související s velkými transakcemi, je objem změn. Bude aktualizováno více řádků, pravděpodobnější je, že nějaký zápis na jiný uzel povede ke konfliktu a celá transakce bude muset být vrácena zpět.
- Hot spots v tabulkách – pravděpodobnější bude aktualizace daného řádku, pravděpodobněji dojde k takové aktualizaci současně na více uzlech, což povede k tomu, že některé transakce budou vráceny zpět
Hlavním problémem zde je, že Galera nezavádí žádné uzamčení na jiných uzlech než na počátečním uzlu, na kterém byla transakce otevřena. Proces certifikace je založen na naději, že pokud jeden uzel může provést transakci, ostatní by to měli být také schopni. Je to pravda, ale jak jsme diskutovali, existují rohové případy, ve kterých je pravděpodobnost, že se to stane, výrazně snížena.
V Galeře 4 se s replikací datových proudů chování změnilo a ve všech uzlech jsou přijímány všechny zámky. Transakce budou rozděleny na části a každá část bude certifikována na všech uzlech. Po úspěšné certifikaci budou řádky uzamčeny na všech uzlech v clusteru. Existuje několik proměnných, které řídí, jak přesně se to dělá - wsrep_trx_fragment_size a wsrep_trx_fragment_unit definují, jak velký by měl být fragment a jak by měl být definován. Je to velmi jemné ovládání:jednotku fragmentu můžete definovat jako bajty, příkazy nebo řádky, což umožňuje spustit certifikaci pro každý řádek upravený v transakci. Pojďme se podívat na to, jak můžete těžit z replikace streamování v reálném životě.
Práce se streamovací replikací
Zvažme následující scénář. Máme spuštěnou transakci, která trvá alespoň 30 sekund:
BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Poté, zatímco běží, provedeme SQL, který se dotýká podobných řádků. To bude provedeno na jiném uzlu:
BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Jaký by byl výsledek?
První transakce je odvolána, jakmile je provedena druhá:
MariaDB [sbtest]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Query OK, 0 rows affected (0.001 sec)
Query OK, 667 rows affected (0.020 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (0.010 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (0.009 sec)
Rows matched: 667 Changed: 667 Warnings: 0
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Query OK, 0 rows affected (0.001 sec)
Transakce na druhém uzlu byla úspěšná:
MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)
Query OK, 7 rows affected (0.002 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 7 rows affected (0.001 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 0 rows affected (0.004 sec)
Co můžeme udělat, abychom se tomu vyhnuli, je použití streamingové replikace pro první transakci. Požádáme Galeru, aby potvrdila každou změnu řádku:
MariaDB [sbtest]> BEGIN; SET SESSION wsrep_trx_fragment_size=1 ; SET SESSION wsrep_trx_fragment_unit='rows' ; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT; SET SESSION wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.001 sec)
Query OK, 0 rows affected (0.000 sec)
Query OK, 0 rows affected (0.000 sec)
Query OK, 667 rows affected (1.757 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (1.708 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (1.685 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Jak vidíte, tentokrát to fungovalo dobře. Na druhém uzlu:
MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)
Query OK, 7 rows affected (33.942 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 7 rows affected (0.001 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 0 rows affected (0.026 sec)
Co je zajímavé, můžete vidět, že provedení UPDATE trvalo téměř 34 sekund - bylo to způsobeno tím, že počáteční transakce prostřednictvím streamovací replikace uzamkla všechny upravené řádky na všech uzlech a naše druhá transakce musela čekat na první, která byla dokončena, i když byly obě transakce provedeny na různých uzlech.
To je v podstatě to, co se týká streamování replikace. V závislosti na požadavcích a provozu jej můžete používat méně přísným způsobem - certifikovali jsme každý řádek, ale můžete to změnit na každý n-tý řádek nebo každý výpis. Můžete dokonce rozhodnout o objemu dat k certifikaci. To by mělo stačit, aby odpovídalo požadavkům vašeho prostředí.
Rádi bychom, abyste měli na paměti a zapamatovali si je ještě několik věcí. Za prvé, streamingová replikace není v žádném případě řešením, které by se mělo používat standardně. To je důvod, proč je ve výchozím nastavení zakázáno. Doporučeným případem použití je ruční rozhodnutí o transakcích, které by profitovaly z replikace streamování, a její povolení na úrovni relace. To je důvod, proč naše příklady končí:
SET SESSION wsrep_trx_fragment_size=0;
Tento příkaz (nastavení wsrep_trx_fragment_size na 0) zakáže replikaci streamování pro aktuální relaci.
Další věc, kterou stojí za to zapamatovat – pokud náhodou používáte replikaci streamování, použije tabulku „wsrep_streaming_log“ ve schématu „mysql“ pro trvalé ukládání dat, která jsou streamována. Pomocí této tabulky můžete získat určitou představu o datech, která jsou přenášena napříč clusterem pomocí streamingové replikace.
Konečně výkon. To je také jeden z důvodů, proč nechcete neustále používat streamingovou replikaci. Hlavním důvodem je zamykání - se streamovací replikací musíte získat zámky řádků na všech uzlech. Získání zámků chvíli trvá, a pokud budete muset transakci vrátit zpět, vyvine to také tlak na všechny uzly, aby provedly vrácení zpět. Provedli jsme velmi rychlý test dopadu na výkon, který má streamingová replikace. Prostředí je přísně testovací, takže nepředpokládejte, že tyto výsledky budou stejné na produkčním hardwaru, je spíše na vás, abyste viděli, jaký to může mít dopad.
Testovali jsme čtyři scénáře:
- Základní hodnota, nastavte globální hodnotu wsrep_trx_fragment_size=0;
- set global wsrep_trx_fragment_unit='rows'; nastavit globální wsrep_trx_fragment_size=1;
- set global wsrep_trx_fragment_unit='příkazy'; nastavit globální wsrep_trx_fragment_size=1;
- set global wsrep_trx_fragment_unit='příkazy'; nastavit globální wsrep_trx_fragment_size=5;
Použili jsme sysbench r/w test:
sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --events=0 --time=300 --mysql-host=10.0.0.141 --mysql-user=sbtest --mysql-password=sbtest --mysql-port=3306 --tables=32 --report-interval=1 --skip-trx=off --table-size=100000 --db-ps-mode=disable run
Výsledky jsou:
- Transakce:82,91 za sekundu, dotazy:1658,27 za sekundu. (100 %)
- Transakce:54,72 za sekundu, dotazy:1094,43 za sekundu. (66 %)
- Transakce:54,76 za sekundu, dotazy:1095,18 za sekundu. (66 %)
- Transakce:70,93 za sekundu, dotazy:1418,55 za sekundu. (86 %)
Jak vidíte, dopad je značný, výkon klesá dokonce o 33 %.
Doufáme, že jste shledali tento blogový příspěvek informativním a že vám poskytl nějaké informace o replikaci streamování, která přichází s Galera 4 a MariaDB 10.4. Pokusili jsme se pokrýt případy použití a potenciální nevýhody související s touto novou technologií.