📦aidp-aws-s3
- ソース
- GitHub で見る ↗
説明
AIDPノートブック上でAWS S3(`s3a://`)の読み書きを行います。 次のような場合に使用: ユーザーがS3、AWS S3バケット、s3a に言及している場合、またはAWSアクセスキーを保有している場合。 認証はHadoop S3Aコネクタによるアクセスキーとシークレットキーの組み合わせで行います。 また、Spark以外の管理操作(一覧取得、コピーなど)にはboto3も利用可能です。
原文を表示
Read and write AWS S3 (`s3a://`) from an AIDP notebook. Use when the user mentions S3, AWS S3 bucket, s3a, or has AWS access keys. Auth is access key + secret key via the Hadoop S3A connector. boto3 is also available for non-Spark management operations (list, copy).
ユースケース
- ✓S3またはAWS S3バケットに言及している
- ✓s3a://プロトコルでのアクセスが必要
- ✓AWSアクセスキーを保有している
本文(日本語訳)
aidp-aws-s3 — S3A コネクタ経由の AWS S3
AWS アクセスキーを使用して、AIDP Spark から s3a://<bucket>/<key> パスの読み書きを行います。
管理操作(list・copy・head)向けに boto3 パスも利用可能(オプション)。
次のような場合に使用
- AIDP が AWS S3 のデータを読み込む、またはデータを書き込む必要がある場合。
- 「S3」「s3a」「AWS bucket」というキーワードが言及されている場合。
次のような場合は使用しない
- OCI Object Storage の場合 →
aidp-object-storage - Azure ADLS Gen2 の場合 →
aidp-azure-adls
クラスター前提条件 — hadoop-aws と aws-java-sdk-bundle の両方をランタイムロードすること
AIDP の tpcds クラスターには org.apache.hadoop.fs.s3a.S3AFileSystem がプリインストールされていません(2026-04-27 実環境確認済み)。
hadoop-aws-<ver>.jar(約 1 MB)と aws-java-sdk-bundle-<ver>.jar(約 280 MB)の両方をランタイムロードする必要があります。
hadoop-aws のバージョンはクラスターの Hadoop バージョンに厳密に合わせてください
(spark._jvm.org.apache.hadoop.util.VersionInfo.getVersion() で確認可能 — Spark 3.5.0 では通常 3.3.4)。
バージョン不一致が発生すると、org.apache.hadoop.fs.s3a 内部で NoSuchMethodError が発生します。
標準的なランタイムロード + DriverManager パターンに加え、S3A では Hadoop の Configuration に対して使用するクラスローダーを明示的に指定する必要があります。
Hadoop の FileSystem.get() は JVM のスレッドコンテキストローダーではなく Configuration.getClassLoader() を使用するためです。
Spark 読み込み(S3A・ランタイムロードドライバー)
import os, urllib.request
from py4j.java_gateway import java_import
# 1. クラスターの Hadoop バージョンを確認し、hadoop-aws jar を一致させる
HADOOP_VER = spark._jvm.org.apache.hadoop.util.VersionInfo.getVersion()
print("hadoop:", HADOOP_VER) # 例: 3.3.4
JARS = {
f"/tmp/hadoop-aws-{HADOOP_VER}.jar":
f"https://repo1.maven.org/maven2/org/apache/hadoop/hadoop-aws/{HADOOP_VER}/hadoop-aws-{HADOOP_VER}.jar",
"/tmp/aws-java-sdk-bundle-1.12.262.jar":
"https://repo1.maven.org/maven2/com/amazonaws/aws-java-sdk-bundle/1.12.262/aws-java-sdk-bundle-1.12.262.jar",
}
for path, url in JARS.items():
if not os.path.exists(path):
urllib.request.urlretrieve(url, path)
# 2. 両 jar を含む URLClassLoader を構築し、Hadoop Configuration に設定する
gw = spark._sc._gateway
URLArr = gw.new_array(spark._jvm.java.net.URL, len(JARS))
for i, p in enumerate(JARS):
URLArr[i] = spark._jvm.java.io.File(p).toURI().toURL()
sysCL = spark._jvm.java.lang.ClassLoader.getSystemClassLoader()
ucl = spark._jvm.java.net.URLClassLoader(URLArr, sysCL)
hconf = spark._jsc.hadoopConfiguration()
hconf.setClassLoader(ucl) # 重要 — Hadoop の FileSystem ルックアップはこちらを使用(スレッドコンテキストではない)
# 3. S3A 認証情報とエンドポイントを設定する
hconf.set("fs.s3a.access.key", os.environ["S3_ACCESS_KEY"])
hconf.set("fs.s3a.secret.key", os.environ["S3_SECRET_KEY"])
hconf.set("fs.s3a.endpoint", "s3.amazonaws.com") # または s3.<region>.amazonaws.com
hconf.set("fs.s3a.aws.credentials.provider",
"org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider")
hconf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
# 4. エグゼキューターへ jar を配布する(ドライバーのみの登録ではクラスター読み込みに不十分)
for p in JARS:
spark._jsc.addJar(p)
# 5. 読み込み — csv/json/parquet/delta に対応
df = spark.read.option("header", "true").csv(
f"s3a://{os.environ['S3_BUCKET']}/{os.environ['S3_FILE']}"
)
df.show()
2026-04-27 実環境検証済み: 本パターンにより s3a://test-data-sep3-2025/csv/sample.csv から 2 行を取得確認。
boto3 フォールバック(管理操作用・データプレーンではない)
import boto3, os
s3 = boto3.client(
"s3",
aws_access_key_id = os.environ["S3_ACCESS_KEY"],
aws_secret_access_key = os.environ["S3_SECRET_KEY"],
region_name = os.environ.get("S3_REGION", "us-east-1"),
)
resp = s3.list_objects_v2(Bucket=os.environ["S3_BUCKET"], Prefix="")
for obj in resp.get("Contents", []):
print(obj["Key"])
注意点
-
s3a://(Hadoop ドライバー)を使用し、s3://やs3n://は使わないこと。 後者の 2 つは非推奨であり、クラスターに存在しない場合があります。 -
aws-java-sdk-bundleのバージョンずれに注意 —hadoop-awsがビルドされた時点のバージョンに固定してください。 ラボ環境のクラスターではこの jar のインストールが必要なことが多く、 バージョン不一致の症状は list/read 時にorg.apache.hadoop.fs.s3a内部でNoSuchMethodErrorが発生することです。 -
ランタイムロード後は
Configuration.setClassLoaderが必須 — Hadoop のFileSystem.get()はConfiguration.getClassByName()を呼び出し、 JVM スレッドコンテキストではなく Configuration のクラスローダーを使用します。hconf.setClassLoader(ucl)を設定しないと、jar を登録済みであってもClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not foundが発生します。 -
シークレットは環境変数のみで管理すること。 ノートブックにキーをハードコードしないでください。
.env/ OCI Vault から取得してください。 -
リージョンについて — デフォルト以外のリージョンでは
boto3.client('s3', region_name=...)の指定が必要です。 Spark パスではバケットのリージョンが自動検出されますが、 us-east-1 以外で listing が失敗する場合はfs.s3a.endpoint=s3.<region>.amazonaws.comの設定が必要になることがあります。 -
boto3は AIDP クラスターにプリインストールされていません。 PyPI ミラーも通常到達不能です。 管理操作(list・copy・head)はクラスターではなくローカルから実行してください。 -
エグレスコストとレイテンシ — AIDP からの S3 読み込みはクラウド間通信になります。 大規模な ETL の場合は、一度 OCI Object Storage にコピーしてからローカルで読み込むことを推奨します。
参考資料
原文(English)を表示
aidp-aws-s3 — AWS S3 via the S3A connector
Read or write s3a://<bucket>/<key> paths from AIDP Spark using AWS access keys. Optional boto3 path for management operations (list, copy, head).
When to use
- AIDP needs to consume or land data in AWS S3.
- Mentioned: "S3", "s3a", "AWS bucket".
When NOT to use
- For OCI Object Storage →
aidp-object-storage. - For Azure ADLS Gen2 →
aidp-azure-adls.
Cluster prerequisite — runtime-load BOTH hadoop-aws and aws-java-sdk-bundle
The AIDP tpcds cluster does NOT have org.apache.hadoop.fs.s3a.S3AFileSystem pre-installed (verified live 2026-04-27). Both hadoop-aws-<ver>.jar (~1 MB) AND aws-java-sdk-bundle-<ver>.jar (~280 MB) must be runtime-loaded. Match hadoop-aws to the cluster's exact Hadoop version (spark._jvm.org.apache.hadoop.util.VersionInfo.getVersion() — typically 3.3.4 for Spark 3.5.0). Mismatch produces NoSuchMethodError deep in org.apache.hadoop.fs.s3a.
Beyond the standard runtime-load + DriverManager pattern, S3A also requires telling Hadoop's Configuration which classloader to use — Hadoop's FileSystem.get() uses Configuration.getClassLoader(), not the JVM thread context loader.
Spark read (S3A, runtime-loaded driver)
import os, urllib.request
from py4j.java_gateway import java_import
# 1. Confirm cluster's Hadoop version + match hadoop-aws jar
HADOOP_VER = spark._jvm.org.apache.hadoop.util.VersionInfo.getVersion()
print("hadoop:", HADOOP_VER) # e.g. 3.3.4
JARS = {
f"/tmp/hadoop-aws-{HADOOP_VER}.jar":
f"https://repo1.maven.org/maven2/org/apache/hadoop/hadoop-aws/{HADOOP_VER}/hadoop-aws-{HADOOP_VER}.jar",
"/tmp/aws-java-sdk-bundle-1.12.262.jar":
"https://repo1.maven.org/maven2/com/amazonaws/aws-java-sdk-bundle/1.12.262/aws-java-sdk-bundle-1.12.262.jar",
}
for path, url in JARS.items():
if not os.path.exists(path):
urllib.request.urlretrieve(url, path)
# 2. Build URLClassLoader covering BOTH jars + set on Hadoop Configuration
gw = spark._sc._gateway
URLArr = gw.new_array(spark._jvm.java.net.URL, len(JARS))
for i, p in enumerate(JARS):
URLArr[i] = spark._jvm.java.io.File(p).toURI().toURL()
sysCL = spark._jvm.java.lang.ClassLoader.getSystemClassLoader()
ucl = spark._jvm.java.net.URLClassLoader(URLArr, sysCL)
hconf = spark._jsc.hadoopConfiguration()
hconf.setClassLoader(ucl) # CRITICAL — Hadoop FileSystem lookup uses this, not the thread context
# 3. Configure S3A credentials + endpoint
hconf.set("fs.s3a.access.key", os.environ["S3_ACCESS_KEY"])
hconf.set("fs.s3a.secret.key", os.environ["S3_SECRET_KEY"])
hconf.set("fs.s3a.endpoint", "s3.amazonaws.com") # or s3.<region>.amazonaws.com
hconf.set("fs.s3a.aws.credentials.provider",
"org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider")
hconf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
# 4. Distribute the jars to executors (driver-only registration won't work for cluster reads)
for p in JARS:
spark._jsc.addJar(p)
# 5. Read — works for csv/json/parquet/delta
df = spark.read.option("header", "true").csv(
f"s3a://{os.environ['S3_BUCKET']}/{os.environ['S3_FILE']}"
)
df.show()
Live-validated 2026-04-27: 2 rows from s3a://test-data-sep3-2025/csv/sample.csv via this pattern.
boto3 fallback (management ops, not data plane)
import boto3, os
s3 = boto3.client(
"s3",
aws_access_key_id = os.environ["S3_ACCESS_KEY"],
aws_secret_access_key = os.environ["S3_SECRET_KEY"],
region_name = os.environ.get("S3_REGION", "us-east-1"),
)
resp = s3.list_objects_v2(Bucket=os.environ["S3_BUCKET"], Prefix="")
for obj in resp.get("Contents", []):
print(obj["Key"])
Gotchas
- Use
s3a://(the Hadoop driver), nots3://ors3n://. The latter two are deprecated and may not be present in the cluster. aws-java-sdk-bundleversion drift — pin to the versionhadoop-awswas built against. Lab clusters often need this jar installed; the symptom of mismatch isNoSuchMethodErrordeep inorg.apache.hadoop.fs.s3awhen listing/reading.Configuration.setClassLoaderis required after runtime-load — Hadoop'sFileSystem.get()callsConfiguration.getClassByName()which uses the Configuration's classloader (not the JVM thread context). Withouthconf.setClassLoader(ucl), you getClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not foundeven though you just registered the jar.- Secrets in env vars only. Never hard-code keys in notebooks. Source from
.env/OCI Vault. - Region —
boto3.client('s3', region_name=...)is required for non-default regions; for the Spark path the bucket region is auto-discovered, but you may needfs.s3a.endpoint=s3.<region>.amazonaws.comfor non-us-east-1 if listings fail. boto3is NOT pre-installed on AIDP cluster and PyPI mirror is typically unreachable. For management ops (list, copy, head), drive from local rather than cluster.- Egress cost & latency — S3 reads from AIDP cross-cloud. For heavy ETL, copy to OCI Object Storage once and read locally.
References
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。