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

Apache Icebergテーブル同時書き込み競合解決の仕組みと注意点

bering
February 22, 2025
77

Apache Icebergテーブル同時書き込み競合解決の仕組みと注意点

Apache Iceberg Japan Meetup #1での発表資料です。
https://iceberg.connpass.com/event/342709/

Icebergテーブルは複数のトランザクションが同時に実行された場合でも整合性を確保できます。これは強力な特徴ですが、それがどのように実現されているかはあまり知られていません。本資料では、そのメカニズムを解説しつつ、実践的なデータパイプラインを構築する際の注意点を紹介しています。

bering

February 22, 2025
Tweet

Transcript

  1. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. © 2025, Amazon Web Services, Inc. or its affiliates. All rights reserved. Iceberg テーブル 同時書き込み 競合解決の仕組みと注意点 ⽦⽥ 宗太郎 (Sotaro Hikita) Solutions Architect アマゾン ウェブ サービス ジャパン合同会社
  2. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. ⽦⽥ 宗太郎 (Sotaro Hikita) 2 アマゾン ウェブ サービス ジャパン ソリューションアーキテクト (アナリティクス) ⼤規模データの効率的な処理や、データ活⽤基盤に取り組むお客様を⽀援しています X(旧 Twitter) : @_Bassari 個⼈ブログ: https://bering.hatenadiary.com/ 趣味: ビッグデータに関わる OSS, 特に Apache Iceberg に関する調査、発信、貢献 Open Table Format に関するPodcast「OTF Talk」参加 https://podcasters.spotify.com/pod/show/otftalk/episodes/10-Iceberg-e2o4leo
  3. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 本セッションのねらい 3 想定聴講者 • Iceberg の ACID 特性の詳細に興味がある • Iceberg の実践的な利⽤、 特に並列書き込みを伴うデータパイプラインの設計に関⼼がある • Iceberg の基本的な機能と仕組みを把握している • 基本を知りたい⼈向け︓https://bering.hatenadiary.com/entry/2023/09/24/175953 ゴール • Iceberg の同時書き込み制御の仕組みを整理 • 並列書き込みを⾏うデータパイプラインの 設計時に意識すべきポイントを紹介 Iceberg の整合性メカニズムを深く理解し、最適な設計のためのヒントを探る
  4. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. Iceberg の同時実⾏制御機能 4 書き込み • トランザクションごとに 「Serializable」 (デフォルト)と「Snapshot」を選択 • Serializable ︓各トランザクションの逐次実⾏と同様の結果を保証 • Snapshot ︓ ⼀部のケースで性能に優れる⼀⽅で、 Write Skew (データ不整合)が発⽣し得る。採⽤時は慎重な検討が必要 読み取り • 書き込み時の分離レベルに関わらず、⼀貫したスナップショットが参照される • 他のトランザクションによる書き込み中のデータが参照されることはない Iceberg テーブル仕様に基づき、各クエリエンジンが同時実⾏制御を実装 https://iceberg.apache.org/javadoc/latest/org/apache/iceberg/Isolatio nLevel.html
  5. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. Iceberg の同時実⾏制御機能 5 書き込み • トランザクションごとに 「Serializable」 (デフォルト)と「Snapshot」を選択 • Serializable ︓各トランザクションの逐次実⾏と同様の結果を保証 • Snapshot ︓ ⼀部のケースで性能に優れる⼀⽅で、 Write Skew (データ不整合)が発⽣し得る。採⽤時は慎重な検討が必要 読み取り • 書き込み時の分離レベルに関わらず、⼀貫したスナップショットが参照される • 他のトランザクションによる書き込み中のデータが参照されることはない Iceberg テーブル仕様に基づき、各クエリエンジンが同時実⾏制御を実装 *トランザクションは原則テーブル単位であり、複数のテーブルを跨いだ分離は保証しない * レコードの⼀意性を保証する仕組みはない * 実装のベースとなる Java API ライブラリは Iceberg プロジェクトが提供しているが、 詳細な挙動は各クエリエンジンの仕様/実装に依存する 注意
  6. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 同時実⾏制御に関わる テーブル仕様内の記述 6 https://iceberg.apache.org/spec/
  7. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. Iceberg テーブルのアーキテクチャ 7 Manifest list Manifest File Manifest File Manifest File Data Files Data Files Data Files Metadata layer Manifest list Iceberg catalog Data layer db1.table1 metadata pointer Metadata file s0 s1 Metadata file s0 • Iceberg カタログ • 最新のメタデータファイル (=テーブルの状態)を記録 • テーブル更新時は metadata file の場所を アトミックに更新する機能を備える • メタデータレイヤー • メタデータファイルを元にツリー構造を辿ること で、歴代のスキーマやスナップショット履歴など への効率的なアクセスを提供する • データレイヤー • テーブルの実レコード、 削除ファイル(Merge on Read ⽤)を保持 同時実⾏制御の観点では、カタログとメタデータファイルの関係が特に重要
  8. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 8 *Apache Spark での実装を元に記載 *図を簡略化するため、テーブルスキャン時のカタログアクセスは省略している 更新トランザクションの流れ 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ
  9. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 9 *Apache Spark での実装を元に記載 *図を簡略化するため、テーブルスキャン時のカタログアクセスは省略している 更新トランザクションの流れ 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ
  10. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 10 更新トランザクションの流れ 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ *Apache Spark での実装を元に記載 *図を簡略化するため、テーブルスキャン時のカタログアクセスは省略している
  11. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 11 更新トランザクションの流れ 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ *Apache Spark での実装を元に記載 *図を簡略化するため、テーブルスキャン時のカタログアクセスは省略している
  12. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 12 更新トランザクションの流れ 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ *Apache Spark での実装を元に記載 *図を簡略化するため、テーブルスキャン時のカタログアクセスは省略している
  13. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 13 更新トランザクションの流れ 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ *Apache Spark での実装を元に記載 *図を簡略化するため、テーブルスキャン時のカタログアクセスは省略している
  14. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 14 更新トランザクションの流れ 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ *Apache Spark での実装を元に記載 *図を簡略化するため、テーブルスキャン時のカタログアクセスは省略している
  15. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 15 競合が発⽣するポイント 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ
  16. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 16 競合が発⽣するポイント 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (ライブラリによる⾃動リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ
  17. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 17 カタログへのコミット競合 (1/2) メタデータファイルコミット時の流れ • カタログがクライアントのコミットを受け付ける際、 更新内容がテーブルの最新断⾯を基にしていること をチェックする • コミットのリクエストが古い断⾯を基にしていた 場合、コミットを失敗させる • コミット失敗時、クライアントはテーブルの パラメータ設定に基づきリトライを実施する • リトライ時は更新の基とするメタデータの確定(3) から再開する • リトライにも失敗した場合︓ CommitFailedException
  18. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 18 カタログへのコミットリトライに関わるパラメータ ユースケースに応じて適切な設定が必要 https://iceberg.apache.org/docs/latest/configuration/#table- behavior-properties
  19. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 19 カタログへのコミット競合 (2/2) • テーブルスキャン(1)時のメタデータと、 更新の基となるメタデータ(3)は同じである必要はない • テーブルスキャン(1)後に最新メタデータが変わっても、 データ競合チェック(後述)が通過する限りにおいて、 3で確定させたメタデータを基にコミットが可能
  20. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 20 競合が発⽣するポイント 1. テーブルの最新の状態を読み取る (テーブルの既存データに依存しないINSERTなどの オペレーションでは不要) 2. 更新内容を確定し、データレイヤーのファイルを作成 3. 更新の基になるテーブルのバージョン(メタデータ) を確定 4. 2の更新内容と、最新のテーブルデータとの間で isolation の観点で整合することを確認する 1. 不整合を検出した場合はトランザクションをアボート (リトライ不可) 5. メタデータレイヤのファイルを作成 6. メタデータファイルをカタログにコミット 1. 成功した場合はトランザクション成功 2. 失敗した場合はテーブル設定に基づき 3 からリトライ
  21. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 更新データの競合 (1/2) 21 • 更新の基とするテーブルの断⾯を確定後、 更新予定のデータと、最新のテーブルデータが isolation の観点で整合することを確認する • チェック内容は書き込み時の isolation level の設定で変化する • 競合のチェックはメタデータを基に実施する (実データは読まない) • 不整合を検出した場合、トランザクションは アボートする︓ ValidationException
  22. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 更新データの競合 (2/2) 22 • 更新データの競合はライブラリによる ⾃動リトライができない • 更新の基とする断⾯の確定(3)からの リトライは意味がない • 更新内容の確定(1 or 2)からのリトライは トランザクションの前提が変わるため データの整合性を破壊する可能性がある • 実際にはリトライして問題ないケースもあ るが、ケースバイケースで判断が必要 • →トランザクションをトリガーしたアプリ側で 適切な例外処理が必要 典型的な競合シナリオ︓ストリーム書き込みの UPDATE / DELETE とコンパクションの競合
  23. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 23 データ競合エラーの簡易的なハンドリング例
  24. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 代表的な書き込みパターン別の競合チェック内容 24 書き込みパターン チェック内容 AppendFiles (INSERT) ファイルの単純な追加 • なし • Iceberg は主キーを持たないため、同じ⾏を重複して挿⼊するかどうかはチェックし ない OverwriteFiles (Copy-on-Write による UPDATE / DELETE) 削除レコードを含むファイルを論理削除 し、新しいファイルに置き換え • データファイルに対応する削除ファイルが追加されていないことを検証 • 削除対象として指定したファイルパスがマニフェスト上で⾒つからない場合に処理 を失敗とする • 同じ更新範囲に合致する新規データファイルが追加されていないことを検証(分離レ ベルがSerializableの場合のみ) RowDelta (Merge-on-Read による UPDATE / DELETE) 更新対象の⾏を書き込み、削除ファイル を登録 • データファイルに対応する削除ファイルが追加されていないことを検証 • 参照対象となるデータファイルが実際にスナップショット上に存在することを検証 • 削除対象となるデータファイルがすでに Overwrite あるいは Delete 操作によって論理 削除済みではないかを検証 • 同じ更新範囲に合致する新規データファイルが追加されていないことを検証(分離レ ベルがSerializableの場合のみ) RewriteFiles (コンパクション) • 削除対象として指定したファイルパスがマニフェスト上で⾒つからない場合に 処理を失敗とする • 最新のスナップショットに新規の削除ファイルが追加されていないことを検証
  25. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. 代表的な書き込みパターン別の競合チェック内容 25 書き込みパターン チェック内容 AppendFiles (INSERT) ファイルの単純な追加 • なし • Iceberg は主キーを持たないため、同じ⾏を重複して挿⼊するかどうかはチェックし ない OverwriteFiles (Copy-on-Write による UPDATE / DELETE) 削除レコードを含むファイルを論理削除 し、新しいファイルに置き換え • データファイルに対応する削除ファイルが追加されていないことを検証 • 削除対象として指定したファイルパスがマニフェスト上で⾒つからない場合に処理 を失敗とする • 同じ更新範囲に合致する新規データファイルが追加されていないことを検証 (分離レベルがSerializableの場合のみ) RowDelta (Merge-on-Read による UPDATE / DELETE) 更新対象の⾏を書き込み、削除ファイル を登録 • データファイルに対応する削除ファイルが追加されていないことを検証 • 参照対象となるデータファイルが実際にスナップショット上に存在することを検証 • 削除対象となるデータファイルがすでに Overwrite あるいは Delete 操作によって論理 削除済みではないかを検証 • 同じ更新範囲に合致する新規データファイルが追加されていないことを検証 (分離レベルがSerializableの場合のみ) RewriteFiles (コンパクション) • 削除対象として指定したファイルパスがマニフェスト上で⾒つからない場合に 処理を失敗とする • 最新のスナップショットに新規の削除ファイルが追加されていないことを検証 INSERT は常にデータ競合しない トランザクション分離レベルによって チェック内容が異なる これらのうち、INSERT 以外の書き込みは 全て競合の可能性がある
  26. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. データ競合フィルタ 26 • 「UPDATE ... WHERE name = ‘Alice'」のように⾏フィルタがある場合、 その条件とパーティション情報やカラム統計を付き合わせることで、 「別のライターが追加したファイルが本当に⾃分の更新対象範囲と重複するか」 を判定し、不要な競合を回避する → 更新範囲を適切に絞り込むことで、競合を回避できる可能性がある 例︓コンパクション / rewrite_data_files プロシージャ トランザクション間の更新範囲の重複を検査し、不要な競合検出を避ける
  27. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. まとめ 27 • Iceberg は書き込み時にクライアントがカタログと連携して競合を検査する • Iceberg の同時書き込み時の競合パターンは 2 種類ある • カタログへのコミット競合: リトライ可能 テーブルプロパティの適切な設定が重要 • 更新データの競合: 競合時はトランザクションが失敗する前提で、 呼び出し側での適切なハンドリングが必要になる • Icebergの ACID 特性は強⼒だが、 ⼤量・⾼頻度の同時書き込みに特化しているわけではない • 競合検知・解決機能が⼗分に機能するユースケースを⾒極めた設計・運⽤が重要
  28. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. Appendix 28 • Apache Icebergにおける同時実⾏制御の仕組みと注意点(参考ブログ) • https://bering.hatenadiary.com/entry/2025/01/18/234339 • Spark での書き込みトランザクション実装の例 • https://github.com/apache/iceberg/blob/bed7c33174ca97809fc4a9657d39b1d09ae38b72/spark/v3.5 /spark/src/main/java/org/apache/iceberg/spark/source/SparkWrite.java#L382 • データ競合チェックのテストコード • https://github.com/apache/iceberg/blob/abb47830e7df7dc2ae93c74b0ad97f06cdd37aad/spark/v3.5/ spark-extensions/src/test/java/org/apache/iceberg/spark/extensions/TestConflictValidation.java#L40 • https://github.com/apache/iceberg/blob/dc1e0b25ad1be42a431f4991381b16bf572a459e/core/src/te st/java/org/apache/iceberg/TestTransaction.java#L221
  29. © 2025, Amazon Web Services, Inc. or its affiliates. All

    rights reserved. Thank you! © 2025, Amazon Web Services, Inc. or its affiliates. All rights reserved.