2

我使用 Anyevent::Fork::Pool 或 Parallel::ForkManager 来创建 100 个 perl 进程。我想在 Global 中创建数据库和集合,并在函数中使用集合对象。但它不起作用。我的示例代码如下:

use ArangoDB;
my $itdb = ArangoDB->new(
{
    host       => '10.211.55.18',
    port       => 8529,
    keep_alive => 1,
    timeout    => 10,
}
);
my $Node_Coll = $itdb->( 'Node' );

...

sub function{
    $Node_Coll->count();
}

这是反馈“错误无法在未定义的值上调用方法“http_get””。我在全局和函数中打印 $Node_Coll。这不一样。

在全局中,$Node_Coll 是正常的。但它在功能上是错误的。在函数中: bless( { 'db' => undef, 'name' => 'Node', 'status' => 3, 'code' => 200, '_api_path' => '/_api/collection/250177068120', 'id' => '250177068120', '连接' => undef }, 'ArangoDB::Collection' );

如果我输入“我的 $Node_Coll = $itdb->('Node');” 在本地功能中,没关系。像这样。子函数{ 我的 $Node_Coll = $itdb->( 'Node' ); $Node_Col->count(); }

我不知道为什么它会这样工作。我认为当“$itdb->('Node');”时它可能在多进程中使用一个套接字 在全球。因为“$itdb->('Node');” 将发送一个 http_get 请求,它会产生额外的负载,尤其是在多进程环境中。如果我们能保存它就更好了。

2014 年 8 月 10 日更新:数据准备:将一些数据插入集合“节点”。执行方法: 1. 保留脚本。并执行$./count_srv.pl 2.修改脚本。评论“我的 $Node_Coll = $itdb->('Node');” 在计数()中。在全局中取消注释。并执行 $./count_srv.pl

count.pm 如下:

package Count;
use ArangoDB;

my $itdb = ArangoDB->new(
{
    host       => '10.211.55.18',
    port       => 8529,
    keep_alive => 1,
    timeout    => 10,
}
);
#my $Node_Coll = $itdb->( 'Node' );

sub count{
    my $Node_Coll = $itdb->( 'Node' );
    my $count = $Node_Coll->count();
    print "The count is ", $count, "\n";
}

count_srv.pl 如下:

use Parallel::ForkManager;
use count;

my $process_num = 10;
$pm = Parallel::ForkManager->new($process_num);

for(1..$process_num){
# Forks and returns the pid for the child:
my $pid = $pm->start and next;

Count::count();

$pm->finish; # Terminates the child process
}
$pm->wait_all_children;
4

1 回答 1

2

为了使它与多个进程一起工作,您还需要多个连接(理想情况下每个进程一个)。否则,单个(共享)连接将被多个进程并行使用,这可能会搞砸。

应该可以预先创建一个连接池,并在分叉时将空闲连接从池中传递给子进程。当子进程终止时,您可以将连接返回到池中。我不知道这如何与 Perl 一起工作,只是想分享一下大致的想法。

于 2014-10-21T14:09:44.427 回答