Php 嵌套GNU并行处理多个大型文件,并将要处理的每个文件数据拆分为队列
我有一个目录,几乎有100个日志文件,每个文件的重量为10~15GB。要求是逐行读取每个文件(顺序根本不重要),清理json行并将其转储到后端elasticsearch存储中进行索引 这是我做这项工作的工人Php 嵌套GNU并行处理多个大型文件,并将要处理的每个文件数据拆分为队列,php,linux,bash,shell,gnu-parallel,Php,Linux,Bash,Shell,Gnu Parallel,我有一个目录,几乎有100个日志文件,每个文件的重量为10~15GB。要求是逐行读取每个文件(顺序根本不重要),清理json行并将其转储到后端elasticsearch存储中进行索引 这是我做这项工作的工人 # file = worker.php echo " -- New PHP Worker Started -- "; // to get how many times gnu-parallel initiated the worker $dataSet = []; while (fals
# file = worker.php
echo " -- New PHP Worker Started -- "; // to get how many times gnu-parallel initiated the worker
$dataSet = [];
while (false !== ($line = fgets(STDIN))) {
// convert line text to json
$l = json_decode($line);
$dataSet[] = $l;
if(sizeof($dataSet) >= 1000) {
//index json to elasticsearch
$elasticsearch->bulkIndex($dataSet);
$dataSet = [];
}
}
在答案的帮助下,我几乎做到了,它正在工作(某种程度上),但只需要确保在引擎盖下,它确实在做我认为它正在做的事情
只需一个文件,我就可以按如下方式处理它
parallel --pipepart -a 10GB_input_file.txt --round-robin php worker.php
这很有效。添加--round-robin确保php工作进程只启动一次,然后继续以管道(穷人队列)的形式接收数据
因此,对于4CPU机器,它会激发4名php工作人员,并非常快速地处理所有数据
要对所有文件执行相同的操作,下面是我对它的看法
find /data/directory -maxdepth 1 -type f | parallel cat | parallel --pipe -N10000 --round-robin php worker.php
这看起来很有效,但我有一种直觉,这是一种错误的嵌套所有文件的并行方式
第二,由于它不能使用管道部件,我认为它速度较慢
第三,一旦工作完成,我看到在4cpu机器上,只有4名工人开始工作,工作完成了。这是正确的行为吗?它不是应该为每个文件启动4个工人吗?只是想确保我没有遗漏任何数据
你知道如何更好地实现这一点吗?如果它们的大小大致相同,为什么不简单地为每个文件分配一个文件:
find /data/directory -maxdepth 1 -type f |
parallel php worker.php '<' {}
如果启动
php worker.php不需要很长时间,那么最后一个可能更可取,因为如果文件大小非常不同,它将分布得更均匀,因此如果最后一个文件很大,您不会等待单个进程完成处理。您的意思肯定是json_encode()
?
do_one() {
parallel --pipepart -a "$1" --block -1 php worker.php
}
export -f do_one
find /data/directory -maxdepth 1 -type f | parallel -j1 do_one