代码之家  ›  专栏  ›  技术社区  ›  Waku-2 Cyril Gandon

带有命名管道的gnu并行作业队列

  •  1
  • Waku-2 Cyril Gandon  · 技术社区  · 5 年前

    我跟着 sample code 创建gnu并行作业队列,如下所示

    // create a job queue file
    touch jobqueue
    
    //start the job queue
    tail -f jobqueue | parallel -u php worker.php 
    
    // in another shell, add the data 
    while read LINE; do echo $LINE >> jobqueue; done < input_data_file.txt 
    

    这种方法确实有效,并且将作业作为一个简单的作业队列来处理。但有两个问题

    1-从输入文件读取数据,然后将其写入jobqueue(另一个文件)速度很慢,因为它涉及磁盘I/O。

    2-如果由于某种原因,我的作业中途中止,并且我重新启动并行处理,它将重新运行jobqueue文件中的所有作业

    我可以在worker.php中添加一个脚本,以便在作业完成时从jobqueue中实际删除该行,但我觉得有更好的方法可以做到这一点。

    有没有可能

    tail -f jobqueue
    

    我可以使用命名管道作为并行的输入,而我当前的设置仍然可以作为一个简单的队列工作?

    我想这样我就不必从管道中移除管线了,因为这样做会在读取时自动移除?

    P.S.我知道,我使用过rabbitmq、zeromq(我也喜欢)、nng、nanomsg,甚至php-pcntl_-fork和pthreads。所以这不是一个并行处理的问题。使用gnu parallel创建一个工作队列更是一个问题。

    1 回复  |  直到 5 年前
        1
  •  0
  •   Ole Tange    5 年前
    while read LINE; do echo $LINE >> jobqueue; done < input_data_file.txt 
    

    这可以更快地完成:

    cat >> jobqueue < input_data_file.txt 
    

    虽然fifo可以工作,但它会阻塞。这意味着你不能在队列中放很多东西——这有点违背了队列的目的。

    如果磁盘i/o是读取实际作业的问题,我会感到惊讶:gnu parallel每秒可以运行100-1000个作业。作业最多可达128 KB,因此磁盘最多只能传送128 MB/s。如果每秒不运行100个作业,则队列的磁盘I/O永远不会成为问题。

    你可以用 --resume --joblog mylog 要在重新启动时跳过已运行的作业,请执行以下操作:

    # Initialize queue
    true >jobqueue
    # (Re)start running the queue 
    tail -n+0 -f jobqueue | parallel --resume --joblog mylog