วิธีโหลดไฟล์ในเครื่องใน sc.textFile แทน HDFS


100

ฉันกำลังติดตามบทแนะนำการจุดประกายที่ยอดเยี่ยม

ดังนั้นฉันพยายามที่ 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อย่างไร

คำตอบ:


177

sc.textFile("file:///path to the file/")ลองระบุอย่างชัดเจน ข้อผิดพลาดเกิดขึ้นเมื่อตั้งค่าสภาพแวดล้อม Hadoop

SparkContext.textFile เรียกภายในorg.apache.hadoop.mapred.FileInputFormat.getSplitsซึ่งจะใช้org.apache.hadoop.fs.getDefaultUriหากไม่มีสคีมา วิธีนี้อ่านพารามิเตอร์ "fs.defaultFS" ของ Hadoop conf หากคุณตั้งค่าตัวแปรสภาวะแวดล้อม HADOOP_CONF_DIR พารามิเตอร์มักจะตั้งเป็น "hdfs: // ... "; หรือ "file: //"


คุณบังเอิญรู้วิธีทำกับ Java หรือไม่? ฉันไม่เห็นวิธีการ พบว่ามันน่าหงุดหงิดมากที่ไม่มีวิธีง่ายๆในการกำหนดเส้นทางในการโหลดไฟล์จากระบบไฟล์แบบธรรมดา
Brad Ellis

ตอบตัวเอง มีสวิตช์ - ไฟล์ที่คุณส่งผ่านด้วย spark-submit ดังนั้นเส้นทางของไฟล์จึงสามารถเข้ารหัสได้ยากหรืออย่างไรก็ตามการกำหนดค่าของคุณถูกตั้งค่าสำหรับแอป แต่คุณส่งสัญญาณเส้นทางนั้นด้วย เมื่อคุณส่งเพื่อให้ผู้ดำเนินการสามารถมองเห็นเส้นทางได้
Brad Ellis

24

คำตอบของกอนเบนั้นยอดเยี่ยมมาก แต่ก็ยังคงฉันต้องการที่จะพูดถึงว่าfile:///= ไม่~/../../ $SPARK_HOMEหวังว่านี่จะช่วยประหยัดเวลาสำหรับมือใหม่อย่างฉันได้บ้าง


4
file:///เป็นโฟลเดอร์รากของระบบไฟล์ตามที่เห็นในการเรียกใช้งาน JVM ไม่ใช่สองระดับที่อยู่เหนือโฟลเดอร์บ้าน รูปแบบ URI ที่ระบุไว้ในRFC 8089file://hostname/absolute/pathคือ ในกรณีท้องถิ่นองค์ประกอบhostname(อำนาจ) ว่างเปล่า
Hristo Iliev

18

แม้ว่า Spark จะรองรับการโหลดไฟล์จากระบบไฟล์ภายในเครื่อง แต่คุณต้องใช้ไฟล์ที่มีอยู่ในเส้นทางเดียวกันบนทุกโหนดในคลัสเตอร์ของคุณ

ระบบไฟล์เครือข่ายบางระบบเช่น NFS, AFS และเลเยอร์ NFS ของ MapR จะเปิดเผยต่อผู้ใช้ในฐานะระบบไฟล์ทั่วไป

หากข้อมูลของคุณอยู่ในระบบใดระบบหนึ่งแล้วคุณสามารถใช้ข้อมูลนี้เป็นอินพุตได้โดยระบุไฟล์: // path; Spark จะจัดการมันตราบใดที่ระบบไฟล์ติดตั้งที่พา ธ เดียวกันในแต่ละโหนด ทุกโหนดจำเป็นต้องมีเส้นทางเดียวกัน

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

หากไฟล์ของคุณไม่ได้อยู่ในโหนดทั้งหมดในคลัสเตอร์คุณสามารถโหลดลงในไดรเวอร์ได้โดยไม่ต้องผ่าน Spark จากนั้นเรียกแบบขนานเพื่อแจกจ่ายเนื้อหาให้กับผู้ปฏิบัติงาน

โปรดใส่ไฟล์: // ไว้ด้านหน้าและการใช้ "/" หรือ "\" ตามระบบปฏิบัติการ


1
มีวิธีใดบ้างที่ Spark จะคัดลอกข้อมูลจากไดเรกทอรี $ SPARK_HOME ไปยังโหนดคอมพิวเตอร์ทั้งหมดโดยอัตโนมัติ หรือคุณจำเป็นต้องทำด้วยตนเอง?
Matthias

ซอร์สโค้ดจุดประกายจัดการรูปแบบระบบไฟล์ที่แตกต่างกันอยู่ที่ไหน
Saher Ahwal

12

คุณต้องระบุเส้นทางของไฟล์เป็น"file: /// directory / file"

ตัวอย่าง:

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

12

ความสนใจ:

ตรวจสอบให้แน่ใจว่าคุณใช้ประกายไฟในโหมดท้องถิ่นเมื่อคุณโหลดข้อมูลจากท้องถิ่น ( sc.textFile("file:///path to the file/")) Caused by: java.io.FileNotFoundException: File file:/data/sparkjob/config2.properties does not existหรือคุณจะได้รับข้อผิดพลาดเช่นนี้ ตัวดำเนินการ Becasuse ที่ทำงานกับคนงานต่างกันจะไม่พบไฟล์นี้ในเส้นทางภายในเครื่อง


11

