web-dev-qa-db-ja.com

Spark-scala:読み取る前にS3ディレクトリが存在するかどうかを確認します

S3ディレクトリが存在するかどうかを読み取る前に確認する方法は?

ここで与えられているように、私はこれを試していました http://bigdatatech.taleia.software/2015/12/21/check-if-exists-a-Amazon-s3-path-from-Apache -spark /

import org.Apache.hadoop.fs.{FileSystem, Path}
import org.Apache.hadoop.conf.Configuration
val fs = FileSystem.get(new Configuration())
fs.listStatus(new Path("s3://s3bucket/2017/10/31/*/*/"))

しかし、このエラーWrong FS: s3://s3bucket/2017/10/31/*/*, expected: hdfs://ip-172-31-55-167.ec2.internal:8020

正確なファイルが存在するかどうかをその正確なパスを使用して確認できますが、サポートされていない「s3:// s3bucket/2017/10/31/*/*」のようなワイルドカードを使用する必要があります。

このStackOverflowの質問を確認しました: Spark:パスが存在する場合のみファイルを読み取ります が、私のユースケースとは関係ありません。

8
Shivam Panjeta

これは、FileSystem.get(new Configuration())を呼び出すと、解決されるファイルシステムがデフォルトのファイルシステム(この場合はhdfs)になるためです。

最初に、s3スキームとバケットを含むパスからURIを提供して、適切なファイルシステムを取得する必要があります。

また、現在のSparkコンテキストのHadoop構成を使用して、Sparkと同じファイルシステム設定を確実に使用することをお勧めします。

import Java.net.URI
import org.Apache.hadoop.fs.FileSystem
import org.Apache.spark.sql.SparkSession

// Create a session with Spark master running locally (vs on a cluster)
// for development purposes
val sparkSession = SparkSession.builder
                               .appName("My App")
                               .master("local")
                               .getOrCreate

val conf = sparkSession.sparkContext.hadoopConfiguration
val fs = FileSystem.get(URI.create("s3://s3bucket/"), conf)

これは、クラスパスにS3ファイルシステムの実装がある場合にのみ機能します。 EC2インスタンスでプログラムを実行しているので、明示的なAWS認証情報を指定せずにS3にアクセスできるはずです。

11
import org.Apache.hadoop.fs.FileSystem
import org.Apache.hadoop.fs.Path
import org.Apache.spark.SparkContext
import Java.net.URI

var sc = new SparkContext()
if(FileSystem.get(new URI(externalTableLocation), sc.hadoopConfiguration).exists(new Path(externalTableLocation)))
{
  println("File exists")
  val maxPopulatedDate = spark.sql(s"SELECT MAX(DateID) FROM tier_ppw.DistributionDailyFact_Stage")
      log.info("Reading maxPopulatedDate: "+maxPopulatedDate)
}
else
{
   val maxPopulatedDate = "2016-01-01"
   log.info("Reading maxPopulatedDate: "+maxPopulatedDate)
}
1
Rajiv Singh

これはとても簡単です。たとえば、Testfolderというディレクトリが存在するかどうかを確認する必要がある場合は、次のコードを使用します。

val s3login = "s3a://Accesskey:Secretkey@Bucket"
val path = "/Myfolder/Testfolder"    
if(FileSystem.get(new Java.net.URI(s3login + path), sc.hadoopConfiguration).exists(new Path(s3login + path)))
{
    println("Directory exists")
}
0
Sarath Avanavu

S3はオブジェクトベースのストレージであり、この種の構文をサポートしません。 /*/*。また、s3ファイルシステムをデフォルトとして設定し、クラスターがバケットにアクセスできるかどうかを確認する必要があります。

0
loneStar