2014-10-04 73 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