claude-skills/

Anthropic公式スキル・プラグインの日本語ディレクトリ

last sync 22h ago
スキルOfficialdevelopment

📦aidp-aws-s3

説明

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」というキーワードが言及されている場合。

次のような場合は使用しない

クラスター前提条件 — hadoop-awsaws-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

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), not s3:// or s3n://. The latter two are deprecated and may not be present in the cluster.
  • aws-java-sdk-bundle version drift — pin to the version hadoop-aws was built against. Lab clusters often need this jar installed; the symptom of mismatch is NoSuchMethodError deep in org.apache.hadoop.fs.s3a when listing/reading.
  • Configuration.setClassLoader is required after runtime-load — Hadoop's FileSystem.get() calls Configuration.getClassByName() which uses the Configuration's classloader (not the JVM thread context). Without hconf.setClassLoader(ucl), you get ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found even though you just registered the jar.
  • Secrets in env vars only. Never hard-code keys in notebooks. Source from .env/OCI Vault.
  • Regionboto3.client('s3', region_name=...) is required for non-default regions; for the Spark path the bucket region is auto-discovered, but you may need fs.s3a.endpoint=s3.<region>.amazonaws.com for non-us-east-1 if listings fail.
  • boto3 is 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 による自動翻訳です。