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.
Затем установите это в 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 с предполагаемой ролью для файла, который не является оптимальным или выполнимым после определенной точки.
Если кто-нибудь увидит какие-либо недостатки в этом рассуждении или альтернативном решении / подходе, я хотел бы услышать это.