2014-10-04 112 views
1
插入性能

我的环境是本地机器: 的Ubuntu 12.04 ArangoDB 2.2.4或2.2.3 Perl驱动程序(ArangoDB) CPU:3核6线程 MEM:3GB我怎样才能提高ArangoDB

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

  1. 一个perl进程,插入30000个文件。平均700个请求/秒。 350个HTTP_GET和350个HTTP_POST。
  2. 10 perl进程,插入30000文件。平均1000个请求/秒。 500个HTTP_GET和500个HTTP_POST。

运行30秒后,会报告HTTP 500错误。我修改了perl驱动程序(ArangeDB)代码以重试它。所以我可以完成这个测试。

当它报告HTTP 500错误时,arangodb的日志正在跟踪。

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 

我希望我的程序可以执行平均3000-5000个请求/秒并减少HTTP 500错误。我可以使用哪些改进。谢谢!

UPDATE BY 7/10/2014,我的插入示例脚本如下。我用AQL替换了保存方法。 一个perl进程,插入10000个文档,Avg 900个请求/秒,1000个HTTP_POST/s。 (无HTTP 500) 一个perl进程,插入30000个文档,Avg 700个请求/秒,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); 
} 
+0

是否有任何与HTTP 500错误返回的消息?另外,是否有可能为您的perl测试程序提供修改的驱动程序以进行复制? – stj 2014-10-06 11:00:10

+0

实际上是否需要进行GET和POST操作?保存一个文档只需要一个HTTP POST,所以我想你正在发布GET来确保文档还没有在那里,对吗?如果您的目标只是保存文档,那么HTTP GET可以完全省略。 – stj 2014-10-06 11:01:44

+0

返回的消息是“500:内部响应:无法连接到10.211.55.2:8529:无法在/home/netdisco/.plenv/versions/5.19.8/lib/perl5/site_perl/5.19.8/ArangoDB分配请求的地址/Connection.pm 73行“。该消息来自Connection.pm中的http_post。 – Hansen 2014-10-07 08:12:14

回答

1

我strace'd客户端程序并能确认一个新的连接被打开以用于每个请求。这会导致发出很多系统调用。 strace的看起来像这样的每个要求:

17300 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 
17300 ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fffaee760c0) = -1 ENOTTY (Inappropriate ioctl for device) 
17300 lseek(3, 0, SEEK_CUR)    = -1 ESPIPE (Illegal seek) 
17300 ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fffaee760c0) = -1 ENOTTY (Inappropriate ioctl for device) 
17300 lseek(3, 0, SEEK_CUR)    = -1 ESPIPE (Illegal seek) 
17300 fcntl(3, F_SETFD, FD_CLOEXEC)  = 0 
17300 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0 
17300 fcntl(3, F_GETFL)     = 0x2 (flags O_RDWR) 
17300 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 
17300 connect(3, {sa_family=AF_INET, sin_port=htons(8529), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress) 
17300 select(8, NULL, [3], [3], {299, 999526}) = 1 (out [3], left {299, 999524}) 
17300 write(3, "POST /_api/cursor HTTP/1.1\r\nConnection: Keep-Alive\r\nUser-Agent: Furl::HTTP/3.05\r\nHost: 127.0.0.1\r\nContent-Type: application/json\r\nContent-Length: 1032\r\nHost: 127.0.0.1:8529\r\n\r\n", 176) = 176 
17300 write(3, "{\"count\":true,\"query\":\"INSERT {\\n   \\\"id\\\": \\\"Jony\\\",\\n   \\\"value\\\": \\\"File\\\",\\n   \\\"popup\\\": \\\"public\\\",\\n   \\\"version\\\": \\\"101\\\",\\n   \\\"machine\\\": \\\"10.20.18.193\\\",\\n   \\\"text\\\": {\\n    \\"..., 1032) = 1032 
17300 read(3, 0x15f0af0, 10240)   = -1 EAGAIN (Resource temporarily unavailable) 
-- 
17300 close(3)       = 0 
17300 rt_sigprocmask(SIG_BLOCK, [PIPE], [], 8) = 0 
17300 rt_sigaction(SIGPIPE, {SIG_DFL, [], SA_RESTORER, 0x7faa49b221f0}, {SIG_IGN, [], SA_RESTORER, 0x7faa49b221f0}, 8) = 0 
17300 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 
17300 rt_sigprocmask(SIG_BLOCK, [PIPE], [], 8) = 0 
17300 rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x7faa49b221f0}, {SIG_DFL, [], SA_RESTORER, 0x7faa49b221f0}, 8) = 0 
17300 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 

我想你会希望避免建立和对每个请求关闭连接。这也解决了OS耗尽端口的问题。

为了使驾驶员重新打开连接所有的时间我不得不修改如下卷起:

在线卷起/ HTTP.pm 526,卷起检查HTTP响应头从服务器获取。它将从那里的响应头部读取Connection,并将头部值与字符串keep-alive进行比较。问题在于,这没有考虑到响应头的不同情况。 ArangoDB返回一个标头值Keep-Alive(介意上限),所以FURL不能正确识别它。

以下变化卷起/ HTTP.pm修复:

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

这使得客户不要关闭每个请求后,连接和没有用完的端口。

+0

非常感谢! 'keep-alive'不起作用,很多插入操作会导致HTTP 500.根据您的方法修改Furl/HTTP.pm后,HTTP 500错误消失。我再次使用strace。 “连接”只是每个请求中的一个。 – Hansen 2014-10-08 02:52:34

+0

我修改了Furl/HTTP.pm之后。我再次执行insert.pl。 HTTP 500消失了,但性能并没有得到显着提高。插入100,000个文档,消耗110秒。平均900个请求/秒。 – Hansen 2014-10-08 02:58:25

+0

我使用Parallel :: ForkManager打开5个插入进程。插入100,000个文档,消耗64个。平均1560个请求/秒。这是双倍的表现。如果我打开10个插入过程,插入100,000个文档,它会消耗70s。所以我认为多进程不能给我3000-5000个请求/秒。我使用Furl/HTTP.pm来做什么,Furl/HTTP.pm可以在一个进程中发送2900个HTTP请求。 – Hansen 2014-10-08 03:39:00