MySQL HeatWave - Speed up your OLAP tasks
Mit MySQL HeatWave bietet Oracle nun seit einiger Zeit einen Service in der Oracle Cloud (OCI) an, mit dem sich die Performance von Analysen & Transaktionsabfragen, ohne großen technischen Aufwand erheblich verbessern lässt.
Durch die Verwendung von sogenannten HeatWave-Engines (oder auch RAPID-Engine genannt), zusätzlich zur eigentlichen MySQL-Instanz, lassen sich ohne weitere Anpassungen OLTP (Online Transaction Processing)- und OLAP (Online Analytical Processing)-Workloads, direkt innerhalb der MySQL-Datenbank ausführen. Dabei bietet Oracle den bequemen Vorteil, dass kein einziges SQL aus Sicht der Anwendung angepasst werden muss, um die gewünschte Performanceverbesserung erzielen zu können.
Das Datenbanksystem wird hierbei um ein HeatWave-Plugin erweitert, welches die Queries entgegennimmt und letztlich mit Hilfe zusätzlicher HeatWave-Cluster abarbeitet. Für die Anwendung ändert sich erstmal nichts (abgesehen von der spürbar besseren Performance).
Damit die Queries durch die HeatWave-Engine verarbeitet werden können, muss die Engine für die betroffenen Tabellen definiert werden. Anschließend wird der Inhalt der Tabelle in die Engine geladen:
alter table lineitem secondary_engine=rapid;
alter table lineitem secondary_load;
Sobald die "RAPID"-Engine als zweite Engine für diese Tabelle hinzugefügt wurde, werden sämtliche Datensätze gesperrt.
DDLs sind ab diesen Zeitraum nicht mehr möglich.
Die hier gezeigte Methode zum Laden der Daten in die Engine ist stark vereinfacht. Es gibt zahlreiche manuelle Anpassungen, die vorgenommen werden können bzw. müssen. So sollte im Vorfeld beispielsweise sichergestellt werden, dass die Engine über genügend Speicher verfügt oder ob die Tabellen & Datensätze überhaupt kompatibel sind.
Oracle liefert hierfür einen System Call, der dieses Laden automatisieren und parallelisieren kann (für mehr Details: https://dev.mysql.com/doc/heatwave/en/auto-parallel-load.html):
sys.heatwave_load (db_list,[options]);
In einem nachfolgenden Beitrag werde ich genauer auf den Prozess des Ladens eingehen. Für mein jetziges Ziel reicht das Verständnis über den Ablauf vollständig aus.
TPC-H Benchmark
Um nun eine vergleichbare Basis zu schaffen, verwende ich die Daten und definierten Abfragen des TPC-H Benchmarks (http://www.tpc.org/tpch/). Exemplarisch wurden hierzu Datenbanken mit einer Größe von 3, 9, 18 und 36 GB erstellt. Die definierten Abfragen werden in diesem Szenario sowohl mit, als auch ohne die HeatWave-Engine ausgeführt und protokolliert.
Es folgt ein Beispiel mit der 3GB großen Datenbank tpc_3 und der TPC-H Query 3. Zunächst laden wir die gesamten Tabellen der Datenbank in die HeatWave Engine:
MySQL 10.0.0.125:3306 ssl tpch_3 SQL > SELECT NAME, LOAD_STATUS from performance_schema.rpd_tables,performance_schema.rpd_table_id where rpd_tables.ID = rpd_table_id.ID; Empty set (0.0010 sec) SET SQL_SAFE_UPDATES = 0; MySQL 10.0.0.125:3306 ssl tpch_3 SQL > CALL sys.heatwave_load(JSON_ARRAY("tpch_3"),NULL); +------------------------------------------+ | INITIALIZING HEATWAVE AUTO PARALLEL LOAD | +------------------------------------------+ | Version: 1.22 | | | | Load Mode: normal | | Load Policy: disable_unsupported_columns | | Output Mode: normal | | | +------------------------------------------+ 6 rows in set (0.0065 sec) +------------------------------------------------------------------------+ | OFFLOAD ANALYSIS | +------------------------------------------------------------------------+ | Verifying input schemas: 1 | | User excluded items: 0 | | | | SCHEMA OFFLOADABLE OFFLOADABLE SUMMARY OF | | NAME TABLES COLUMNS ISSUES | | ------ ----------- ----------- ---------- | | `tpch_3` 8 61 | | | | Total offloadable schemas: 1 | | | +------------------------------------------------------------------------+ 10 rows in set (0.0065 sec) +-----------------------------------------------------------------------------------------------------------------------------+ | CAPACITY ESTIMATION | +-----------------------------------------------------------------------------------------------------------------------------+ | Default load pool for tables: TRANSACTIONAL | | Default encoding for string columns: VARLEN (unless specified in the schema) | | Estimating memory footprint for 1 schema(s) | | | | TOTAL ESTIMATED ESTIMATED TOTAL DICTIONARY VARLEN ESTIMATED | | SCHEMA OFFLOADABLE HEATWAVE NODE MYSQL NODE STRING ENCODED ENCODED LOAD | | NAME TABLES FOOTPRINT FOOTPRINT COLUMNS COLUMNS COLUMNS TIME | | ------ ----------- --------- --------- ------- ---------- ------- --------- | | `tpch_3` 8 5.78 GiB 32.00 MiB 29 0 29 20.00 s | | | | Sufficient MySQL host memory available to load all tables. | | Sufficient HeatWave cluster memory available to load all tables. | | | +-----------------------------------------------------------------------------------------------------------------------------+ 13 rows in set (0.0065 sec) +-------------------------------------------------------------------------------+ | LOAD SUMMARY | +-------------------------------------------------------------------------------+ | | | SCHEMA TABLES TABLES COLUMNS LOAD | | NAME LOADED FAILED LOADED DURATION | | ------ ------ ------ ------- -------- | | `tpch_3` 8 0 61 6.73 s | | | +-------------------------------------------------------------------------------+
Die gesamte Datenbank wurde nun erfolgreich in die Engine geladen.
MySQL 10.0.0.125:3306 ssl tpch_3 SQL > SELECT NAME, LOAD_STATUS from performance_schema.rpd_tables,performance_schema.rpd_table_id where rpd_tables.ID = rpd_table_id.ID; +-----------------+---------------------+ | NAME | LOAD_STATUS | +-----------------+---------------------+ | tpch_3.orders | AVAIL_RPDGSTABSTATE | | tpch_3.lineitem | AVAIL_RPDGSTABSTATE | | tpch_3.nation | AVAIL_RPDGSTABSTATE | | tpch_3.region | AVAIL_RPDGSTABSTATE | | tpch_3.customer | AVAIL_RPDGSTABSTATE | | tpch_3.part | AVAIL_RPDGSTABSTATE | | tpch_3.supplier | AVAIL_RPDGSTABSTATE | | tpch_3.partsupp | AVAIL_RPDGSTABSTATE | +-----------------+---------------------+
Zum Vergleich wird die HeatWave-Engine zunächst deaktiviert, das Profiling aktiviert und die Query 3 des Benchmarks ausgeführt.
MySQL 10.0.0.125:3306 ssl SQL > use tpch_3 MySQL 10.0.0.125:3306 ssl tpch_3 SQL > set @@use_secondary_engine=off; SET @@profiling = 0; SET @@profiling_history_size = 0; SET @@profiling = 1; SET @@profiling_history_size = 100; SELECT l_orderkey, sum(l_extendedprice * (1 - l_discount)) as revenue, o_orderdate, o_shippriority FROM customer, orders, lineitem WHERE c_mktsegment = 'BUILDING' AND c_custkey = o_custkey AND l_orderkey = o_orderkey AND o_orderdate < date '1995-03-15' AND l_shipdate > date '1995-03-15' GROUP BY l_orderkey, o_orderdate, o_shippriority ORDER BY revenue desc, o_orderdate LIMIT 20; show profiles;
→ | 4 | 7.0137665
Die Query benötigt ohne HeatWave-Engine gute 7 Sekunden. Nun zum Vergleich die gleiche Query mit aktivierter HeatWave-Engine. Zu Darstellungszwecken wird das SQL nicht erneut ausgegeben:set @@use_secondary_engine=on; SET @@profiling = 0; SET @@profiling_history_size = 0; SET @@profiling = 1; SET @@profiling_history_size = 100; <Query 3> show profiles;
→ | 15 | 0.7033645
Mit eingeschalteter HeatWave-Engine benötigt die Query nur 0,7 Sekunden. Eine Anzeige des Ausführungsplans (mit EXPLAIN) zeigt nun den Hinweis, dass als Secondary Engine RAPID, also die HeatWave-Engine, verwendet wird.Using where; Using temporary; Using filesort; Using secondary engine RAPID
Erweitert man die Teststrecke nun um sämtliche Queries und die verschiedenen Datenbankgrößen, zeigt sich folgendes Bild:
Besonders deutlich wird der Laufzeitunterschied bei Query 9 mit 114 Sekunden ohne und lediglich 0,26 Sekunden Laufzeit mit der RAPID-Engine. Selbst bei einer kleinen Datenmenge, die problemlos in nahezu jeden Database Buffer passt, schlägt die RAPID-Engine, InnoDB um Längen. Mit Zunahme der Datenmenge wird dieser Unterschied immer stärker sichtbar:
DB Größe (in GB) | Query | InnoDB (in s) | RAPID (in s) | InnoDB/RAPID |
3 | 3 | 7,12 | 0,059 | 120-fache |
9 | 17,407 | 0,073 | 238-fache | |
9 | 3 | 50,98 | 0,107 | 476-fache |
9 | 364,87 | 0,825 | 442-fache | |
18 | 3 | 65,03 | 0,197 | 330-fache |
9 | 684,85 | 4,548 | 150-fache | |
36 | 3 | 250,12 | 0,384 | 651-fache |
9 | - | - | - |
Was hierbei deutlich wird: Bei linearer Entwicklung der Datenmenge (9 – 18 – 36 GB), nimmt die Laufzeit der RAPID-Engine ebenfalls linear zu ( 0,107 - 0,197 – 0,384 Sekunden), während die InnoDB-Engine ab einer bestimmten Größe (abhängig vom Database Buffer) eher exponentiell ansteigt (50,98 – 65,03 – 250,12 Sekunden).
Die RAPID-Engine kann also OLTP/OLAP-Abfragen, auf Basis einer großen Datenmenge, um ein Vielfaches schneller verarbeiten, als die klassische InnoDB-Engine. Hierbei kommt es in jedem Fall auf die Datenbasis und Konfiguration der Datenbank an, ab der die InnoDB-Engine ins Hintertreffen gerät.
Der Gedanke hinter der Verwendung von HeatWave ist klar: Steht planmäßig eine OLTP/OLAP-Verarbeitung an, können die Engines modular hinzugeschaltet und die Abfragen so beschleunigt werden. Dazu ist lediglich ein Laden der Daten notwendig. Den Rest übernimmt die Engine selbst. Nach der Abarbeitung der Abfragen werden die Daten wieder entladen, Sperren aufgehoben und die Engines heruntergefahren.
Für eine Datenbank, die sich bereits in der Oracle-Cloud befindet, entstehen so nur marginale Mehrkosten, da die Ressourcen nur temporär verwendet werden müssen.
In diesem Satz steckt allerdings auch der Knackpunkt: HeatWave ist aktuell lediglich ein Benefit-Tool der OCI und steht auch nur dort zur Verfügung. Für En-Premise-Datenbanken ist die Hürde also deutlich höher, da zunächst eine Migration notwendig sein wird.
Wer aber bereits seine MySQL-Datenbank in der OCI betreibt und klassische Datawarehouse-Auswertungen benötigt, sollte HeatWave eine Chance geben.
Seminar zum Thema
MySQL Administration
Zum SeminarBei Updates im Blog, informieren wir per E-Mail.
Kommentare