Slide 1

Slide 1 text

Apache Hudi-Based Data Lake Supporting Record-Level Deletions Apache Hudiを用いたレコード単位で 削除可能なデータレイク ௕็ ᔨ໻ ,PZB /BHBNJOF

Slide 2

Slide 2 text

従来のデータレイク IoT REST DB Machine Learning BI Report 追加 利⽤ ⼤量の多種多様なデータを追加し、それらのデータを分析に利⽤できる環境 ※ Designed by Freepik and distributed by Flaticon ※ ※ ※ ※ ※ ※

Slide 3

Slide 3 text

近年のデータレイク IoT REST DB Machine Learning BI Report 追加 利⽤ Consumer 削除 更新 例: Change Data Capture (CDC) 例: プライバシー規制 (GDPRなど) ※ ※ ※ ※ ※ ※ ※ ※ Designed by Freepik and distributed by Flaticon

Slide 4

Slide 4 text

データレイク上のデータ削除・更新の課題 1. レコード単位の処理が不得意 2. ACIDトランザクションが⾮対応 列指向フォーマットでの保存が基本 → 特定⾏の探索・削除・更新のコストが⼤きい ・書き込み処理途中の読み込み ・複数処理の同時書き込み 下記発⽣時の整合性を保証できない → 分析環境として安⼼して利⽤できない ※ Apache Parquet及びApache ORC は、The Apache Software Foundation の⽶国およびその他の国における登録商標または商標です。

Slide 5

Slide 5 text

Apache Hudi • 2016年にUber社が開発し、2017年にOSS化 • 主要なOpen Table Formatの中で最も早い • 機能 • レコード(⾏)単位の更新・削除 • ACIDトランザクション • ストリーミングなデータ取り込み ※ Apache Hudiは、The Apache Software Foundation の⽶国およびその他の国における登録商標または商標です。

Slide 6

Slide 6 text

レコード(⾏)単位の更新・削除

Slide 7

Slide 7 text

1: Two Table Types 共通:データの部分更新・削除を可能にするテーブル 例: 100GBのテーブルの内100MBのファイルのみ更新したい 通常のデータレイク Apache Hudi版データレイク File 1 (100MB) File 2 (100MB) File 1000 (100MB) テーブル全体を更新 (100GB) 参考: https://www.onehouse.ai/blog/comparing-apache-hudis-mor-and-cow-tables-use-cases-from-uber-and-shopee File 1 (100MB) File 2 (100MB) File 1000 (100MB) File 1 (100MB) File 2 (100MB) File 1000 (100MB) 1ファイルのみ更新 (0.1GB) File 1 (100MB) File 2 (100MB) File 1000 (100MB) … … … …

Slide 8

Slide 8 text

1: Two Table Types Merge-On-Read (MOR): Writeの処理コストを下げるためのType 現在 Write処理後 Base File v1 Base File v1 Delta Log File 1 Compaction処理後 Data File A v1 Base File v2 主にWriterがStream処理の場合に利⽤ Writer1 Reader Delta Log File 2 Writer2 • Write処理は差分情報の追加のみで良いため低負荷 • Read処理は複数ファイルをMergeが必要なため⾼負荷 ※ Data Fileのみを参照するクエリタイプ(Read Optimized Queries)により⾼速化可能

Slide 9

Slide 9 text

1: Two Table Types Copy-On-Write (COW): Readの処理コストを下げるためのType 現在 Write処理後 Base File v1 Data File A v1 Base File v2 • Write処理時に新たにBase Fileを作成する • 変更のないレコードはCopyするのみ • Read処理はBase Fileのみの参照で良いため低負荷 主にWriterがBatch処理の場合に利⽤

Slide 10

Slide 10 text

1: Two Table Types Copy-On-Write (COW): Readの処理コストを下げるためのType 現在 Write処理後 Base File v1 Data File A v1 Base File v2 • Write処理時に新たにBase Fileを作成する • 変更のないレコードはCopyするのみ • Read処理はBase Fileのみの参照で良いため低負荷 主にWriterがBatch処理の場合に利⽤ "QBDIF)VEJ͸4USFBNॲཧɾ#BUDIॲཧʹΑΒͣ ϑΝΠϧ୯Ґͷߋ৽Λαϙʔτ

Slide 11

Slide 11 text

2: Index File A Hoodie Key Col A Col B 001 a b 002 A B File B Hoodie Key Col A Col B 003 a b 004 A B Table Metadata File A → Bloom Filter A File B → Bloom Filter B ... WHERE HoodieKey = ʻ002ʼ Bloom Filter A is True Bloom Filter B is False Request to search files プライマリーキー(Hoodie Key)とファイルのマッピング 各レコードを格納するファイルを⾼速に探索可能に ※ この図はIndex TypeにBLOOMを指定した例

Slide 12

Slide 12 text

ACIDトランザクション

