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

时间:2016-08-04 11:53:19

标签: node.js concurrency performance-testing arangodb arangojs

我们使用ArangoDB和PostgreSQL来存储几乎相同的数据。 PostgreSQL用于执行关系数据库可以很好地执行的一般类型的查询。选择ArangoDB来执行诸如图遍历,寻找最短路径等类型的查询等。

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

我们正在处理的API将同时被多个用户使用,因此我想要检查的是ArangoDB和PostgreSQL在负载下的性能。我创建了一个简单的负载测试,当工作负载使用ArangoDB和PostgreSQL的过滤器执行简单的选择查询时。

查询使用按日期过滤字段筛选前N个记录/文档。

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

当您从单个用户开始时,对ArangoDB的相同查询大约需要2秒,然后响应时间与并发用户数量成正比。有30个并发用户,等待60秒后,所有查询都会超时。

我尝试调试arangojs连接器并找到了:

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。

示例文档(我们大约有16 000个):

{
  "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

1 个答案:

答案 0 :(得分:1)

我使用以下查询创建了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上的跳转列表似乎可以最佳地提高性能,将其降低到0.20秒,代价为~18MB内存。在服务器重新启动之后,查询需要1.5秒,因为必须在首次访问时加载集合并且需要重建索引。然而,后续查询不断采用0.2秒。

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

如果您一直看到查询时间> 1.0秒,那么事情就不对了。如果集合被自动卸载(可能由RAM不足引起),您可以在查询之间进行检查吗?如果是这样,检查你的内存是什么(如果它甚至是ArangoDB),并确保你尝试使用更多的RAM来查看它是否会影响查询时间。另一个资源是否会限制性能,例如大容量存储或CPU?