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

Apache Hudi-Based Data Lake Supporting Record-Level Deletions

Apache Hudi-Based Data Lake Supporting Record-Level Deletions

Open Table Format Study Group Tokyo Meetup #1
https://otfsg-tokyo.connpass.com/event/296440/

Koya Nagamine

October 12, 2023
Tweet

Other Decks in Technology

Transcript

  1.  従来のデータレイク IoT REST DB Machine Learning BI Report 追加

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

    利⽤ Consumer 削除 更新 例: Change Data Capture (CDC) 例: プライバシー規制 (GDPRなど) ※ ※ ※ ※ ※ ※ ※ ※ Designed by Freepik and distributed by Flaticon
  3.  データレイク上のデータ削除・更新の課題 1. レコード単位の処理が不得意 2. ACIDトランザクションが⾮対応 列指向フォーマットでの保存が基本 → 特定⾏の探索・削除・更新のコストが⼤きい ・書き込み処理途中の読み込み

    ・複数処理の同時書き込み 下記発⽣時の整合性を保証できない → 分析環境として安⼼して利⽤できない ※ Apache Parquet及びApache ORC は、The Apache Software Foundation の⽶国およびその他の国における登録商標または商標です。
  4.  Apache Hudi • 2016年にUber社が開発し、2017年にOSS化 • 主要なOpen Table Formatの中で最も早い •

    機能 • レコード(⾏)単位の更新・削除 • ACIDトランザクション • ストリーミングなデータ取り込み ※ Apache Hudiは、The Apache Software Foundation の⽶国およびその他の国における登録商標または商標です。
  5.  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) … … … …
  6.  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)により⾼速化可能
  7.  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処理の場合に利⽤
  8.  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ॲཧʹΑΒͣ ϑΝΠϧ୯Ґͷߋ৽Λαϙʔτ
  9.  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を指定した例
  10.  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
  11. 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
  12.  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
  13.  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が保証されない」点に注意
  14.  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
  15.  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処理中のプロセスの存在に関わらず削除されるため注意
  16.  Rollback Commit処理前に前回不完全に終わったデータが無いか確認する Commit 1 Creating File v2 Commit 2

    Creating File v2 Failed Rollback Time Commit1 関連の実データ とTimelineの両⽅を削除 TimelineにInflightステータスあれば削除する ※ Multi Writeの場合はHeartbeatも確認
  17.  まとめ レコード(⾏)単位の更新・削除 • Two Table Types: ファイル単位の更新 • Index:

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