2013-01-08 68 views
13

我有一個非常大的文件壓縮與坐在磁盤上的gzip。生產環境是基於「雲」的,因此存儲性能很差,但CPU很好。以前我們的數據處理流程開始於gzip -dc從磁盤流式傳輸數據。隨機訪問gzip文件?

現在,爲了平行工作,我想要運行多個管道,每個管道都需要一對字節偏移量 - 開始和結束 - 並獲取該文件的大塊。用一個普通的文件,這可以通過headtail來實現,但是我不知道如何用壓縮文件有效地完成它;如果我gzip -dc和管道head,接近文件末尾的偏移對將緩慢地解壓縮,浪費地搜索整個文件。

所以我的問題是關於gzip算法 - 理論上可能尋求在底層文件中的字節偏移量或獲取它的任意塊,而沒有解壓到整個文件的全部影響到那一點?如果不是,我怎麼可以有效地對一個文件進行分區以便多個進程進行「隨機」訪問,同時最大限度地減少I/O吞吐量開銷?

回答

11

你不能用gzip做到這一點,但你可以用bzip2來做到這一點,它是塊而不是基於流的 - 這就是Hadoop DFS如何拆分和並行化在MapReduce中使用不同映射器的大文件的讀取算法。也許將文件重新壓縮爲bz2是有意義的,所以你可以利用這個優勢;這比用一些臨時的方式來整理文件要容易一些。

我發現,是在Hadoop中實現這一點,這裏的補丁:https://issues.apache.org/jira/browse/HADOOP-4012

下面是關於該主題的另一個帖子:BZip2 file read in Hadoop

或許瀏覽Hadoop的源代碼會給你如何閱讀bzip2的一個想法文件按塊。

+0

您首先需要依次讀取bzip2文件以查找塊。然後你可以單獨訪問它們。 gzip格式也可以做到這一點。 –

+0

我不認爲你提到的是隨機訪問壓縮文件的最佳方式,請參閱本文:http://blastedbio.blogspot.com/2011/11/bgzf-blocked-bigger-better-gzip.html和Hadoop中的這個問題跟蹤器:https://issues.apache.org/jira/browse/HADOOP-4012 –

+0

正如我在我的回答中所說的,您可以準備一個gzip文件以優化隨機訪問。隨機訪問的一些應用程序控制gzip文件的創建,在這種情況下,您將爲此目的準備gzip文件並同時構建索引。有些應用程序不能控制gzip文件的創建,在這種情況下,您需要解壓縮一次才能創建索引。 –

7

gzip確實希望能夠從頭開始流式傳輸文件。你不能從中間開始。

你可以做的是將文件拆分成分段壓縮的塊,然後連接在一起,分成gzip。您可以選擇任意大小,例如10MB或100MB。然後在包含所需字節偏移量的塊的開始處開始解壓縮。由於gzip這個鮮爲人知的功能(即解壓縮一個文件,這個文件是幾個較小的gzip文件的連接產生與解壓縮每個較小文件並將結果連接在一起相同的輸出),分段壓縮的大文件也可以工作與標準gzip -d/gunzip,如果你下載整個事情。

棘手的部分:您必須維護一個包含大文件中每個壓縮塊起始字節偏移量的索引。

+2

只要您從頭開始解壓縮一次,並構建入口點,就可以在gzip流的中間開始。或者如果您在壓縮時已經達到了入口點。 –

+0

這真的很有趣,@MarkAdler,感謝您的提示。您*必須將32KiB的數據與每個訪問點一起存儲在您的索引中,但如果訪問點之間的距離很大,我想這可能是確定的。 – Celada

+0

正確。雖然如果你在創建gzip文件的控制下,那麼你可以放入不需要32K的無歷史入口點。 pigz(一個並行gzip壓縮器)使用-i選項執行此操作。 –

18

是的,您可以通過按順序讀取整個東西並構建索引來隨機訪問gzip文件。請參閱zlib分配中的examples/zran.c

如果您正在控制創建gzip文件,那麼您可以通過構建隨機訪問入口點並在壓縮時構建索引來爲此目的優化文件。

您也可以通過使用Z_SYNC_FLUSH隨後Z_FULL_FLUSH中的zlib的deflate()插入兩個標記,使下一個模塊獨立於先前數據的創建標記一個gzip文件。這會減少壓縮,但如果你不經常這樣做的話,壓縮比不會太大。例如。每兆字節一次應該有非常小的影響。然後你可以搜索一個9字節的標記(與bzip2的6字節標記相比,誤報的可能性更小):00 00 ff ff 00 00 00 ff ff

+1

是否有關於使用zran的教程;即如何使用它來索引gzip文件並隨後訪問我選擇的行號(或字符數?)?我認爲這是我一直在尋找的銀彈。 –

+1

不,除了源文件中的註釋以外沒有其他內容。您需要閱讀'build_index()'和'extract()'的註釋,並且可以在main()中看到它們的使用示例。 –

+0

另外下面的博客文章可能在這裏感興趣:http://lh3.github.io/2014/07/05/random-access-to-zlib-compressed-files/ – PhiS