5

Tôi nhận được dưới đây ngoại lệ khi một kích thước kỷ lục cá nhân là hơn 3GB 'Xử lý kích thước kỷ lục hơn 3GB trong spark

java.lang.IllegalArgumentException 
App > at java.nio.CharBuffer.allocate(CharBuffer.java:330) 
App > at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:792) 
App > at org.apache.hadoop.io.Text.decode(Text.java:412) 
App > at org.apache.hadoop.io.Text.decode(Text.java:389) 
App > at org.apache.hadoop.io.Text.toString(Text.java:280) 
App > at org.apache.spark.sql.execution.datasources.json.JsonFileFormat$$anonfun$createBaseRdd$1.apply(JsonFileFormat.scala:135) 
App > at org.apache.spark.sql.execution.datasources.json.JsonFileFormat$$anonfun$createBaseRdd$1.apply(JsonFileFormat.scala:135) 

Làm thế nào tôi có thể làm tăng kích thước bộ đệm cho một hồ sơ duy nhất?

+2

Có thể không hữu ích, nhưng đáng chú ý: ngay cả khi điều này là có thể làm (không chắc chắn), nó có thể không phải là cách tiếp cận đúng (sẽ được làm chậm và nguy hiểm). Bạn có thể tránh được một kích thước kỷ lục khổng lồ như vậy không? Làm thế nào nó đến được? Nếu đó là kết quả của một 'RDD.groupByKey', ví dụ, bạn có thể muốn thay thế nó bằng' reduceByKey' hoặc một số tập hợp khác. –

+0

Đây là tệp json có tất cả các bản ghi dưới dạng mảng json dưới một khóa. Tôi đang cố gắng làm phẳng nó. Nhưng tôi không thể thực hiện bất kỳ thao tác nào trên nó. Thậm chí không in lược đồ của mảng json. –

+1

Nếu bạn có thể đủ khả năng thay đổi cấu trúc của tệp JSON, chúng tôi có thể không chia tách "mảng lớn duy nhất" thành "mảng mảng" bằng một số chương trình utiliy trước khi bạn xử lý thêm không? – Marco99

Trả lời

0

Bạn có thể có một dòng rất lớn trong tệp chứa mảng. Ở đây bạn nhận được một ngoại lệ bởi vì bạn đang cố gắng để xây dựng một CharBuffer đó là quá lớn (rất có thể là một số nguyên đã trở thành tiêu cực sau khi đi ra khỏi ràng buộc). Kích thước chuỗi/chuỗi tối đa trong java là 2^31-1 (Integer.MAX_VALUE -1) (xem this thread). Bạn nói rằng bạn có một bản ghi 3GB, với 1B mỗi char, mà làm cho 3 tỷ ký tự đó là hơn 2^31 đó là gần bằng 2 tỷ.

Hai điều bạn có thể làm là hơi khó hiểu nhưng vì bạn chỉ có một khóa với một mảng lớn, nó có thể hoạt động. tệp json của bạn có thể trông giống như:

{ 
    "key" : ["v0", "v1", "v2"... ] 
} 

hay như thế này nhưng tôi nghĩ rằng trong trường hợp của bạn nó là cựu:

{ 
    "key" : [ 
     "v0", 
     "v1", 
     "v2", 
     ... 
    ] 
} 

Vì vậy bạn có thể thử thay đổi dòng delimiter được sử dụng bởi hadoop đến "" là here. Về cơ bản, họ làm điều đó như thế này:

import org.apache.hadoop.io.LongWritable 
import org.apache.hadoop.io.Text 
import org.apache.hadoop.conf.Configuration 
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat 

def nlFile(path: String) = { 
    val conf = new Configuration 
    conf.set("textinputformat.record.delimiter", ",") 
    sc.newAPIHadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text], conf) 
      .map(_._2.toString) 
} 

Sau đó, bạn có thể đọc mảng của bạn và sẽ chỉ phải loại bỏ các dấu ngoặc JSON một mình với một cái gì đó như thế này:

nlFile("...") 
    .map(_.replaceAll("^.*\\[", "").replaceAll("\\].*$","")) 

Lưu ý rằng bạn sẽ phải cẩn thận hơn nếu hồ sơ của bạn có thể chứa các ký tự "[" và "]" nhưng đây là ý tưởng.

Các vấn đề liên quan