如何提高ArangoDB中的插入性能

如何提高ArangoDB中的插入性能,arangodb,Arangodb,我的环境是本地计算机: ubuntu 12.04 ArangoDB 2.2.4或2.2.3 perl驱动数据库 CPU:3核6线程 内存:3GB 我使用了保存方法。Save方法等于HTTP_GET和HTTP_POST。 执行结果如下: 一个perl进程,插入30000个文档。平均700次请求/秒。350 HTTP_GET和350 HTTP_POST。 10 perl进程,插入30000个文档。平均1000次请求/秒。500个HTTP_GET和500个HTTP_POST。 运行30秒后,它将报告H

我的环境是本地计算机: ubuntu 12.04 ArangoDB 2.2.4或2.2.3 perl驱动数据库 CPU:3核6线程 内存:3GB

我使用了保存方法。Save方法等于HTTP_GET和HTTP_POST。 执行结果如下:

一个perl进程,插入30000个文档。平均700次请求/秒。350 HTTP_GET和350 HTTP_POST。 10 perl进程,插入30000个文档。平均1000次请求/秒。500个HTTP_GET和500个HTTP_POST。 运行30秒后,它将报告HTTP 500错误。我修改了perl DriverRangeDB代码以重试它。所以我可以完成这个测试

arangodb报告HTTP 500错误时,其日志正在跟踪

2014-10-04T14:46:47Z [26642] DEBUG [./lib/GeneralServer/GeneralServerDispatcher.h:403]   shutdownHandler called, but no handler is known for task
2014-10-04T14:46:47Z [26642] DEBUG [./lib/GeneralServer/GeneralServerDispatcher.h:403] shutdownHandler called, but no handler is known for task
我希望我的程序能够执行avg 3000-5000请求/秒,减少HTTP 500错误。我能用的改进是什么。谢谢

2014年10月7日前更新,我的插入示例脚本如下。我用AQL代替了保存方法。 一个perl进程,插入10000个文档,平均900个请求/s,1000个HTTP_POST/s。没有HTTP 500 一个perl进程,插入30000个文档,平均700个请求/s,700个HTTP_POST/s。将发出HTTP 500,需要重试吗

#!/usr/bin/perl

use warnings;
use strict;

use ArangoDB;

my $itdb = ArangoDB->new(
{
    host       => '10.211.55.2',
    port       => 8529,
    keep_alive => 1,
}
);

# Find or create collection
$itdb->create('Node_temp',{isVolatile => JSON::true});
ImpNodes();

sub ImpNodes{

    for(1..30000){
        my $sth = $itdb->query('INSERT {
            "id": "Jony",
            "value": "File",
            "popup": "public",
            "version": "101",
            "machine": "10.20.18.193",
            "text": {
               "Address": ["center","bold","250","100"]
            },
            "menuitem":[
            {
                "value": "New",
                "onclick": "CreateNewDoc",
                "action": "CreateNewDoc"
            }
            ,
            {
                "value": "Open",
                "onclick": "OpenNewDoc",
                "action": "OpenNewDoc"
            },
            {
                "value": "Close",
                "onclick": "CloseDoc",
                "action": "CloseDoc"
            },
            {
                "value": "Save",
                "onclick": "SaveDoc",
                "action": "SaveDoc"
            }]
        } in Node_temp');

        my $cursor = $sth->execute({
            do_count => 1,
            batch_size => 10,
        });
    }
}
我修改了Arangodb-0.08,以便在Connection.pm中顺利插入。 http_post方法:

$retries = 100 #for testing
for(1..$retries){
    ( undef, $code, $msg, undef, $body ) = $self->{_http_agent}->request(
        %{ $self->{_req_args} },
        method     => 'POST',
        path_query => $path,
        headers    => $headers,
        content    => $data,
    );
    last if ( $code < 500 || $code >= 600 );
    print "The return code is 5xx,retry http_post!\n";
    print $code, " : " , $msg , " : " , $body;
    select(undef, undef, undef, 3);
}

我扫描了客户端程序,可以验证是否为每个请求打开了一个新连接。这会导致发出许多系统调用。strace对于每个请求都是这样的:

我认为您应该避免在每次请求时建立和关闭连接。这也解决了操作系统端口不足的问题

为了防止驾驶员一直重新打开连接,我必须修改FURL,如下所示:

在Furl/HTTP.pm的第526行中,Furl检查从服务器获取的HTTP响应头。它将从那里的响应头读取连接,并将头值与字符串keep-alive进行比较。问题在于,这没有考虑响应头的不同情况。ArangoDB返回一个标题值Keep Alive mind the caps,因此FURL无法正确识别它

对Furl/HTTP.pm的以下更改修复了以下问题:

-    if ($connection_header eq 'keep-alive') {
+    if (lc($connection_header) eq 'keep-alive') {

这使得客户端在每次请求后都不会关闭连接,也不会耗尽端口。

是否返回HTTP 500错误消息?此外,是否可以为perl测试程序提供修改后的驱动程序以进行复制?是否确实需要执行GET和POST操作?保存一个文档只需要一个HTTP POST,所以我猜您发出GET是为了确保文档还没有出现,对吗?如果您的目标只是保存文档,那么可以完全忽略HTTP GET。返回的消息是500:内部响应:无法连接到10.211.55.2:8529:无法在/home/netdisco/.plenv/versions/5.19.8/lib/perl5/site_perl/5.19.8/ArangoDB/Connection.pm第73行分配请求的地址。。消息来自http_post in Connection.pm。我使用perl CPAN中的ArangoDB-0.08。在save方法中,$self->{connection}->http_post$api,$data将发送http_post,ArangoDB::Document->new$self->{connection},$res->fetch将发送http_get。我想没关系。我可以修改它,删除http_get。我已经附加了我的测试程序。谢谢!非常感谢“保持活动”无效,大量插入将导致HTTP 500。在我按照您的方法修改Furl/HTTP.pm之后,HTTP 500错误消失了。我又用了strace。每个请求只有一个connect。在我修改Furl/HTTP.pm之后。我再次执行了insert.pl。HTTP 500消失了,但性能并没有显著提高。插入100000个文档,耗时110秒。Avg 900请求/秒。我使用Parallel::ForkManager进行Open5插入过程。插入100000个文档,需要64秒。平均1560次请求/秒。这是双重表演。如果我打开10个insert进程,插入100000个文档,它将消耗70秒。所以我认为多流程不能给我3000-5000个需求/秒。我使用Furl/HTTP.pm什么也不做,Furl/HTTP.pm可以在一个进程中发送2900个HTTP请求/秒。我不确定Parallel::ForkManager在内部是如何工作的。您能否确保当您使用5个插入进程时,它实际上使用了5个到ArangoDB的连接?或者它是否在所有5个进程之间共享一个连接,我怀疑这会起作用,但只是为了确保。您可以尝试的另一件事是不要使用AQL查询来插入单个文档,而是使用/u api/document上的HTTP POST方法来插入文档。这里有相关文档:与发出AQL查询相比,处理单个文档的每次调用的开销应该略低一些
-    if ($connection_header eq 'keep-alive') {
+    if (lc($connection_header) eq 'keep-alive') {