Невозможно получить доступ к данным S3 с помощью Spark 2.2
Я загружаю много данных в корзину S3, которую я хочу анализировать / визуализировать с помощью Spark и Zeppelin. Тем не менее, я все еще застрял при загрузке данных из S3.
Я немного почитал, чтобы собраться и избавить меня от мрачных деталей. Я использую докер-контейнер p7hb / docker-spark в качестве установки Spark, и мой основной тест для чтения данных из S3 получен отсюда:
Я запускаю контейнер и ведущий и подчиненный процессы внутри. Я могу проверить эту работу, посмотрев веб-интерфейс Spark Master, отображаемый на порте 8080. На этой странице приведен список рабочих и ведется журнал всех моих неудачных попыток под заголовком "Завершенные приложения". Все это в состоянии
FINISHED
,Я открываю
bash
внутри этого контейнера и сделайте следующее:а) экспортировать переменные среды
AWS_ACCESS_KEY_ID
а такжеAWS_SECRET_ACCESS_KEY
, как предлагается здесь.б) начать
spark-shell
, Чтобы получить доступ к S3, нужно загрузить несколько дополнительных пакетов. Просматривая SE, я нашел особенно это, что учит меня, что я могу использовать--packages
параметр для загрузки указанных пакетов. По сути бегаюspark-shell --packages com.amazonaws:aws-java-sdk:1.7.15,org.apache.hadoop:hadoop-aws:2.7.5
(для произвольных комбинаций версий).в) я запускаю следующий код
sc.hadoopConfiguration.set("fs.s3a.endpoint", "s3-eu-central-1.amazonaws.com")
sc.hadoopConfiguration.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
sc.hadoopConfiguration.set("com.amazonaws.services.s3.enableV4", "true")
val sonnets=sc.textFile("s3a://my-bucket/my.file")
val counts = sonnets.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)
И тогда я получаю всевозможные сообщения об ошибках, в зависимости от версий, выбранных в 2b).
Я полагаю, что нет ничего плохого в 2a), б / с я получаю сообщение об ошибке Unable to load AWS credentials from any provider in the chain
если я не поставлю их. Это известная ошибка, которую делают новые пользователи.
Пытаясь решить проблему, я выбираю более или менее случайные версии здесь и там для двух дополнительных пакетов. Где-то на SE я читал, что hadoop-aws:2.7 должен быть правильным выбором, потому что Spark 2.2 основан на Hadoop 2.7. Предположительно, нужно использовать aws-java-sdk:1.7 с этой версией hadoop-aws.
Без разницы! Я попробовал следующие комбинации
--packages com.amazonaws:aws-java-sdk:1.7.4,org.apache.hadoop:hadoop-aws:2.7.1
, что приводит к общей ошибке Bad Request 400. Многие проблемы могут привести к этой ошибке, моя попытка, как описано выше, содержит все, что я смог найти на этой странице. Описание выше содержитs3-eu-central-1.amazonaws.com
в качестве конечной точки, в то время как другие места используютs3.eu-central-1.amazonaws.com
, В соответствии с описанием ссылки здесь, оба имени конечной точки должны работать. Я попробовал оба.--packages com.amazonaws:aws-java-sdk:1.7.15,org.apache.hadoop:hadoop-aws:2.7.5
, которые являются самыми последними версиями микро в любом случае, я получаю сообщение об ошибкеjava.lang.NoSuchMethodError: com.amazonaws.services.s3.transfer.TransferManager.<init>(Lcom/amazonaws/services/s3/AmazonS3;Ljava/util/concurrent/ThreadPoolExecuto r;)V
--packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.7.5
Я тоже получаюjava.lang.NoSuchMethodError: com.amazonaws.services.s3.transfer.TransferManager.<init>(Lcom/amazonaws/services/s3/AmazonS3;Ljava/util/concurrent/ThreadPoolExecutor;)V
--packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.8.1
, Я получилjava.lang.IllegalAccessError: tried to access method org.apache.hadoop.metrics2.lib.MutableCounterLong.<init>(Lorg/apache/hadoop/metrics2/MetricsInfo;J)V from class org.apache.hadoop.fs.s3a.S3AInstrumentation
--packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.8.3
Я тоже получаюjava.lang.IllegalAccessError: tried to access method org.apache.hadoop.metrics2.lib.MutableCounterLong.<init>(Lorg/apache/hadoop/metrics2/MetricsInfo;J)V from class org.apache.hadoop.fs.s3a.S3AInstrumentation
--packages com.amazonaws:aws-java-sdk:1.8.12,org.apache.hadoop:hadoop-aws:2.8.3
Я тоже получаюjava.lang.IllegalAccessError: tried to access method org.apache.hadoop.metrics2.lib.MutableCounterLong.<init>(Lorg/apache/hadoop/metrics2/MetricsInfo;J)V from class org.apache.hadoop.fs.s3a.S3AInstrumentation
--packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.9.0
Я тоже получаюjava.lang.NoClassDefFoundError: org/apache/hadoop/fs/StorageStatistics
И, ради полноты, когда я не предоставляю --packages
параметр, я получаю java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found
,
В настоящее время, кажется, ничего не работает. Тем не менее, по этой теме так много вопросов и ответов, кто знает, как это сделать. Это все в локальном режиме, поэтому другого источника ошибки практически нет. Мой метод доступа к S3 должен быть неправильным. Как это сделано правильно?
Изменить 1:
Поэтому я вложил в это еще один день, без какого-либо реального прогресса. Насколько я могу судить, начиная с Hadoop 2.6, Hadoop больше не имеет встроенной поддержки S3, но загружается через дополнительные библиотеки, которые не являются частью Hadoop и полностью управляются самим собой. Помимо всего этого беспорядка, библиотека, которую я в конечном счете хочу, кажется, hadoop-aws
, Здесь есть веб-страница, на которой есть то, что я бы назвал авторитетной информацией:
Версии hadoop-common и hadoop-aws должны быть идентичны.
Важным в этой информации является то, что hadoop-common
на самом деле поставляется с установкой Hadoop. Каждая установка Hadoop имеет соответствующий файл JAR, так что это хорошая отправная точка. В моих контейнерах есть файл /usr/hadoop-2.7.3/share/hadoop/common/hadoop-common-2.7.3.jar
поэтому справедливо предположить, что 2.7.3 - это версия, которая мне нужна hadoop-aws
,
После этого становится темным. В версиях 2.7.x Hadoop что-то происходит внутри, поэтому они не совместимы с более поздними версиями aws-java-sdk
, которая является библиотекой, требуемой hadoop-aws
, В Интернете полно советов использовать версию 1.7.4, например, здесь, но другие комментарии предлагают использовать версию 1.7.14 для 2.7.x.
Так что я сделал еще один запуск, используя hadoop-aws:2.7.3
а также aws-java-sdk:1.7.x
, с x
от 4 до 14. Никаких результатов, я всегда получаю ошибку 400, Bad Request.
Моя установка Hadoop поставляется joda-time
2.9.4. Я прочитал, что проблема была решена с Hadoop 2.8. Полагаю, я просто собираюсь создавать собственные док-контейнеры с более свежими версиями.
Редактировать 2
Перемещено в Hadoop 2.8.3. Это просто работает сейчас. Оказывается, вам даже не нужно возиться с банками. Hadoop поставляется с тем, что должно работать с JAR для доступа к AWS S3. Они спрятаны в ${HADOOP_HOME}/share/hadoop/tools/lib
и не добавляется в путь к классам по умолчанию. Я просто загружаю JARS в этот каталог, выполняю свой код, как указано выше, и теперь он работает.
1 ответ
Как вы обнаружили, смешивание и сопоставление JAR-файлов AWS SDK с чем-либо еще - бесполезное упражнение. Вам нужна версия AWS JAR, с которой была построена Jads, и версия Jackson AWS, с которой. О, и не пытайтесь смешивать какие-либо из (разные JAR-файлы amazon-, разные JAR-файлы hadoop-, разные JAR-файлы jackson-); все они идут в режиме синхронизации.
Для Spark 2.2.0 и Hadoop 2.7 используйте артефакты AWS 1.7.4 и убедитесь, что если вы используете Java 8, то время Joda> 2.8.0, например 2.9.4. Это может привести к 400 "плохим проблемам с аутентификацией".
В противном случае попробуйте устранить неполадки S3A