簡體   English   中英

將一個大的 tar.gz 文件分成多個小的 tar.gz 文件

[英]Break a large tar.gz file into multiple smaller tar.gz files

在 spark 中處理大於 1gb 的 tar.gz 文件時出現OutOfMemoryError

為了克服這個錯誤,我嘗試使用“拆分”命令將 tar.gz 分成多個部分,結果發現每個拆分本身並不是一個 tar.gz,因此不能這樣處理。

dir=/dbfs/mnt/data/temp
b=524288000
for file in /dbfs/mnt/data/*.tar.gz; 
do 
a=$(stat -c%s "$file");
if [[ "$a" -gt "$b" ]] ; then 
split -b 500M -d --additional-suffix=.tar.gz $file "${file%%.*}_part"
mv $file $dir
fi
done

嘗試處理拆分文件時出錯

Caused by: java.io.EOFException
    at org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream.read(GzipCompressorInputStream.java:281)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
    at org.apache.commons.compress.archivers.tar.TarArchiveInputStream.read(TarArchiveInputStream.java:590)
    at org.apache.commons.io.input.ProxyInputStream.read(ProxyInputStream.java:98)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.Reader.read(Reader.java:140)
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2001)
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1980)
    at org.apache.commons.io.IOUtils.copy(IOUtils.java:1957)
    at org.apache.commons.io.IOUtils.copy(IOUtils.java:1907)
    at org.apache.commons.io.IOUtils.toString(IOUtils.java:778)
    at org.apache.commons.io.IOUtils.toString(IOUtils.java:803)
    at linea3796c25fa964697ba042965141ff28825.$read$$iw$$iw$$iw$$iw$$iw$$iw$Unpacker$$anonfun$apply$1.apply(command-2152765781429277:33)
    at linea3796c25fa964697ba042965141ff28825.$read$$iw$$iw$$iw$$iw$$iw$$iw$Unpacker$$anonfun$apply$1.apply(command-2152765781429277:31)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:418)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1233)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1223)
    at scala.collection.immutable.Stream.foreach(Stream.scala:595)
    at scala.collection.TraversableOnce$class.toMap(TraversableOnce.scala:316)
    at scala.collection.AbstractTraversable.toMap(Traversable.scala:104)
    at linea3796c25fa964697ba042965141ff28825.$read$$iw$$iw$$iw$$iw$$iw$$iw$Unpacker$.apply(command-2152765781429277:34)
    at linea3796c25fa964697ba042965141ff28827.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(command-2152765781429278:3)
    at linea3796c25fa964697ba042965141ff28827.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(command-2152765781429278:3)

我有 go 大小高達 4GB 的 tar.gz 文件,每個文件最多可以包含 7000 json 大小從 1mb 到 50mb 不等的文件。

如果我想將大的 tar.gz 文件分成小的 tar.gz 文件是我解壓縮的唯一選擇,然后以某種方式根據文件大小或文件數重新壓縮? ——“是這樣嗎?”

普通 gzip 文件不可分割。 GZip Tar 檔案更難處理。 Spark 可以處理 gzipped json 文件,但不能處理 gzipped tar 文件而不是 tar 文件。 Spark 可以處理每個最大約 2GB 的二進制文件。 Spark 可以處理連接在一起的 JSON

我建議使用 Pandas UDF 或 a.pipe() 運算符來處理每個 tar gzip 文件(每個工作人員一個)。 每個工作人員將以流方式解壓縮、解壓縮和處理每個 JSON 文檔,永遠不會填充 memory。希望您有足夠的源文件來並行運行它並看到加速。

您可能想要探索流式傳輸方法,以將壓縮的 JSON 文件遞增地交付到 ADLS Gen 2 / S3,並使用 Databricks Auto Loader 功能在文件到達后立即加載和處理。

還回答了這個問題How to load tar.gz files in streaming datasets? 看起來很有前途。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM