我们使用 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
我使用以下查询创建了 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)是否会限制性能?
您找到问题的解决方案了吗?我在 3.10.6 版本中遇到了完全相同的问题。