-- опция файлов в pyspark не работает
пробовал sc.addFile
опция (работает без каких-либо проблем) и --files
опция из командной строки (ошибка).
выполнить 1 : spark_distro.py
from pyspark import SparkContext, SparkConf
from pyspark import SparkFiles
def import_my_special_package(x):
from external_package import external
ext = external()
return ext.fun(x)
conf = SparkConf().setAppName("Using External Library")
sc = SparkContext(conf=conf)
sc.addFile("/local-path/readme.txt")
with open(SparkFiles.get('readme.txt')) as test_file:
lines = [line.strip() for line in test_file]
print(lines)
int_rdd = sc.parallelize([1, 2, 4, 3])
mod_rdd = sorted(int_rdd.filter(lambda z: z%2 == 1).map(lambda x:import_my_special_package(x)))
внешний пакет: external_package.py
class external(object):
def __init__(self):
pass
def fun(self,input):
return input*2
readme.txt
MY TEXT HERE
spark-отправить команду
spark-submit
--master yarn-client
--py-files /path to local codelib/external_package.py
/local-pgm-path/spark_distro.py
1000
вывод: работает ожидалось
['MY TEXT HERE']
но если я попытаюсь передать файл (readme.txt) из командной строки с помощью --files (вместо sc.addFile) опция не работает. Как внизу.
выполнить 2 : spark_distro.py
from pyspark import SparkContext, SparkConf
from pyspark import SparkFiles
def import_my_special_package(x):
from external_package import external
ext = external()
return ext.fun(x)
conf = SparkConf().setAppName("Using External Library")
sc = SparkContext(conf=conf)
with open(SparkFiles.get('readme.txt')) as test_file:
lines = [line.strip() for line in test_file]
print(lines)
int_rdd = sc.parallelize([1, 2, 4, 3])
mod_rdd = sorted(int_rdd.filter(lambda z: z%2 == 1).map(lambda x: import_my_special_package(x)))
external_package.py то же, что и выше
Искра представить
spark-submit
--master yarn-client
--py-files /path to local codelib/external_package.py
--files /local-path/readme.txt#readme.txt
/local-pgm-path/spark_distro.py
1000
выход:
Traceback (most recent call last):
File "/local-pgm-path/spark_distro.py", line 31, in <module>
with open(SparkFiles.get('readme.txt')) as test_file:
IOError: [Errno 2] No such file or directory: u'/tmp/spark-42dff0d7-c52f-46a8-8323-08bccb412cd6/userFiles-8bd16297-1291-4a37-b080-bbc3836cb512/readme.txt'
и sc.addFile
и --file
используется для тех же цель? Кто-нибудь, пожалуйста, поделитесь своими мыслями.
4 ответов
я, наконец, понял проблему, и это очень тонкие действительно.
как и предполагалось, два варианта (sc.addFile
и --files
) составляют не эквивалент, и это (по общему признанию, очень тонко) намекает на документацию (курсив добавлен):
addFile
(путь, рекурсивный=False)
Добавьте файл для загрузки с помощью этого задания Spark на каждом узел.
--files
файлы
Разделенный запятыми список файлов, которые будут помещены в рабочих каталог каждого исполнитель.
на простом английском языке, в то время как файлы, добавленные с sc.addFile
доступны как исполнителям, так и водителю, файлы добавлены с --files
доступны только исполнителям; следовательно, при попытке доступа к ним из драйвера (как это имеет место в OP) мы получаем No such file or directory
ошибка.
давайте подтвердите это (избавляясь от всего неуместного --py-files
и 1000
материал в OP):
test_fail.py
:
from pyspark import SparkContext, SparkConf
from pyspark import SparkFiles
conf = SparkConf().setAppName("Use External File")
sc = SparkContext(conf=conf)
with open(SparkFiles.get('readme.txt')) as test_file:
lines = [line.strip() for line in test_file]
print(lines)
тест:
spark-submit --master yarn \
--deploy-mode client \
--files /home/ctsats/readme.txt \
/home/ctsats/scripts/SO/test_fail.py
результат:
[...]
17/11/10 15:05:39 INFO yarn.Client: Uploading resource file:/home/ctsats/readme.txt -> hdfs://host-hd-01.corp.nodalpoint.com:8020/user/ctsats/.sparkStaging/application_1507295423401_0047/readme.txt
[...]
Traceback (most recent call last):
File "/home/ctsats/scripts/SO/test_fail.py", line 6, in <module>
with open(SparkFiles.get('readme.txt')) as test_file:
IOError: [Errno 2] No such file or directory: u'/tmp/spark-8715b4d9-a23b-4002-a1f0-63a1e9d3e00e/userFiles-60053a41-472e-4844-a587-6d10ed769e1a/readme.txt'
в приведенном выше скрипте test_fail.py
, это водитель программа, которая запрашивает доступ к файлу readme.txt
; Давайте изменим сценарий, так что доступ запрашивается для исполнители (test_success.py
):
from pyspark import SparkContext, SparkConf
conf = SparkConf().setAppName("Use External File")
sc = SparkContext(conf=conf)
lines = sc.textFile("readme.txt") # run in the executors
print(lines.collect())
тест:
spark-submit --master yarn \
--deploy-mode client \
--files /home/ctsats/readme.txt \
/home/ctsats/scripts/SO/test_success.py
результат:
[...]
17/11/10 15:16:05 INFO yarn.Client: Uploading resource file:/home/ctsats/readme.txt -> hdfs://host-hd-01.corp.nodalpoint.com:8020/user/ctsats/.sparkStaging/application_1507295423401_0049/readme.txt
[...]
[u'MY TEXT HERE']
обратите внимание также, что здесь нам не нужно SparkFiles.get
- файл доступен.
как сказали выше, sc.addFile
будет работать в обоих случаях, т. е. когда доступ запрашивается либо драйвером, либо исполнителями (проверено, но не показано здесь).
что касается порядка параметров командной строки: как я утверждал везде все Аргументы, связанные с Spark, должны быть перед исполняемым скриптом; возможно, относительный порядок --files
и --py-files
не имеет значения (оставляя это в качестве упражнения).
проверено с обоими Искра 1.6.0 & 2.2.0.
обновление (после комментариев): кажется, что мой fs.defaultFS
установка точек на HDFS тоже:
$ hdfs getconf -confKey fs.defaultFS
hdfs://host-hd-01.corp.nodalpoint.com:8020
но позвольте мне сосредоточиться на леса здесь (вместо деревьев, то есть), и объяснить почему вся эта дискуссия представляет только академический интерес:
передает файлы для обработки С --files
флаг-плохая практика; оглядываясь назад, я теперь понимаю, почему я не мог найти почти никаких ссылок в интернете - вероятно, никто не использует его на практике, и не без оснований.
(обратите внимание, что я говорю не для --py-files
, который выполняет другую, законную роль.)
поскольку Spark-это распределенная платформа обработки, работающая над кластер и распределенная файловая система (HDFS), лучшее, что нужно сделать, это иметь все файлы для обработки в HDFS уже - период. "Естественным" местом для обработки файлов Spark является HDFS, а не локальная FS - хотя есть некоторые игрушки примеры использования локальных FS только для демонстрационных целей. Более того, если вы хотите в будущем изменить режим развертывания на cluster
, вы обнаружите, что кластер по умолчанию ничего не знает локальных путей и файлов, и по праву...
та же цель, но разные использования.
С --files
опции
--files FILES Comma-separated list of files to be placed in the working
directory of each executor.
не нужно SparkFiles.get
получить расположение файла, потому что это на самом деле в working directory of each executor
.
with open('readme.txt') as test_file:
lines = [line.strip() for line in test_file]
попробовать
import os
from os import path
here = os.getcwd()
with open(path.join(here, 'readme.txt')) as f:
pass
читайте Подачи Заявок снова, он сказал:
для приложений Python просто передайте .py-файл вместо банки и добавьте Python .промелькнуть. ,яйцо или .py-файлы в путь поиска с --py-файлами.
search path
ключ
передайте этот файл в качестве аргумента при его использовании в spark-submit
как sc = SparkContext(conf=conf)
with open(SparkFiles.get(args(0))) as test_file:
в программе и в spark submit
spark-submit \
--master yarn-client \
/local-pgm-path/spark_distro.py \
/local/file/path
путь к файлу должен прийти после файла jar приложения.