Cách tải tệp cục bộ trong sc.textFile, thay vì HDFS


100

Tôi đang làm theo hướng dẫn tuyệt vời về tia lửa

vì vậy tôi đang cố gắng ở 46 phút: 00 để tải README.mdnhưng không thành công những gì tôi đang làm là:

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

làm thế nào tôi có thể tải nó README.md?

Câu trả lời:


177

Hãy thử chỉ định rõ ràng sc.textFile("file:///path to the file/"). Lỗi xảy ra khi môi trường Hadoop được thiết lập.

SparkContext.textFile gọi nội bộ org.apache.hadoop.mapred.FileInputFormat.getSplits, lần lượt sử dụng org.apache.hadoop.fs.getDefaultUrinếu lược đồ vắng mặt. Phương thức này đọc tham số "fs.defaultFS" của Hadoop conf. Nếu bạn đặt biến môi trường HADOOP_CONF_DIR, tham số thường được đặt là "hdfs: // ..."; nếu không thì "tệp: //".


Bạn có tình cờ biết cách làm điều này với Java không? Tôi không thấy một phương pháp. Rất bực bội khi không có cách nào dễ dàng để đưa ra một đường dẫn để tải một tệp từ một hệ thống tệp đơn giản.
Brad Ellis

tự trả lời. Có một công tắc - tệp mà bạn vượt qua với trình gửi tia lửa. Vì vậy, đường dẫn tệp có thể được mã hóa cứng hoặc tuy nhiên cấu hình của bạn được thiết lập cho ứng dụng, nhưng bạn cũng báo hiệu đường dẫn đó. khi bạn gửi để những người thực thi có thể nhìn thấy đường dẫn.
Brad Ellis

24

câu trả lời của gonbe là tuyệt vời. Nhưng tôi vẫn muốn đề cập đến điều đó file:///= ~/../../, không phải $SPARK_HOME. Hy vọng điều này có thể tiết kiệm thời gian cho những người mới như tôi.


4
file:///là thư mục gốc của hệ thống tệp như được thấy bởi JVM đang thực thi, không phải là hai cấp trên thư mục chính. Định dạng URI như được chỉ định trong RFC 8089file://hostname/absolute/path. Trong trường hợp cục bộ, hostnamethành phần (quyền hạn) trống.
Hristo Iliev

17

Mặc dù Spark hỗ trợ tải tệp từ hệ thống tệp cục bộ, nhưng nó yêu cầu các tệp có sẵn tại cùng một đường dẫn trên tất cả các nút trong cụm của bạn.

Một số hệ thống tệp mạng, như NFS, AFS và lớp NFS của MapR, được hiển thị với người dùng như một hệ thống tệp thông thường.

Nếu dữ liệu của bạn đã nằm trong một trong các hệ thống này, thì bạn có thể sử dụng nó làm đầu vào bằng cách chỉ định một tệp: // path; Spark sẽ xử lý nó miễn là hệ thống tệp được gắn trên cùng một đường dẫn trên mỗi nút. Mọi nút cần có cùng một đường dẫn

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

Nếu tệp của bạn chưa có trên tất cả các nút trong cụm, bạn có thể tải nó cục bộ trên trình điều khiển mà không cần thông qua Spark và sau đó gọi song song để phân phối nội dung cho công nhân

Chú ý đặt tệp: // ở phía trước và sử dụng "/" hoặc "\" theo hệ điều hành.


1
Có cách nào mà Spark sẽ tự động sao chép dữ liệu từ thư mục $ SPARK_HOME sang tất cả các nút máy tính không. Hay bạn cần phải làm điều đó theo cách thủ công?
Matthias,

mã nguồn tia lửa xử lý các định dạng hệ thống tệp khác nhau ở đâu?
Saher Ahwal

12

Bạn chỉ cần chỉ định đường dẫn của tệp là "tệp: /// thư mục / tệp"

thí dụ:

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

12

Chú ý:

Đảm bảo rằng bạn chạy spark ở chế độ cục bộ khi tải dữ liệu từ local ( sc.textFile("file:///path to the file/")), nếu không bạn sẽ gặp lỗi như thế này Caused by: java.io.FileNotFoundException: File file:/data/sparkjob/config2.properties does not exist. Sử dụng các trình thực thi chạy trên các công nhân khác nhau sẽ không tìm thấy tệp này trong đường dẫn cục bộ của nó.


