如何在独立的火花星团(pySpark)中使用FTP上的文件?

时间:2016-05-16 13:16:49

标签: python apache-spark ftp pyspark

嘿,我是全新的火花,最近建立了一个几乎没有笔记本电脑的火花独立集群。

我在本地ftp服务器上共享了一个名为new.txt的文件 根据Spark指南 " PySpark可以从Hadoop支持的任何存储源创建分布式数据集,包括本地文件系统,HDFS,Cassandra,HBase,Amazon S3等等。 (http://spark.apache.org/docs/latest/programming-guide.html#external-datasets

我已通过执行以下操作在独立群集模式下打开了pyspark交互式shell:

 $ MASTER=spark://IP:PORT ./bin/pyspark

然后执行指南中的示例命令。

>>> ff= sc.textFile("ftp://192.168.125.124/new.txt")
>>> ans = ff.map(lambda s: len(s)).reduce(lambda a, b: a + b)


第一行执行正常并创建rdd。在第二行之后我收到此错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/shrey/spark-1.6.1/python/pyspark/rdd.py", line 797, in reduce
    vals = self.mapPartitions(func).collect()
  File "/home/shrey/spark-1.6.1/python/pyspark/rdd.py", line 771, in collect
    port = self.ctx._jvm.PythonRDD.collectAndServe(self._jrdd.rdd())
  File "/home/shrey/spark-1.6.1/python/lib/py4j-0.9-src.zip/py4j/java_gateway.py", line 813, in __call__
  File "/home/shrey/spark-1.6.1/python/pyspark/sql/utils.py", line 45, in deco
    return f(*a, **kw)
  File "/home/shrey/spark-1.6.1/python/lib/py4j-0.9-src.zip/py4j/protocol.py", line 308, in get_return_value
py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe.
: java.io.IOException: Login failed on server - 192.168.125.124, port - 21
    at org.apache.hadoop.fs.ftp.FTPFileSystem.connect(FTPFileSystem.java:133)
    at org.apache.hadoop.fs.ftp.FTPFileSystem.getFileStatus(FTPFileSystem.java:390)
    at org.apache.hadoop.fs.FileSystem.globStatusInternal(FileSystem.java:1701)
    at org.apache.hadoop.fs.FileSystem.globStatus(FileSystem.java:1647)
    at org.apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.java:222)
    at org.apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.java:270)
    at org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:199)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:239)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:237)
    at scala.Option.getOrElse(Option.scala:120)
    at org.apache.spark.rdd.RDD.partitions(RDD.scala:237)
    at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:35)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:239)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:237)
    at scala.Option.getOrElse(Option.scala:120)
    at org.apache.spark.rdd.RDD.partitions(RDD.scala:237)
    at org.apache.spark.api.python.PythonRDD.getPartitions(PythonRDD.scala:58)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:239)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:237)
    at scala.Option.getOrElse(Option.scala:120)
    at org.apache.spark.rdd.RDD.partitions(RDD.scala:237)
    at org.apache.spark.SparkContext.runJob(SparkContext.scala:1929)
    at org.apache.spark.rdd.RDD$$anonfun$collect$1.apply(RDD.scala:927)
    at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:150)
    at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:111)
    at org.apache.spark.rdd.RDD.withScope(RDD.scala:316)
    at org.apache.spark.rdd.RDD.collect(RDD.scala:926)
    at org.apache.spark.api.python.PythonRDD$.collectAndServe(PythonRDD.scala:405)
    at org.apache.spark.api.python.PythonRDD.collectAndServe(PythonRDD.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:231)
    at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:381)
    at py4j.Gateway.invoke(Gateway.java:259)
    at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133)
    at py4j.commands.CallCommand.execute(CallCommand.java:79)
    at py4j.GatewayConnection.run(GatewayConnection.java:209)
    at java.lang.Thread.run(Thread.java:745)


它说在端口21上的192.168.125.124登录失败似乎有一些问题将结果返回到ftp?我无法理解结果是如何返回的。我从从属计算机的浏览器访问我的ftp服务器,它没有提示登录。我的vsftpd.conf具有以下权限设置。

anonymous_enable=YES
local_enable=YES
write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
listen=YES
no_anon_password=YES
anon_root=/srv/ftp


 当我打破地图并将部分缩进为两个不同的语句时

>>> ff= sc.textFile("ftp://192.168.125.124/new.txt")
>>> df = ff.map(lambda s: len(s))
>>> df.reduce(lambda a, b: a + b)


地图部分运行正常但我在reduce上得到了相同的错误。 我运行了其他正常工作,这些工作不需要成功完成集群上的外部数据集。如

>>> data=[f for x in xrange(10000)]
>>> distData=sc.parallelize(data);
>>>distData.reduce(lambda a, b: a + b)


现在请告诉我如何解决这个问题以及我做错了什么。我可以使用hdfs,但我想知道使用ftp有什么问题。

2 个答案:

答案 0 :(得分:2)

查看this

您的网址格式应为ftp://username:password@host/file。对于匿名登录,请使用anonymous作为用户,密码可以是任何内容,它不应为空。

ff= sc.textFile("ftp://anonymous:pandamagic@192.168.125.124/new.txt")

您之所以仅在reduce部分看到错误,是因为map是转换而reduce是一个动作。只有在对其调用操作时,才会实现RDD。

答案 1 :(得分:1)

看来你有两个问题:

  • 如何形成ftp网址
  • ftp
  • 不支持搜索功能

第一个问题在上面得到了很好的解答。

对于搜索问题,谁可能希望查看sc.wholeTextFiles("ftp://anonymous:pandamagic@192.168.125.124/new.txt"),这将允许您将文本文件检索为单个字符串。

或者,您可以使用sc.wholeTextFiles("ftp://anonymous:pandamagic@192.168.125.124/new.txt").values

创建行的RDD

希望这有帮助