Slide 13

Slide 13 text

3: Timeline テーブルに実⾏された全てのアクションをイベントログとして保存 データストレージ上に[timestamp.action.state]の形式で保存 action • commit, delta_commit, rollback, ... state • requested: 実⾏予定 • inflight: 実⾏開始 ※ commit時はaction=ʻʼ • completed: 完了 (state=ʻʼ) ❯ aws s3 ls ${basepath}/.hoodie | sort –n 2023-10-07 06:09:27 0 20231006210904517.commit.requested 2023-10-07 06:10:25 124282 20231006210904517.inflight 2023-10-07 06:11:04 163034 20231006210904517.commit 2023-10-07 06:37:00 1225 20231006213659249.rollback.requested 2023-10-07 06:37:01 0 20231006213659249.rollback.inflight 2023-10-07 06:37:05 1408 20231006213659249.rollback 2023-10-07 06:37:06 0 20231006213646555.commit.requested 2023-10-07 06:37:56 109837 20231006213646555.inflight 2023-10-07 06:38:27 144093 20231006213646555.commit

Slide 14

Slide 14 text

3: Timeline Commit時に各ファイルグループのpathが記録される → Commitされないファイルは利⽤されない ❯ aws s3 cp ${basepath}hoodie/20231006210904517.commit - | jq '.partitionToWriteStats."yyyymmdd=20230902"[:2][] | {fileId, path}' { "fileId": "fdc8237b-1540-4443-9d92-4d9d961d34bb-0", "path": "yyyymmdd=20230902/fdc8237b-1540-4443-9d92-4d9d961d34bb-0_0-39-21451_20231006210904517.parquet" } { "fileId": "6c2b937b-03a1-469b-978d-1f1b5af7c75a-0", "path": "yyyymmdd=20230902/6c2b937b-03a1-469b-978d-1f1b5af7c75a-0_1-39-21342_20231006210904517.parquet" } ※ ファイルグループ:複数バージョンのファイルを束ねる集合 Delta Log File 1 Base File v2 File Group A File Group B Base File v3

Slide 15

Slide 15 text

4: Concurrency Control Single Writer Mode Multi Version Concurrency Control (MVCC)によってACIDを保証 ただしテーブル毎にWriterが⼀つ以下であることはクライアント側で担保が必要 Reader 1 Writer Reader 2 Reading v1 File Reading v1 File Creating File v2 Reading v2 File Table Version Version 1 Version 2 File Group v1 File Group v2

Slide 16

Slide 16 text

4: Concurrency Control Multi Writer Mode (異なるファイルグループを更新する場合) Writer 1 Writer 2 Creating File A v2 Creating File B v2 Table Version Version 1 File Group A v1 File Group B v1 Version 2 Version 3 File Group B v1 File Group A v2 File Group A v2 File Group B v2 楽観的並⾏制御を採⽤することで 他のWriterの処理に⼲渉することなくCommit可能 ※ 「Insertの⼀意性が保証がされない」・「ReadのSerializabilityが保証されない」点に注意

Slide 17

Slide 17 text

4: Concurrency Control Multi Writer Mode (同⼀ファイルグループを更新する場合) Writer 1 Writer 2 Creating Filev2 Creating File v3 Table Version Version 1 File Group v1 Version 2 File Group v2 Writer 3 Creating File v3 Waiting… External Lock Provider (Like Zookeeper) Locking Failed Heartbeat Waiting… Locking Locking

Slide 18

Slide 18 text

完全に削除するには?

Slide 19

Slide 19 text

Cleaning Base File v1 Base File v2 Base File vN Cleaner Hudi Table … Writer Delete records 実際は ファイル追加 Remove old files 3つのポリシーから選択可 • KEEP_LATEST_COMMITS • KEEP_LATEST_FILE_VERSIONS • KEEP_LATEST_BY_HOURS 古いバージョンのファイルを削除することでレコードを完全に削除 Cleaning処理はCommitの度に⾃動かつ⾮同期に実⾏することも可能 ※ Read処理中のプロセスの存在に関わらず削除されるため注意

Slide 20

Slide 20 text

Rollback Commit処理前に前回不完全に終わったデータが無いか確認する Commit 1 Creating File v2 Commit 2 Creating File v2 Failed Rollback Time Commit1 関連の実データ とTimelineの両⽅を削除 TimelineにInflightステータスあれば削除する ※ Multi Writeの場合はHeartbeatも確認

Slide 21

Slide 21 text

まとめ レコード(⾏)単位の更新・削除 • Two Table Types: ファイル単位の更新 • Index: ⾼速なレコード探索 ACIDトランザクション • Timeline: イベントログを保存 • Currency Control: MVCCとExternal Lock Provider 完全な削除 • Cleaning: 旧バージョンのファイル削除 • Rollback: 異常終了した処理途中のファイル削除