繁体   English   中英

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

[英]How to load local file in sc.textFile, instead of HDFS

我正在关注很棒的Spark教程

所以我正在尝试在46m:00s加载README.md但无法执行以下操作:

$ 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 <console>: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)

如何加载README.md

尝试显式指定sc.textFile("file:///path to the file/") 设置Hadoop环境时会发生此错误。

SparkContext.textFile在内部调用org.apache.hadoop.mapred.FileInputFormat.getSplits ,如果缺少架构,则转而使用org.apache.hadoop.fs.getDefaultUri 此方法读取Hadoop conf的“ fs.defaultFS”参数。 如果设置HADOOP_CONF_DIR环境变量,则该参数通常设置为“ hdfs:// ...”; 否则为“ file://”。

贡贝的答案非常好。 但我仍然要提到file:/// = ~/../../ ,而不是$SPARK_HOME 希望这可以为像我这样的新手节省一些时间。

尽管Spark支持从本地文件系统加载文件,但它要求文件在群集中所有节点上的同一路径上可用。

一些网络文件系统(例如NFS,AFS和MapR的NFS层)作为常规文件系统向用户公开。

如果您的数据已经在这些系统之一中,则只需指定file://路径就可以将其用作输入。 只要文件系统安装在每个节点的相同路径上,Spark就会处理它。 每个节点都必须具有相同的路径

 rdd = sc.textFile("file:///path/to/file")

如果文件尚未位于集群中的所有节点上,则可以在不通过Spark的情况下在驱动程序上本地加载文件,然后调用parallelize将内容分发给worker

请注意将file://放在前面,并根据操作系统使用“ /”或“ \\”。

您只需要将文件的路径指定为“ file:/// directory / file”

例:

val textFile = sc.textFile("file:///usr/local/spark/README.md")

注意:

从本地加载数据时,请确保在本地模式下运行spark( sc.textFile("file:///path to the file/") ),否则会收到类似的错误, Caused by: java.io.FileNotFoundException: File file:/data/sparkjob/config2.properties does not exist 因为在不同工作程序上运行的执行程序不会在本地路径中找到此文件。

我的桌面上有一个名为NewsArticle.txt的文件。

在Spark中,我输入:

val textFile= sc.textFile(“file:///C:/Users/582767/Desktop/NewsArticle.txt”)

我需要将文件路径的所有\\更改为/字符。

为了测试它是否有效,我输入了:

textFile.foreach(println)

我正在运行Windows 7,但未安装Hadoop。

这已经在spark邮件列表中讨论过了,请参阅此邮件

您应该使用hadoop fs -put <localsrc> ... <dst>将文件复制到hdfs

${HADOOP_COMMON_HOME}/bin/hadoop fs -put /path/to/README.md README.md

如果文件位于您的Spark主节点中(例如,在使用AWS EMR的情况下),请首先以本地模式启动spark-shell。

$ 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|
+----+-------+

或者,您可以先将文件从本地文件系统复制到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|
+----+-------+

对于Spark 2.3来说,这已经发生了,并且Hadoop也安装在公用的“ hadoop”用户主目录下。由于Spark和Hadoop都安装在同一公用目录下,因此Spark默认情况下将方案视为hdfs ,并开始查找输入Hadoop的core-site.xml fs.defaultFS指定的hdfs下的文件。 在这种情况下,我们需要将方案明确指定为file:///<absoloute path to file>

这是我在Windows群集上的Azure中托管的Spark群集上遇到的此错误的解决方案:

加载原始的HVAC.csv文件,使用函数进行解析

data = sc.textFile("wasb:///HdiSamples/SensorSampleData/hvac/HVAC.csv")

我们使用(wasb:///)允许Hadoop访问azure博客存储文件,三个斜杠是对正在运行的节点容器文件夹的相对引用。

例如:如果您在Spark群集仪表板的“文件资源管理器”中文件的路径为:

sflcc1 \\ sflccspark1 \\ HdiSamples \\ SensorSampleData \\ hvac

因此要描述的路径如下:sflcc1:是存储帐户的名称。 sflccspark:是集群节点名称。

因此,我们用相对的三个斜杠来引用当前的群集节点名称。

希望这可以帮助。

如果您尝试读取HDFS文件格式。 尝试在SparkConf中设置路径

 val conf = new SparkConf().setMaster("local[*]").setAppName("HDFSFileReader")
 conf.set("fs.defaultFS", "hdfs://hostname:9000")

您不必使用sc.textFile(...)将本地文件转换为数据帧。 选项之一是,逐行读取本地文件,然后将其转换为Spark Dataset。 这是Java中Windows机器的示例:

StructType schemata = DataTypes.createStructType(
            new StructField[]{
                    createStructField("COL1", StringType, false),
                    createStructField("COL2", StringType, false),
                    ...
            }
    );

String separator = ";";
String filePath = "C:\\work\\myProj\\myFile.csv";
SparkContext sparkContext = new SparkContext(new SparkConf().setAppName("MyApp").setMaster("local"));
JavaSparkContext jsc = new JavaSparkContext (sparkContext );
SQLContext sqlContext = SQLContext.getOrCreate(sparkContext );

List<String[]> result = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
    String line;
    while ((line = br.readLine()) != null) {
      String[] vals = line.split(separator);
      result.add(vals);
    }
 } catch (Exception ex) {
       System.out.println(ex.getMessage());
       throw new RuntimeException(ex);
  }
  JavaRDD<String[]> jRdd = jsc.parallelize(result);
  JavaRDD<Row> jRowRdd = jRdd .map(RowFactory::create);
  Dataset<Row> data = sqlContext.createDataFrame(jRowRdd, schemata);

现在,您可以在代码中使用数据框data

我尝试了以下操作,并且它可以从本地文件系统运行。基本上,spark可以从本地,HDFS和AWS S3路径读取

listrdd=sc.textFile("file:////home/cloudera/Downloads/master-data/retail_db/products")

尝试

val f = sc.textFile("./README.md")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM