PySpark использует роли IAM для доступа к S3

Мне интересно, поддерживает ли PySpark доступ S3 с использованием ролей IAM. В частности, у меня есть бизнес-ограничение, когда я должен взять на себя роль AWS, чтобы получить доступ к данному сегменту. Это нормально при использовании boto (так как это часть API), но я не могу найти однозначного ответа относительно того, поддерживает ли PySpark это "из коробки".

В идеале я хотел бы иметь возможность взять на себя роль при локальном запуске в автономном режиме и указать свой SparkContext на этот путь s3. Я видел, что звонки не IAM обычно следуют:

spark_conf = SparkConf().setMaster('local[*]').setAppName('MyApp')
sc = SparkContext(conf=spark_conf)
rdd = sc.textFile('s3://<MY-ID>:<MY-KEY>@some-bucket/some-key')

Существует ли что-то подобное для предоставления информации IAM?:

rdd = sc.textFile('s3://<MY-ID>:<MY-KEY>:<MY-SESSION>@some-bucket/some-key')

или же

rdd = sc.textFile('s3://<ROLE-ARN>:<ROLE-SESSION-NAME>@some-bucket/some-key')

Если нет, каковы лучшие методы работы с кредитами IAM? Это вообще возможно?

Я использую Python 1.7 и PySpark 1.6.0

Спасибо!

5 ответов

Spark поддерживает доступ к файлам в S3 на основе ролей IAM, вам просто нужно быть осторожным с настройками. В частности, вам нужно:

  • Совместимые версии aws-java-sdk а также hadoop-aws, Это довольно хрупко, поэтому работают только определенные комбинации.
  • Вы должны использовать S3AFileSystem не NativeS3FileSystem, Первый разрешает доступ на основе ролей, а последний разрешает только учетные данные пользователя.

Вот что сработало для меня:

импорт ОС

import pyspark
from pyspark import SparkContext
from pyspark.sql import SparkSession

os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages com.amazonaws:aws-java-sdk:1.7.4,org.apache.hadoop:hadoop-aws:2.7.1 pyspark-shell'

sc = SparkContext.getOrCreate()

hadoopConf = sc._jsc.hadoopConfiguration()
hadoopConf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")

spark = SparkSession(sc)

df = spark.read.csv("s3a://mybucket/spark/iris/",header=True)
df.show()

Это конкретная комбинация aws-java-sdk:1.7.4 а также hadoop-aws:2.7.1 это волшебно заставило это работать. Здесь есть хорошее руководство по устранению неполадок доступа к s3a.

Особо отметим, что

Случайное изменение JAR-файлов hadoop и aws в надежде заставить проблему "уйти" или получить доступ к нужной функции, не приведет к желаемому результату.

Совет: вы можете использовать mvnrepository для определения требований к версии зависимостей конкретного JAR-файла hadoop-aws, опубликованного ASF.

Вот полезный пост, содержащий дополнительную информацию.

Вот еще немного полезной информации о совместимости между библиотеками Java

Я пытался заставить это работать в тетради jupyter pyspark. Обратите внимание, что aws-hadoop версия должна соответствовать установке hadoop в Dockerfile, т.е. здесь.

Роль IAM для доступа s3 Поддерживается только s3a, потому что он использует AWS SDK.

Вам нужно поставить hadoop-aws JAR и aws-java-sdk JAR (и сторонние Jars в его упаковке) в ваш CLASSPATH.

ссылка hadoop-aws.

ссылка aws-java-sdk.

Затем установите это в core-site.xml:

<property>
    <name>fs.s3.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
</property>
<property>
    <name>fs.s3a.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
</property>

Соединитель s3a в Hadoop 2.8+ поддерживает роли IAM через нового поставщика учетных данных; Его нет в выпуске Hadoop 2.7. Чтобы использовать его, нужно сменить поставщика учетных данных. fs.s3a.aws.credentials.provider = org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider fs.s3a.access.key = <your access key> fs.s3a.secret.key = <session secret> fs.s3a.session.token = <session token> Что в Hadoop 2.7 (и включено по умолчанию) - это получение AWS_ переменные среды

Если вы установите переменные AWS env для входа в сеанс в локальной и удаленной системах , они должны быть активированы.

Я знаю, это больно, но что касается команды Hadoop, то Hadoop 2.7, выпущенный в середине 2016 года, и с тех пор мы многое сделали, вещи, которые мы не собираемся рекламировать.

Вы можете попробовать подход в локальном чтении файлов S3 через Spark (или лучше: pyspark).

Однако мне повезло с настройкой переменных среды (AWS_ACCESS_KEY_ID и т.д.) в Bash ... pyspark автоматически подберет их для вашей сессии.

После дополнительных исследований я убежден, что это еще не подтверждено, что подтверждается здесь.

Другие предложили использовать более ручной подход (см. Этот пост в блоге), который предлагает перечислить ключи s3 с помощью boto, а затем распараллелить этот список с помощью Spark для чтения каждого объекта.

Проблема здесь (и я пока не вижу, как они сами обойдут это) в том, что объекты s3, возвращаемые из списка внутри корзины, не могут быть сериализуемы / рассортированы (помните: предполагается, что эти объекты передаются работникам читать в независимых процессах через карту или flatMap). Кроме того, проблема заключается в том, что сам клиент boto s3 не сериализуем (на мой взгляд, это разумно).

То, что у нас осталось, - это единственный выбор воссоздания клиента s3 с предполагаемой ролью для файла, который не является оптимальным или выполнимым после определенной точки.

Если кто-нибудь увидит какие-либо недостатки в этом рассуждении или альтернативном решении / подходе, я хотел бы услышать это.

Другие вопросы по тегам