【问题标题】:How to use arangodb collection in multi-process如何在多进程中使用 arangodb 集合
【发布时间】:2014-10-21 22:09:44
【问题描述】:

我使用 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 是正常的。但它在功能上是错误的。 在功能上: 祝福({ 'db' => undef, '名称' => '节点', '状态' => 3, '代码' => 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;

【问题讨论】:

  • 您能在此处发布示例客户端程序(带有 Pool 或 ForkManager 的客户端程序),其中包含工作和非工作变体?否则很难说。谢谢!
  • 感谢您的回复!我附上了我的示例程序。区别在于“我的 $Node_Coll = $itdb->('Node');”在全局或 count() 中。
  • 在我看来,在多个并行线程中使用相同的连接是行不通的,因为客户端线程将通过相同的连接并行发送数据,交错写入和读取。结果将是不确定的,并且可能会出现乱码。我认为为每个分叉线程创建一个连接会更好,保证只能由一个线程使用。我认为这是明智的,建立几个连接的开销应该可以忽略不计,因为每个工作人员可能都会发出很多后续请求。
  • 我的产品计划是基于事件的。如果它收到一个事件,Count::count() 将被执行一次。所以我不喜欢放“$itdb->('Node');”在 count() 中,对于每个事件执行它是一个额外的工作量。所以我认为很难同时“实现每个分叉线程创建一个连接”和“建立几个连接应该可以忽略不计”。
  • 明白。但是多个线程将数据写入同一个共享连接可能也不起作用。例如,如果一个线程写入连接并等待响应,您无法确定另一个线程会首先“窃取”连接的响应。所以我认为你将需要多个连接。也许可以创建一个线程池,每个线程都有一个连接,并在事件发生时唤醒一个?

标签: arangodb


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多