403 Исключение при попытке построить DataFrame из файла паркета в S3 локально - PullRequest
0 голосов
/ 10 июля 2019

Я создаю приложение Spark и пытаюсь запустить его локально, прежде чем запускать его в EMR или в контейнере.Я могу заставить DataFrame нормально работать, когда сам файл паркета является локальным, но он отказывается читать файл паркета, если он находится в S3.Я попытался установить все переменные, которые, как мне кажется, предлагаются при чтении с S3a, вот как я создаю сеанс Spark:

package util

import org.apache.spark.sql.SparkSession
import scala.io.Source

object SparkSessionFactory {

  def generateSession(sessionLocation: String): SparkSession = {
    val session = {
      sessionLocation match {
        case "local" =>
          SparkSession.builder().appName("LocalS3SparkProfiler").master("yarn").master("local[*]")
            .config("spark.driver.host", "localhost")
            .config("fs.s3a.enableServerSideEncryption", "true")
            .config("fs.s3a.serverSideEncryptionAlgorithm", "aws:kms")
            .getOrCreate()
      }
    }
    setHadoopConfigs(session, sessionLocation)
    session
  }

  private def setHadoopConfigs(session:SparkSession, sessionLocation:String) = {
    session.sparkContext.hadoopConfiguration.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
    session.sparkContext.hadoopConfiguration.set("fs.s3a.path.style.access", "true")
    sessionLocation match {
      case "local"=> {
        val userHome = System.getProperty("user.home")
        val aWSCredentialsLines = Source.fromFile(s"$userHome/.aws/credentials").getLines.toList

        val key = aWSCredentialsLines(1).substring(aWSCredentialsLines(1).lastIndexOf(" ")).trim
        val secret = aWSCredentialsLines(2).substring(aWSCredentialsLines(2).lastIndexOf(" ")).trim
        val s3Token = aWSCredentialsLines(3).substring(aWSCredentialsLines(3).lastIndexOf(" ")).trim

        session.sparkContext.hadoopConfiguration.set("fs.s3a.access.key", key)
        session.sparkContext.hadoopConfiguration.set("fs.s3a.secret.key", secret)
        session.sparkContext.hadoopConfiguration.set("fs.s3a.session.token", s3Token)
        session.sparkContext.hadoopConfiguration.set("fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider")
      }
    }
  }
}

И затем, когда я пытаюсь прочитать фрейм данныхЯ звоню

val spark = SparkSessionFactory.generateSession("local")
val df = spark.read.parquet("s3a://my-bucket/thepath/myparquetfile")

И выдается следующее сообщение об ошибке:

Исключение в потоке "main" com.amazonaws.services.s3.model.AmazonS3Exception: Forbidden (Service:Amazon S3, код состояния: 403; Код ошибки: 403 Forbidden; Request ID: 366CFE11F21144F3; S3 Extended Request ID: eW4C6PQZ4uSJOPmYKoZ8qCwmK4PwL6eFPwef9e1KLA3kL2LsiCMctZ + ZLYVplZh927iNiSro7ko =), S3 Extended Request ID: eW4C6PQZ4uSJOPmYKoZ8qCwmK4PwL6eFPwef9e1KLA3kL2LsiCMctZ + ZLYVplZh927iNiSro7ko = в com.amazonaws.http.AmazonHttpClient $ RequestExecutor.handleErrorResponse (AmazonHttpClient.java:1632) по адресу com.amazonaws.http.AmazonHttpClient $ RequestExecutor.executeOneRequest (AmazonHttpClient.java:1304) по адресу com.amazonaws.http.AmazonHttpClient10HecentExHezTezTezHezTezTezHezTez:!,http.AmazonHttpClient $ RequestExecutor.699) на com.amazonaws.http.AmazonHttpClient $ RequestExecutor.access $ 500 (AmazonHttpClient.java:667) на com.amazonaws.http.AmazonHttpClient $ RequestExecutionBuilderImpl.execute (AmazonHttpClient.http.выполнить (AmazonHttpClient.java:513) на com.amazonaws.services.s3.AmazonS3Client.invoke (AmazonS3Client.java:4330) на com.amazonaws.services.s3.AmazonS3Client.invoke (AmazonS3Client.java:4277) на com.amazonaw.services.s3.AmazonS3Client.getObjectMetadata (AmazonS3Client.java:1265)

Все, что я прочитал, говорит о том, что мне нужны учетные данные, которые я предоставляю.Я проверил значения key, secret и s3Token, и они выглядят правильно, так как я использую эти учетные данные в другом проекте, который без проблем использует обычный AWS SDK.

Любая идеяв чем проблема?

1 Ответ

0 голосов
/ 11 июля 2019

Отладка сбоев аутентификации AWS является сложной задачей, поскольку ни AWS, ни кто-либо, внедряющий клиентов, не хотят регистрировать секреты на консоли.«403», как правило, так же бесполезен, как «400» для отладки

  1. Посмотрите на Устранение неполадок S3A
  2. Так же, как и прямые проблемы с аутентификацией, вы получитеошибка аутентификации, если файл SSE-KMS зашифрован с помощью ключа AWS KMS, и он не может получить доступ к вашей учетной записи.в сообщении об ошибке это специально не упоминается.
  3. Попробуйте использовать AWS cli с теми же кредитами, чтобы убедиться, что они работают.Если они позволяют вам просматривать данные, это неизбежно приводит к некоторой проблеме конфигурации spark / s3a.
  4. Загрузите последнюю версию Hadoop (в идеале 3.2), установите ее и настройте файл core-site.xml с параметрами.Затем используйте Cloudstore storeiag , чтобы позволить ему выполнить структурированную отладку процесса входа в систему.Если это не сработает, искра тоже не будет.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...