如何在sc.textFile中加载本地文件,而不是HDFS

8 浏览
0 Comments

如何在sc.textFile中加载本地文件,而不是HDFS

我正在跟随那个很棒的Spark教程,所以我在46分00秒尝试加载README.md,但是失败了。我做的是这样的:\n

$ sudo docker run -i -t -h sandbox sequenceiq/spark:1.1.0 /etc/bootstrap.sh -bash
bash-4.1# cd /usr/local/spark-1.1.0-bin-hadoop2.4
bash-4.1# ls README.md
README.md
bash-4.1# ./bin/spark-shell
scala> val f = sc.textFile("README.md")
14/12/04 12:11:14 INFO storage.MemoryStore: ensureFreeSpace(164073) called with curMem=0, maxMem=278302556
14/12/04 12:11:14 INFO storage.MemoryStore: Block broadcast_0 stored as values in memory (estimated size 160.2 KB, free 265.3 MB)
f: org.apache.spark.rdd.RDD[String] = README.md MappedRDD[1] at textFile at :12
scala> val wc = f.flatMap(l => l.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)
org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://sandbox:9000/user/root/README.md
    at org.apache.hadoop.mapred.FileInputFormat.singleThreadedListStatus(FileInputFormat.java:285)

\n我该如何加载那个README.md

0
0 Comments

在使用sc.textFile加载本地文件而不是HDFS时,问题的出现原因是文件位于Spark主节点上。解决方法有两种:

1. 在本地模式下启动spark-shell,然后使用file://前缀加载文件。

$ spark-shell --master=local
scala> val df = spark.read.json("file:///usr/lib/spark/examples/src/main/resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
scala> df.show()
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

2. 可以先将文件从本地文件系统复制到HDFS,然后在其默认模式下启动Spark(例如,在使用AWS EMR时使用YARN),直接读取文件。

$ hdfs dfs -mkdir -p /hdfs/spark/examples
$ hadoop fs -put /usr/lib/spark/examples/src/main/resources/people.json /hdfs/spark/examples
$ hadoop fs -ls /hdfs/spark/examples
Found 1 items
-rw-r--r--   1 hadoop hadoop         73 2017-05-01 00:49 /hdfs/spark/examples/people.json
$ spark-shell
scala> val df = spark.read.json("/hdfs/spark/examples/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
scala> df.show()
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

以上两种方法是解决这个问题的方法之一。

0
0 Comments

问题的出现原因是:在使用sc.textFile加载本地文件时,有些用户会将文件路径写成$SPARK_HOME/file:///path/to/file这样的形式,以为file:///表示当前用户的home目录,然而实际上file:///表示的是执行JVM看到的文件系统的根目录。

解决方法是:将文件路径写成file:///path/to/file的形式,其中file:///表示的是执行JVM看到的文件系统的根目录。

下面是整理后的

在使用sc.textFile加载本地文件时,有些用户会将文件路径写成$SPARK_HOME/file:///path/to/file这样的形式,以为file:///表示当前用户的home目录,然而实际上file:///表示的是执行JVM看到的文件系统的根目录。

file:///是执行JVM看到的文件系统的根目录,而不是当前用户的home目录。根据RFC 8089中规定的URI格式,file://hostname/absolute/path,在本地情况下,hostname(authority)部分为空。

因此,解决方法是将文件路径写成file:///path/to/file的形式,其中file:///表示执行JVM看到的文件系统的根目录。希望这个解决方法能够帮助像我这样的新手节省一些时间。

0
0 Comments

在Spark中加载本地文件,而不是HDFS文件,可以使用sc.textFile("file:///path to the file/")来显式指定路径。出现错误的原因是Hadoop环境的设置。SparkContext.textFile在内部调用org.apache.hadoop.mapred.FileInputFormat.getSplits,该方法再调用org.apache.hadoop.fs.getDefaultUri,如果没有指定协议,则使用该方法读取Hadoop配置中的"fs.defaultFS"参数。如果设置了HADOOP_CONF_DIR环境变量,该参数通常设置为"hdfs://...",否则设置为"file://"。

有人问如何在Java中实现这一功能,他发现没有相应的方法,因此对于从简单文件系统加载文件的路径设置非常困扰。有人回答说,可以使用spark-submit命令的--file选项来传递文件路径,这样可以在提交任务时指定路径,以便执行器可以看到路径。

还某些情况下在Windows上指定路径时,"file:///C:\\Xiang\\inputfile"file:////C:\\Xiang\\inputfile都可以工作,而"file://C:\\Xiang\\inputfile在Java代码中不起作用。在Linux上应该如何设置路径前缀呢?是file:///(三个斜杠)还是file:////(四个斜杠)?file:////在Linux上也能工作吗?

检查源代码后发现,static final URI NAME = URI.create("file:///");,因此路径前缀应该硬编码为file:///(三个斜杠)。但我仍然不明白为什么file:////(四个斜杠)也能工作。

有人询问是否可以在Java代码中添加指向源代码行的链接,提供了一个指向源代码的GitHub链接。

还某些情况下他的错误消息:java.lang.IllegalArgumentException: Wrong FS: file://C:\Xiang\cs_hdfs\csByDate\20190822/C:/Xiang/323Bit/bigfoot, expected: file:/// at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:645) at org.apache.hadoop.fs.RawLocalFileSystem.pathToFile(RawLocalFileSystem.java:80) at org.apache.hadoop.fs.RawLocalFileSystem.deprecatedGetFileStatus(RawLocalFileSystem.java:534) at org.apache.hadoop.fs.RawLocalFileSystem.getFileLinkStatusInternal(RawLocalFileSystem.java:752)

有人说他没有Windows电脑,并且有人询问如何在Java代码中检查是否设置了Hadoop环境。

0