Локально чтение файлов S3 через Spark (или лучше: pyspark)
Я хочу прочитать файл S3 с моей (локальной) машины, через Spark (pyspark, действительно). Теперь я продолжаю получать ошибки аутентификации, например
java.lang.IllegalArgumentException: идентификатор ключа доступа AWS и секрет Ключ доступа должен быть указан как имя пользователя или пароль (соответственно) URL-адреса s3n или установкой fs.s3n.awsAccessKeyId или fs.s3n.awsSecretAccessKey(соответственно).
Я смотрел повсюду здесь и в Интернете, пробовал много вещей, но, по-видимому, S3 менялся за последний год или месяцы, и все методы не удались, но один:
pyspark.SparkContext().textFile("s3n://user:[email protected]/key")
(обратите внимание, что s3n
[s3
не работает]). Теперь я не хочу использовать URL с пользователем и паролем, потому что они могут появляться в журналах, и я также не уверен, как их получить из файла ~/.aws/credentials
.
Итак, как я могу читать локально с S3 через Spark (или, лучше, pyspark), используя учетные данные AWS из файла standard ~/.aws/credentials
в идеале, без копирования учетных данных в другой файл конфигурации)?
PS: Я пробовал os.environ["AWS_ACCESS_KEY_ID"] = …
и os.environ["AWS_SECRET_ACCESS_KEY"] = …
, это не сработало.
PPS: я не уверен, где "установить свойства fs.s3n.awsAccessKeyId или fs.s3n.awsSecretAccessKey" (Google ничего не придумал). Тем не менее, я пробовал много способов установить их: SparkContext.setSystemProperty()
, sc.setLocalProperty()
и conf = SparkConf(); conf.set(…); conf.set(…); sc = SparkContext(conf=conf)
. Ничего не получилось.
Ответы
Ответ 1
Проблема была на самом деле ошибкой в модуле Python Amazon boto
. Проблема была связана с тем, что версия MacPort на самом деле старая: установка boto
через pip решила проблему: ~/.aws/credentials
была правильно прочитана.
Теперь, когда у меня больше опыта, я бы сказал, что в целом (по состоянию на конец 2015 года) инструменты Amazon Web Services и Spark/PySpark имеют патчавую документацию и могут иметь некоторые серьезные ошибки, которые очень легко запускать. Для первой проблемы я бы рекомендовал сначала обновить интерфейс командной строки aws, boto
и Spark каждый раз, когда что-то странное происходит: это "магически" разрешило несколько проблем уже для меня.
Ответ 2
Да, вы должны использовать s3n
вместо s3
. s3
- это какое-то странное злоупотребление S3, преимущества которого мне неясны.
Вы можете передать учетные данные вызовам sc.hadoopFile
или sc.newAPIHadoopFile
:
rdd = sc.hadoopFile('s3n://my_bucket/my_file', conf = {
'fs.s3n.awsAccessKeyId': '...',
'fs.s3n.awsSecretAccessKey': '...',
})
Ответ 3
Вот решение о том, как читать учетные данные из ~/.aws/credentials
. Он использует тот факт, что файл учетных данных является INI файлом, который может быть проанализирован с помощью конфигурационного файла Python.
import os
import configparser
config = configparser.ConfigParser()
config.read(os.path.expanduser("~/.aws/credentials"))
access_id = config.get(aws_profile, "aws_access_key_id")
access_key = config.get(aws_profile, "aws_secret_access_key")
См. также мой текст в https://gist.github.com/asmaier/5768c7cda3620901440a62248614bbd0.
Ответ 4
Я не могу много сказать о java-объектах, которые вы должны дать функции hasoopFile, только эта функция уже кажется лишенной для некоторого "newAPIHadoopFile". Документация по этому вопросу довольно отрывочна, и я чувствую, что вам нужно знать Scala/Java, чтобы действительно понять, что все значит.
Тем временем я понял, как фактически получить некоторые данные s3 в pyspark, и я думал, что поделюсь своими выводами.
Эта документация: Документация API Spark говорит, что она использует dict, который преобразуется в java-конфигурацию (XML). Я нашел конфигурацию для java, это, вероятно, должно отражать значения, которые вы должны ввести в dict: Как получить доступ к S3/S3n из локальной установки hadoop
bucket = "mycompany-mydata-bucket"
prefix = "2015/04/04/mybiglogfile.log.gz"
filename = "s3n://{}/{}".format(bucket, prefix)
config_dict = {"fs.s3n.awsAccessKeyId":"FOOBAR",
"fs.s3n.awsSecretAccessKey":"BARFOO"}
rdd = sc.hadoopFile(filename,
'org.apache.hadoop.mapred.TextInputFormat',
'org.apache.hadoop.io.Text',
'org.apache.hadoop.io.LongWritable',
conf=config_dict)
Этот фрагмент кода загружает файл из ведра и префикса (путь к файлу в ковше), указанный в первых двух строках.
Ответ 5
Настройка переменных окружения может помочь.
Здесь в Spark FAQ в разделе "Как я могу получить доступ к данным на S3?" они предлагают установить переменные среды AWS_ACCESS_KEY_ID
и AWS_SECRET_ACCESS_KEY
.