はじめに
Amazon EMR 6.15.0 上で Spark ジョブを実行中、S3 Tables Catalog(Iceberg)を使って S3 上のテーブルデータを処理したところ、以下のような Avro 関連エラーが発生しました:
java.lang.NoSuchMethodError: 'org.apache.avro.LogicalTypes$TimestampNanos org.apache.avro.LogicalTypes.timestampNanos()'
自分は今まで依存関係や環境周りのエラーについては先輩に任せっきりだったため、
自分でもできるようにならねばと思い、今回悪戦苦闘しました。
次回も同じところで躓かないよう備忘録です!
前提
今回追加したいのは、S3 Tables Catalog(Iceberg)を使用するのに必要なライブラリ
s3-tables-catalog-for-iceberg
そのため、関連するライブラリのバージョンは以下にする必要がありました。
今回の手順はここにたどり着くまでの過程を記載してます。
iceberg-core 1.6.1
→実際には、 iceberg-spark-runtime-3.4_2.12を1.6.1で指定iceberg-aws 1.6.1
EMR + Iceberg の依存関係を調べる方法(サンプル)
EMR 上で Spark + Iceberg を使う場合、依存関係のバージョンを把握することが重要です。
今回は Maven Repository と EMR リリースノート を使って確認しました。
※他にも調べ方があれば教えてほしいです!
1. Maven Repository でバージョンを確認
Maven Repository では各ライブラリの 最新バージョンや依存関係 を確認できます。
例: Iceberg
- https://mvnrepository.com にアクセス
- 検索ボックスに
iceberg-spark-runtime
と入力 - 使用している Spark/Scala バージョンに合ったアーティファクトを選択
- バージョン一覧や依存関係を確認
ポイント
- Iceberg は Spark と Scala のバージョンによって JAR 名が変わる
例:iceberg-spark-runtime-3.4_2.12
は Spark 3.4 + Scala 2.12 用
※このspark、scalaのバージョンについては、EMRリリースノート参照
2. EMR リリースノートで標準ライブラリを確認
EMR のバージョンごとに標準で搭載されているライブラリが存在するので、
自分が使用したいバージョンと競合しないか確認が必要。
手順
-
AWS ドキュメントで Amazon EMR Release Notes を開く
-
使用する EMR リリース(例: 6.15.0)の 6.15.0 アプリケーションバージョン セクションを確認
ポイント
- 標準搭載のバージョンより新しいライブラリを使う場合は、fat JAR を作って extraClassPath で先に読むなどの対策が必要
参考:https://qiita.com/drafts/24a5bd6c7f3f8413eb12/edit
まとめ
- Maven Repository で 自分が使いたいバージョン を確認
- EMR リリースノートで 標準搭載バージョン を確認
- バージョン差がある場合は、fat JAR + extraClassPath で上書きして使う
補足
iceberg-core
:Icebergの基本API ※↓に含まれてるため、不要
iceberg-spark-runtime-3.4_2.12
:spark上でicebergを使うためのもの ※必須
iceberg-aws
:S3連携などを担当 ※AWS上で使う場合はあった方がよい
💡 Tips:
- Maven の依存関係を調べるには
mvn dependency:tree
も便利 - EMR 標準 JAR を優先的に読み込ませないために、Spark の
--conf spark.driver.extraClassPath
も活用