我正在使用生产服务器将大型数据集加载到Hadoop访问来自蜂巢桌子。
我们正在加载电信部门的订户网页浏览数据。我们有大量.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
并附加到数据文件,而不需要解压缩。
答案1
有很多磁盘 I/O 可以用管道代替。它func_create_dat_file
获取 50 个压缩文件的列表,读取每个文件并写入未压缩的数据。然后,它读取 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。
[编辑] 要求解释该部分的评论sed "s/^/${f%.gz}|/"
。这是将文件名作为新字段放在每行开头的代码。$f
是文件名。从字符串末尾${f%.gz}
删除。在这种情况下,.gz
没有什么特别的|
,${f%.gz}|
文件名也是如此,删除尾部.gz
后跟|
. Insed
s/old/new/
是替换(替换)命令,它需要regular expression
代表该old
部分。^
因为正则表达式匹配行的开头,所以将其放在一起,表示将行的开头更改为不带尾随.gz
和|
.添加它|
是为了匹配OP的程序而不是OP的描述。如果它确实是 CSV(逗号分隔变量)文件,那么这应该是逗号而不是竖线。
答案2
那么这个hive和hadoop呢?当您提供gzip -d
“原始文件列表”时,可能会不必要地绕过该分布式文件系统。
该生产服务器上的某些内容肯定无法正常工作。一小时解压20GB(我省略了细节)。我在 0.8 秒内解压了 100 MB、分成 11300 个文件的文件。这大约快了 20 倍。使用 naiv 巨大文件列表 gzip 调用和 ram 磁盘。我还按照建议安装并尝试了并行。速度快了 10%:0.7 秒。所以这不是问题。
(我只有 8 GB 内存的 Mini-PC i5)
我有一个正在运行的瓦特表。在 14 秒的慢速循环中,使用了 6 W。
在我的可疑循环中,它的功率约为 17 W,持续 6 秒。 (提示,也是 X 服务器,为 3.5 W,susp-to-ram 为 1.1,关闭为...0.7 瓦)
在我的测试中,14 s 循环与 0.8 s 巨大参数列表的比率与您的总体 25 GB/h 与我的 100 MB/0.8 s 的比率相同:二十倍...就好像您使用的是慢速 for 循环一样。我认为 hadoop 和 hive 的巨大参数列表正在干扰 gzip 和 bash。