หากไฟล์อยู่ในโหนดหลัก 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 ในโหมดเริ่มต้น (เช่น YARN ในกรณีที่ใช้ AWS EMR) เพื่ออ่านไฟล์โดยตรง

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

9

ฉันมีไฟล์ชื่อ NewsArticle.txt บนเดสก์ท็อป

ใน Spark ฉันพิมพ์ว่า:

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

ฉันต้องการเปลี่ยนอักขระ \ to / ทั้งหมดสำหรับ filepath

เพื่อทดสอบว่าใช้งานได้หรือไม่ฉันพิมพ์:

textFile.foreach(println)

ฉันใช้ Windows 7 และไม่ได้ติดตั้ง Hadoop


5

สิ่งนี้ได้รับการกล่าวถึงในรายชื่อผู้รับจดหมายจุดประกายแล้วโปรดอ้างอิงอีเมลนี้

คุณควรใช้hadoop fs -put <localsrc> ... <dst>คัดลอกไฟล์ลงในhdfs:

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

5

สิ่งนี้เกิดขึ้นกับฉันด้วย Spark 2.3 พร้อมกับ Hadoop ที่ติดตั้งภายใต้โฮมไดเร็กทอรีผู้ใช้ "hadoop" ทั่วไปเนื่องจากทั้ง Spark และ Hadoop ได้รับการติดตั้งภายใต้ไดเร็กทอรีทั่วไปเดียวกันโดยค่าเริ่มต้น Spark จะพิจารณาโครงร่างเป็นhdfsและเริ่มค้นหาไฟล์อินพุต ภายใต้ HDFS ตามที่ระบุโดยfs.defaultFSใน core-site.xmlHadoop file:///<absoloute path to file>ภายใต้กรณีเช่นนี้เราจำเป็นต้องระบุอย่างชัดเจนโครงการเป็น


0

นี่คือวิธีแก้ปัญหาสำหรับข้อผิดพลาดนี้ที่ฉันได้รับบนคลัสเตอร์ Spark ที่โฮสต์ใน Azure บนคลัสเตอร์ windows:

โหลดไฟล์ดิบ HVAC.csv แยกวิเคราะห์โดยใช้ฟังก์ชัน

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

เราใช้ (wasb: ///) เพื่ออนุญาตให้ Hadoop เข้าถึงไฟล์ที่เก็บข้อมูลบล็อกสีฟ้าและเครื่องหมายทับสามตัวเป็นการอ้างอิงสัมพัทธ์กับโฟลเดอร์คอนเทนเนอร์โหนดที่กำลังทำงานอยู่

ตัวอย่างเช่น: หากเส้นทางสำหรับไฟล์ของคุณใน File Explorer ในแดชบอร์ดคลัสเตอร์ Spark คือ:

sflcc1 \ sflccspark1 \ HdiSamples \ SensorSampleData \ hvac

เพื่ออธิบายเส้นทางมีดังนี้: sflcc1: คือชื่อของบัญชีหน่วยเก็บข้อมูล sflccspark: คือชื่อโหนดคลัสเตอร์

ดังนั้นเราจึงอ้างถึงชื่อโหนดคลัสเตอร์ปัจจุบันด้วยเครื่องหมายทับสามตัวที่สัมพันธ์กัน

หวังว่านี่จะช่วยได้


0

หากคุณพยายามอ่านไฟล์ในรูปแบบ HDFS พยายามตั้งค่าเส้นทางใน SparkConf

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

โปรดเพิ่มการเยื้อง 4 ช่องว่าง / แท็บลงในโค้ดของคุณเพื่อให้ได้รับการจัดรูปแบบเป็นรหัส ขอแสดงความนับถือ
YakovL

0

คุณไม่จำเป็นต้องใช้ sc.textFile (... ) เพื่อแปลงไฟล์ในเครื่องเป็นดาต้าเฟรม ทางเลือกหนึ่งคือการอ่านไฟล์ภายในเครื่องทีละบรรทัดจากนั้นแปลงเป็น Spark Dataset นี่คือตัวอย่างสำหรับเครื่อง Windows ใน Java:

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);

ตอนนี้คุณสามารถใช้ dataframe dataในโค้ดของคุณได้แล้ว


0

ฉันลองทำสิ่งต่อไปนี้และใช้งานได้จากระบบไฟล์ในเครื่องของฉัน .. โดยทั่วไปแล้ว spark สามารถอ่านจากเส้นทางในเครื่อง HDFS และ AWS S3

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

-6

ลอง

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

scala> val f = sc.textFile("./README.md") 14/12/04 12:54:33 INFO storage.MemoryStore: ensureFreeSpace(81443) called with curMem=164073, maxMem=278302556 14/12/04 12:54:33 INFO storage.MemoryStore: Block broadcast_1 stored as values in memory (estimated size 79.5 KB, free 265.2 MB) f: org.apache.spark.rdd.RDD[String] = ./README.md MappedRDD[5] 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
Jas

คุณสามารถทำpwdในเปลือกทุบตีbash-4.1#
Soumya Simanta

ทุบตี-4.1 # pwd /usr/local/spark-1.1.0-bin-hadoop2.4
Jas

สิ่งนี้ใช้ได้กับฉันใน spark โดยไม่ต้อง hadoop / hdfs อย่างไรก็ตามดูเหมือนว่าจะไม่ทำงานกับ OP เนื่องจากทำให้เกิดข้อผิดพลาดในการถ่ายโอนข้อมูล
พอล
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.