如何提高负载下的ArangoDB性能(多个并发查询)?

我们使用ArangoDB和PostgreSQL来存储几乎相同的数据。 PostgreSQL用于执行关系数据库可以很好地执行的一般types的查询。 selectArangoDB来执行graphics遍历等查询,find最短path等。

目前,我们有一个在PostgreSQL中有160000条logging的表,在ArangoDB中有一个与文档数量相同的集合。

我们正在使用的API将被多个用户同时使用,所以我首先要检查的是ArangoDB和PostgreSQL在负载下如何执行。 我创build了一个简单的负载testing,作为一个工作负载执行一个简单的select查询与filter既ArangoDB和PostgreSQL。

查询使用按date过滤字段select前N个logging/文档。

当我运行负载testing时,对PostgreSQL的所有查询都在0.5秒内执行,我将用户数量从10增加到100,并且完全不影响执行时间。

对于ArangoDB来说,同样的查询需要花费大约2秒钟的时间,然而,响应时间与并发用户的数量成正比。 有30个并发用户,等待60秒后,所有查询都会超时。

我试图debuggingarangojs连接器,发现这一点:

var maxTasks = typeof agent.maxSockets === 'number' ? agent.maxSockets * 2 : Infinity; 

和这个:

 Connection.agentDefaults = { maxSockets: 3, keepAlive: true, keepAliveMsecs: 1000 }; 

这意味着默认的arangojs行为是同时向ArangoDB发送不超过6个并发查询,这导致所有其余查询在Node.js端排队。 我试图增加数量,但它没有帮助,现在看起来像所有的查询排队在ArandoDB一侧。 现在,如果我运行加载并尝试使用ArangoDB Web Interface执行一些查询,则查询将提交不可预测的时间量(取决于当前用户的数量),然后返回结果并显示它已被执行在大约4秒内这是不正确的。 对我来说,看起来像ArangoDB一次只能执行一个查询,而所有其他查询排队…

我错过了什么吗? 有没有什么设置来调整ArangoDB并提高它在负载下的性能?

更新:

我们使用ArangoDB 3.0,并将其作为Docker容器(来自官方图片)与1.5 GB的RAM一起运行。

样本文件(我们有大约16000个):

 { "type": "start", "from_date": "2016-07-28T10:22:16.000Z", "to_date": "9999-06-19T18:40:00.000Z", "comment": null, "id": "13_start", "version_id": 1 } 

AQL查询:

 FOR result IN @@collection FILTER (result.version_id == 1) FILTER (result.to_date > '2016-08-02T15:57:45.278Z') SORT result._key LIMIT 100 RETURN result 

我使用以下查询创build了160k个示例文档:

 LET v = [1,1,1,1,1,2,2,2,3,3,4] LET d = DATE_NOW() FOR i IN 1..160000 INSERT { "type": "start", "from_date": DATE_SUBTRACT(d, RAND()*4000, "days"), "to_date": DATE_ADD(d, RAND()*4000+100, "days"), "comment": null, "id": CONCAT(i, "_start"), "version_id": v[RAND()*LENGTH(v)] } INTO @@collection RETURN NEW 

当同步到磁盘时,数据文件大约为30MB。 日志文件是32MB。

如果在该数据集上运行查询,报告的执行时间平均为0.35秒

我尝试了不同的索引,并且在version_id上有一个跳过列表,似乎可以最好地提高性能,以索引的大约18MB内存为代价将其降低到0.20秒。 在服务器重新启动后,查询花费1.5s,因为集合必须在首次访问时加载,并且需要重build索引。 随后的查询不断地花费0.2秒。

我使用了ArangoDB 3.0.devel,它应该会显示出与稳定版本3.0.x相同的性能。 根据Web界面几次运行查询后,DBMS使用的RAM大约为440MB。

如果您持续查看时间大于1.0s,则说明问题不对。 如果集合被自动卸载(可能是由于RAM不足造成的),你可以检查两个查询吗? 如果是这样,检查什么吃你的记忆(如果它甚至是ArangoDB),并确保您尝试更多的RAM,看看是否影响查询时间。 另一个资源是否可以限制性能,比如海量存储或者CPU?