1

我们使用 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 界面执行一些查询,则查询将等待不可预测的时间(取决于目前的用户数量),然后返回结果并告诉我它已被执行在大约 4 秒内,这是不正确的。对我来说,看起来 ArangoDB 一次只能执行一个查询,而所有其他查询都在排队......

我错过了什么吗?是否有任何设置可以调整 ArangoDB 并提高其在负载下的性能?

更新:

我们使用 ArangoDB 3.0 并将其作为具有 1.5 GB RAM 的 Docker 容器(来自官方图像)运行。

样本文件(我们有大约 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
4

1 回答 1

1

I created 160k sample documents with the following query:

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

When synced to disk, the datafile is roughly 30MB. The journal files are 32MB.

If a run your query on that dataset, the reported execution time is 0.35 seconds on average.

I tried different indexes and a skiplist on just version_id seems to improve the performance best, bringing it down to 0.20 seconds at the cost of ~18MB memory for indexes. Right after a server restart, the query takes 1.5s, because the collection has to be loaded on first access and the indexes need to be rebuilt. Subsequent queries constantly take 0.2s however.

I used ArangoDB 3.0.devel, which should show more or less the same performance as the stable 3.0.x releases. The RAM used by the DBMS was ~440MB after running the query a couple times according to the web interface.

If you keep seeing query times >1.0s, something is not right. Can you check between queries, if the collection is automatically unloaded (possibly caused by insufficient RAM)? If so, check what eats your memory (if it's even ArangoDB), and make sure you try with more RAM to see if it influences the query time. Could another resource limit the performance, such as the mass storage or the CPU?

于 2016-08-04T18:30:40.640 回答