【发布时间】: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