Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 嵌套GNU并行处理多个大型文件,并将要处理的每个文件数据拆分为队列_Php_Linux_Bash_Shell_Gnu Parallel - Fatal编程技术网

Php 嵌套GNU并行处理多个大型文件,并将要处理的每个文件数据拆分为队列

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

我有一个目录,几乎有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 (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