Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[HeatWavejpMeetup#13] HeatWave Lakehouse で オブジェ...

[HeatWavejpMeetup#13] HeatWave Lakehouse で オブジェクト・ストレージのデータ変換/加工ができるか試してみた![@vidaisuki 氏]

【講演内容】
HeatWave Lakehouse で オブジェクト・ストレージのデータ変換/加工ができるか試してみた!

 - HeatWaveの魅力とは?
 ‐ HeatWave Lakehouse / Lakehouse Architecture
 ‐ Exporting query results to object storage with HeatWave
→ クエリの結果をオブジェクトストレージにエクスポート、これをOCIでためしてみます。

【発表者】
@vidaisuki 氏

【イベント情報】
HeatWavejp Meetup #13
https://heatwavejp.connpass.com/event/349599/

More Decks by HeatWavejp(MySQL HeatWave Japan User Group)

Other Decks in Technology

Transcript

  1. HeatWaveの魅力とは? 魅力ポイント 内容・補足 爆速な分析 インメモリ列指向エンジン(HeatWave)で、100 倍以上のクエリ高速化も可能 MySQLに統合 別のDWHを用意せず、MySQLのままでOLAPが できる(ETL不要!) マネージド

    & 自動化 OCI上で完全マネージド。スケーリングやイン デックス最適化(Autopilot)も自動 Lakehouse対応(2023〜) Parquet/CSVファイルを直接分析可能。S3やOCI Object StorageをそのままJOINできる コスト効率が高い SnowflakeやRedshiftと比べて最大80%以上安く、 かつ高速(公式ベンチあり) Oracle製MySQLなので安心 MySQLの作者がOracleにいる安心感。エンタープ ライズ対応も手厚い 使い慣れたSQLで全部できる 別言語やツールを覚えずに、SQLだけで分析〜可 視化までできるのが強み ここが一番の魅力かなと思いますが、MySQLを使っていないと縁が遠い
  2. Transform Tool Lakehouse Architecture データの加工/変換が必要 Data source Prepare and transform

    Analyze Events Functions Integration Bronze Layer BI Tool Silver Layer Gold Layer Data File Database Analytics Engine
  3. Exporting query results to object storage with HeatWave • クエリの結果をオブジェクトストレージにエクスポート、これを

    OCIでためしてみます。 • Changes in HeatWave 9.1.1 (2024-11-19, General Availability) • HeatWave Lakehouse • HeatWave Lakehouse now supports exporting query results directly to an object store in OCI or AWS. This lets you store, transform, and persist data in CSV and Parquet formats. The new syntaxes introduced make it easier to export data, especially in command-line environments, and provide more control over the output format. This enhancement enables efficient data storage, retrieval, and transformation, improving data management and analysis workflows. • For more information, see Exporting Query Results to Object Storage. (WL #16214)
  4. 権限の確認(MySQL) EXPORT_QUERY_RESULTS が付与されている事 初期ユーザー(Admin)では最初からついているが、ユーザーを作成する場合 は別途付与する。 SQL > show grants; -略

    | GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE,zenn REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE ROLE, DROP ROLE ON *.* TO `vidaisuki`@`%` WITH GRANT OPTION | | GRANT APPLICATION_PASSWORD_ADMIN,AUDIT_ADMIN,BACKUP_ADMIN,CONNECTION_ADMIN,EXPORT_QUERY_RESULTS,FLUSH_OPTIMIZER _COSTS,FLUSH_PRIVILEGES,FLUSH_STATUS,FLUSH_TABLES,FLUSH_USER_RESOURCES,OPTION_TRACKER_OBSERVER,REPLICATIO N_APPLIER,ROLE_ADMIN,SET_ANY_DEFINER,SHOW_ROUTINE,TRANSACTION_GTID_TAG,VECTOR_STORE_LOAD_EXEC,XA_RECOVER_ ADMIN ON *.* TO `vidaisuki`@`%` WITH GRANT OPTION | 略|
  5. サンプルデータ(TPC-H) $ head -5 orders.tbl 1|36901|O|173665.47|1996-01-02|5-LOW|Clerk#000000951|0|nstructions sleep furiously among |

    2|78002|O|46929.18|1996-12-01|1-URGENT|Clerk#000000880|0| foxes. pending accounts at the pending, silent asymptot| 3|123314|F|193846.25|1993-10-14|5-LOW|Clerk#000000955|0|sly final accounts boost. carefully regular ideas cajole carefully. depos| 4|136777|O|32151.78|1995-10-11|5-LOW|Clerk#000000124|0|sits. slyly regular warthogs cajole. regular, regular theodolites acro| 5|44485|F|144659.20|1994-07-30|5-LOW|Clerk#000000925|0|quickly. bold deposits sleep slyly. packages use slyly| http://www.tpc.org/tpch/ dbgenでデータ作成 区切り文字「|」、行末「|¥¥n」
  6. 権限の確認(OCI) 動的グループの作成 • アイデンティティ>ドメイン>”ドメイン名”>動的グループ • 動的グループの作成>一致ルールの追加 • ALL{resource.type='mysqldbsystem', resource.compartment.id =

    '<user-Compartment-ocid>'} • ALL {instance.compartment.id = ‘<user-Compartment- ocid>’} ※コンピュートインスタンスからオブジェクトストレージにアクセスする為
  7. 権限の確認(OCI) ポリシーの作成 • アイデンティティ>ポリシー>ポリシーの作成 • >ポリシーステートメントの編集 • Allow dynamic-group '<Domain-name>'/'<Dynamic-Group-Name>'

    to read buckets in compartment id <user-Compartment-ocid> • Allow dynamic-group '<Domain-name>'/'<Dynamic-Group-Name>' to manage objects in compartment id <user-Compartment-ocid> where any {request.permission='OBJECT_READ',request.permission='OBJECT_CREATE', request.permission='OBJECT_INSPECT', request.permission='OBJECT_OVERWRITE', request.permission='OBJECT_DELETE’} • 前項で作成した動的グループにオブジェクトストレージへのアクセスを 許可
  8. ファイルアップロード $ oci os object put --bucket-name heatwave-lakehouse-test - -name

    "lakehouse_test/nation/orders.tbl" -- file ./orders.tbl -auth instance_principal コンピュートインスタンスからファイルアップロード(もしくは直接バケットにアップロード)。
  9. テーブル作成 CREATE TABLE `ORDERS` ( `O_ORDERKEY` bigint NOT NULL, `O_CUSTKEY`

    int NOT NULL, `O_ORDERSTATUS` char(1) NOT NULL, `O_TOTALPRICE` decimal(15,2) NOT NULL, `O_ORDERDATE` date NOT NULL, `O_ORDERPRIORITY` char(15) NOT NULL, `O_CLERK` char(15) NOT NULL, `O_SHIPPRIORITY` int NOT NULL, `O_COMMENT` varchar(79) NOT NULL) ENGINE=Lakehouse DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci SECONDARY_ENGINE=RAPID ENGINE_ATTRIBUTE='{"file": [{"bucket": "heatwave-lakehouse-test", "prefix": "lakehouse_test/orders/", "region": "ap-tokyo-1", "namespace": "bucket_namespace"}], "dialect": {"format": "csv", "has_header": false, "is_strict_mode": false, "field_delimiter": "|", "record_delimiter": "|¥¥n"}}' バケットやdialect(ファイルの書式等)を指定
  10. データをHeatWaveにロード SQL > SET @input_list = '[{ "db_name": "lakehouse_test", "tables":

    [ { "table_name": "ORDERS" } ] }]'; SQL > SET @options = JSON_OBJECT('mode', 'normal', 'refresh_external_tables', TRUE); SQL > CALL sys.heatwave_load(CAST(@input_list AS JSON), @options);
  11. データをHeatWaveにロードを確認 SQL > SELECT log FROM sys.heatwave_autopilot_report WHERE type IN

    ('error', 'warn'); +---------------------------------------------------------------------------- -------------------| {"cmd": "¥"ALTER TABLE /*+ AUTOPILOT_DISABLE_CHECK */ `lakehouse_test`.`ORDERS` SECONDARY_LOAD;¥"", "msg": "Command Issue", "warn": "[WARNINGS SUMMARY] Lakehouse Load had 1 warning(s) out of which 1 were not recorded (due to max_error_count limit or filtering rules)", "location": "EXECUTE stmt", "table_name": "ORDERS", "schema_name": "lakehouse_test"} | | {"cmd": "¥"ALTER TABLE /*+ AUTOPILOT_DISABLE_CHECK */ `lakehouse_test`.`ORDERS` SECONDARY_LOAD;¥"", "msg": "Command Issue", "warn": "[WARNINGS SUMMARY] 1 warning(s) with code: 6069(ER_LH_EMPTY_FILE)", "location": "EXECUTE stmt", "table_name": "ORDERS", "schema_name": "lakehouse_test"} Prefix指定だとWarningが出るが・・、(name指定だと出ない)
  12. データをHeatWaveにロードを確認 SQL > show table status like 'ORDERS'; +--------+-----------+---------+------------+---------+----------------+-------------+----------- ------+--------------+-----------+----------------+---------------------+-------------+----------

    --+--------------------+----------+---------------------------------------------+---------+ | Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment | +--------+-----------+---------+------------+---------+----------------+-------------+----------- ------+--------------+-----------+----------------+---------------------+-------------+---------- --+--------------------+----------+---------------------------------------------+---------+ | ORDERS | Lakehouse | 10 | Dynamic | 1500000 | 0 | 171952161 | 0 | 0 | 0 | NULL | 2025-04-16 21:39:26 | NULL | NULL | utf8mb4_0900_ai_ci | NULL | SECONDARY_ENGINE="RAPID" SECONDARY_LOAD="1" | | +--------+-----------+---------+------------+---------+----------------+-------------+----------- ------+--------------+-----------+----------------+---------------------+-------------+---------- --+--------------------+----------+---------------------------------------------+---------+ 1 row in set (0.0020 sec) DataはLoadできている。
  13. INTO OUTFILE実行 select YEAR(O_ORDERDATE) year,count(*) count from ORDERS WHERE YEAR(O_ORDERDATE)

    in ('1993', '1994', '1995') GROUP BY YEAR(O_ORDERDATE) INTO OUTFILE WITH PARAMETERS '{ "file": [ { "region": "ap-tokyo-1", "namespace": "bucket_namespace", "bucket": "heatwave-lakehouse-test", "prefix": "lakehouse_test/summary-layer/" } ] , "dialect": {"has_header": true, "format": "csv"} }';
  14. 再度 INTO OUTFILE実行 select YEAR(O_ORDERDATE) year,count(*) count from ORDERS WHERE

    YEAR(O_ORDERDATE) in ('1996', '1997', '1998') GROUP BY YEAR(O_ORDERDATE) INTO OUTFILE WITH PARAMETERS '{ "file": [ { "region": "ap-tokyo-1", "namespace": "bucket_namespace", "bucket": "heatwave-lakehouse-test", "prefix": "lakehouse_test/summary-layer/" } ] , "dialect": {"has_header": true, "format": "csv"} }';
  15. Exportし た ファイル を元に Table作成 SQL> SET @input_list = '[

    { "db_name": "lakehouse_test", "tables": [ "ORDERS_COUNT", { "table_name": "ORDERS_COUNT", "engine_attribute": { "dialect": {"format": "csv", "field_delimiter": ",", "has_header": true, "record_delimiter": "¥¥n", "is_strict_mode": false }, "file": [{"region": "ap-tokyo-1", "namespace": "bucket_namespace", "bucket": "heatwave-lakehouse-test", "prefix": "lakehouse_test/summary-layer/" }] } } ] }]'; SQL> SET @options = JSON_OBJECT('mode', 'normal'); SQL> CALL sys.heatwave_load(CAST(@input_list AS JSON), @options);
  16. テーブル作成確認 SQL > SHOW CREATE TABLE 'ORDERS_COUNT' CREATE TABLE `ORDERS_COUNT`

    ( `year` year NOT NULL, `count` mediumint unsigned NOT NULL ) ENGINE=Lakehouse DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci SECONDARY_ENGINE=RAPID /*!80021 ENGINE_ATTRIBUTE='{"file": [{"bucket": "heatwave-lakehouse-test", "prefix": "lakehouse_test/summary-layer/", "region": "ap-tokyo-1", "namespace": "bucket_namespace"}], "dialect": {"format": "csv", "has_header": true, "is_strict_mode": false, "field_delimiter": ",", "record_delimiter": "¥¥n"}}' */
  17. データ確認 SQL > select * from ORDERS_COUNT ORDER BY year;

    +------+--------+ | year | count | +------+--------+ | 1993 | 226645 | | 1994 | 227597 | | 1995 | 228637 | | 1996 | 228626 | | 1997 | 227783 | | 1998 | 133623 | +------+--------+ 6 rows in set (0.0067 sec)
  18. 余談2 Primary key • Lakehouse tableでも有効にできますが、初回ロード時しか チェックが行われないようです? CREATE TABLE `NATION_PK`

    ( `N_NATIONKEY` int NOT NULL, `N_NAME` char(25) NOT NULL, `N_REGIONKEY` int NOT NULL, `N_COMMENT` varchar(152) DEFAULT NULL, PRIMARY KEY (`N_NATIONKEY`) ) ENGINE=Lakehouse DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci SECONDARY_ENGINE=RAPID /*!80021 ENGINE_ATTRIBUTE='{"file": [{"bucket": "heatwave-lakehouse-test", "prefix": "lakehouse_test/nation/", "region": "ap- tokyo-1", "namespace": "bucket_namespace"}], "dialect": {"format": "csv", "has_header": false, "is_strict_mode": true, "field_delimiter": "|", "record_delimiter": "|¥¥n", "check_constraints": true}}'
  19. Primary key $ cat nation.tbl 26|HOGE|4|hoge hoge| 26|HOGE|4|hoge hoge| {"cmd":

    "¥"ALTER TABLE /*+ AUTOPILOT_DISABLE_CHECK */ `lakehouse_test`.`NATION_PK` SECONDARY_LOAD;¥"", "msg": "Command Failed", "error": "Duplicate entry '26' for key 'NATION_PK.PRIMARY'.", "location": "EXECUTE stmt", "table_name": "NATION_PK", "schema_name": "lakehouse_test"} • エラー • 重複ありデータで初回ロード
  20. Primary key $ cat nation.tbl.second 26|HOGE|4|hoge hoge| 26|HOGE|4|hoge hoge| •

    Indexを作るわけではないので、重複排除が必要な場合はソース 側で行う想定 $ cat nation.tbl.first 1|FIRST|4|hoge hoge| 26|HOGE|4|hoge hoge| • 重複なしで初回ロード • 2回目は重複ありでロード(これは通る)
  21. まとめ • Heatwave Lakehouseで基本的なデータ変換/加工は可能。 • INTO OUTFILEの出力先ファイル名が指定できたらなお良い。 • カラムの自動追加などが出来たらさらによい。 •

    今回の話とは関係ないがHeatWaveは従量課金では無いので費 用対効果は高いと思われる。ので、 •HeatWaveの今後に期待しております