替代太慢的 gzip -d 命令
我正在使用生產伺服器將大型數據集載入到Hadoop以從Hive表訪問。
我們正在載入電信部門的訂戶網路瀏覽數據。我們有大量使用**.csv.gz 壓縮**的文件(文件大小約為 300-500MB)
gzip
。假設一個文件如下:文件名:dna_file_01_21090702.csv.gz
內容:
A,B,C,2
D,E,F,3
我們解壓縮 50 個左右的文件並連接到一個文件。出於故障排除的目的,我們將文件名附加為每一行的第一列。
所以連接數據文件將是:
dna_file_01_21090702.csv.gz,A,B,C,2
dna_file_01_21090702.csv.gz,D,E,F,33
為此目的寫在下面的 bash 腳本中:
#!/bin/bash func_gen_new_file_list() { > ${raw_file_list} ls -U raw_directory| head -50 >> ${raw_file_list} } func_create_dat_file() { cd raw_directory gzip -d `cat ${raw_file_list}` awk '{printf "%s|%s\n",FILENAME,$0}' `cat ${raw_file_list}|awk -F".gz" '{print $1}'` >> ${data_file} } func_check_dir_n_load_data() { ## Code to copy data file to HDFS file system } ##___________________________ Main Function _____________________________ ##__Variable data_load_log_dir=directory raw_file_list=${data_load_log_dir}/raw_file_list_name data_file_name=dna_data_file_`date "+%Y%m%d%H%M%S"`.dat data_file=${data_load_log_dir}/${data_file_name} ##__Function Calls func_gen_new_file_list func_create_dat_file func_check_dir_n_load_data
現在的問題是
gzip -d
命令執行速度非常慢。我的意思是真的很慢。如果它解壓縮 50 個文件並製作連接的數據文件,大小將在 20-25GB 左右。解壓縮 50 個文件並將其連接到一個文件需要將近 1 個小時,這是巨大的。以這種速度,不可能處理一天內產生的所有數據。
我的生產伺服器(VM)非常強大。總核心為 44,RAM 為 256GB。硬碟也非常好和高性能。IOwait 在 0-5 左右。
我怎樣才能加快這個過程?的替代品是什麼
gzip -d
。有沒有其他方法可以更有效地連接數據文件。請注意,我們需要將文件名保存在記錄中,以便進行故障排除。否則,我們可以只使用
zcat
並附加到數據文件而根本不解壓縮。
有很多磁碟 I/O 可以用管道代替。獲取一個包含 50 個壓縮文件的
func_create_dat_file
列表,讀取每個文件並寫入未壓縮的數據。然後,它讀取 50 個未壓縮數據文件中的每一個,並在文件名前面再次寫入。所有這些工作都是按順序完成的,因此不能利用您的多個 CPU。我建議你試試
func_create_dat_file() { cd raw_directory while IFS="" read -r f do zcat -- "$f" | sed "s/^/${f%.gz}|/" done < "${raw_file_list}" >> "${data_file}" }
這裡壓縮數據從磁碟讀取一次。未壓縮的數據被寫入管道一次,從管道讀取一次,然後寫入磁碟一次。數據的轉換與讀取並行發生,因此可以使用 2 個 CPU。
$$ Edit $$評論要求解釋該
sed "s/^/${f%.gz}|/"
部分。這是將文件名作為新欄位放在每行開頭的程式碼。$f
是文件名。${f%.gz}
從字元串的末尾刪除.gz
。|
在這種情況下,沒有什麼特別之處,刪除尾隨後跟.${f%.gz}|
的文件名也是如此。in是替換(replace)命令,它需要一個作為零件。因為正則表達式匹配行首,所以把它放在一起說將行首更改為不帶尾隨和. 這.gz``|``sed
s/old/new/``regular expression``old``^``.gz``|``|
添加以匹配 OP 的程序而不是 OP 的描述。如果它真的是 CSV(逗號分隔變數)文件,那麼這應該是逗號而不是豎線。