11

Nếu tệp nằm trong nút chính Spark của bạn (ví dụ: trong trường hợp sử dụng AWS EMR), thì trước tiên hãy khởi chạy spark-shell ở chế độ cục bộ.

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

Ngoài ra, trước tiên, bạn có thể sao chép tệp sang HDFS từ hệ thống tệp cục bộ và sau đó khởi chạy Spark ở chế độ mặc định (ví dụ: YARN trong trường hợp sử dụng AWS EMR) để đọc tệp trực tiếp.

$ 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

Tôi có một tệp có tên NewsArticle.txt trên Máy tính để bàn của mình.

Trong Spark, tôi đã gõ:

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

Tôi cần thay đổi tất cả ký tự \ thành / cho đường dẫn tệp.

Để kiểm tra xem nó có hoạt động không, tôi đã nhập:

textFile.foreach(println)

Tôi đang chạy Windows 7 và tôi chưa cài đặt Hadoop.


5

Điều này đã được thảo luận trong danh sách gửi thư spark, và vui lòng tham khảo thư này .

Bạn nên sử dụng hadoop fs -put <localsrc> ... <dst>sao chép tệp vào hdfs:

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

5

Điều này đã xảy ra với tôi với Spark 2.3 với Hadoop cũng được cài đặt dưới sự chung "hadoop" directory.Since dùng nhà cả Spark và Hadoop đã được cài đặt trong thư mục chung cùng, Spark theo mặc định coi chương trình như hdfs, và bắt đầu tìm kiếm các tập tin đầu vào dưới hdfs như được chỉ định bởi fs.defaultFSHadoop's core-site.xml. Trong những trường hợp như vậy, chúng ta cần chỉ định rõ ràng lược đồ là file:///<absoloute path to file>.


0

Đây là giải pháp cho lỗi này mà tôi gặp phải trên cụm Spark được lưu trữ trong Azure trên cụm cửa sổ:

Tải tệp HVAC.csv thô, phân tích cú pháp bằng hàm

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

Chúng tôi sử dụng (wasb: ///) để cho phép Hadoop truy cập vào tệp lưu trữ blog azure và ba dấu gạch chéo là một tham chiếu tương đối đến thư mục vùng chứa nút đang chạy.

Ví dụ: Nếu đường dẫn cho tệp của bạn trong File Explorer trong bảng điều khiển cụm Spark là:

sflcc1 \ sflccspark1 \ HdiSamples \ SensorSampleData \ hvac

Vì vậy, để mô tả đường dẫn như sau: sflcc1: là tên của tài khoản lưu trữ. sflccspark: là tên nút cụm.

Vì vậy, chúng tôi đề cập đến tên nút cụm hiện tại với ba dấu gạch chéo tương đối.

Hi vọng điêu nay co ich.


0

Nếu bạn đang cố gắng đọc tập tin dạng HDFS. thử thiết lập đường dẫn trong SparkConf

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

Vui lòng thêm thụt lề 4 dấu cách / tab vào mã của bạn để mã được định dạng dưới dạng mã. Trân trọng
YakovL 19/09/17

0

Bạn không phải sử dụng sc.textFile (...) để chuyển đổi các tệp cục bộ thành khung dữ liệu. Một trong các tùy chọn là đọc từng dòng một tệp cục bộ và sau đó chuyển đổi nó thành Tập dữ liệu Spark. Đây là một ví dụ cho máy Windows trong 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);

Bây giờ bạn có thể sử dụng khung dữ liệu datatrong mã của mình.


0

Tôi đã thử cách sau và nó hoạt động từ hệ thống tệp cục bộ của tôi .. Về cơ bản tia lửa có thể đọc từ đường dẫn cục bộ, HDFS và AWS S3

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

-6

thử

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

Bạn có thể làm điều gì pwdtrên vỏ bashbash-4.1#
Soumya Simanta

bash-4.1 # pwd /usr/local/spark-1.1.0-bin-hadoop2.4
Jas

Điều này hoạt động đối với tôi trên spark mà không có hadoop / hdfs. Tuy nhiên, nó dường như không hoạt động đối với OP, vì nó đã tạo cho họ một kết xuất lỗi.
Paul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.