我对MongoDB中的全文搜索性能非常不满意,因此我一直在寻找现成的解决方案。在8台强大的机器(4个带冗余的分片)上分片的2500万个文档中,相对较小的集合使我看到一些查询需要10秒钟。真可怕在百灵鸟上,我直接对分片尝试了10秒的查询,看来mongos是以串行方式而不是并行地将查询发送到分片的。在这4个分片中,我发现一个分片的搜索时间为2.5秒,而其他3个分片的搜索时间均在2秒以下。总共不到8.5秒,但经过mongos花了10秒。 Facepalm。
有人可以确认对分片的这些查询正在串行运行吗?或提供其他解释?
直接查询分片有哪些陷阱?
我们使用的是4.0,查询如下:
db.items.aggregate(
[
{ "$match" : {
"$text" : { "$search" : "search terms"}
}
},
{ "$project": { "type_id" : 1, "source_id": 1 } },
{ "$facet" : { "types" : [ { "$unwind" : "$type_id"} , { "$sortByCount" : "$type_id"}] , "sources" : [ { "$unwind" : "$source_id"} , { "$sortByCount" : "$source_id"}]}}
]
);
我之前犯了一个错误,这是发送的有问题的查询。而且我与MongoDB专家进行了交谈,并且了解到发生了很大的事情(我认为),但是很高兴看到其他人要说些什么,以便我支付赏金并将其设为官方。
答案 0 :(得分:1)
有人可以确认对分片的这些查询正在串行运行吗?要么 提供其他解释?
查询中没有分片键,查询将发送到所有分片并并行进行 处理。但是,所有分片的结果都将合并到主分片中,因此它将等到最慢的分片返回。
直接查询分片有哪些陷阱?
您可能会包含孤立的文档。通过mongos
进行的查询还会检查孤立的文档,以确保数据的一致性。因此,与直接从每个分片查询相比,通过mongos
进行查询的开销更大。
使用Robo 3T的查询时间进行测量
使用Robo 3T无法正确测量查询时间。默认情况下,Robo 3T返回前50个文档。对于驱动程序实施,如果返回的文档数大于默认的批处理大小,则要检索所有文档,将向数据库发送getmore
个请求。 Robo 3T仅给您第一批结果,即结果的子集。
要评估您的查询,请在查询中添加explain('executionStats')
。性能下降可能是分片之间的数据传输。由于查询中缺少分片键,因此在合并之前必须将所有分片的结果发送到分片。总时间不仅是来自mongo引擎的查询时间(查找文档),还包括文档检索时间。
执行以下命令,您将在每个分片中看到 inputStages ,以更好地评估您的查询。
db.items.explain('executionStats').aggregate(
[
{ "$match" : {
"$text" : { "$search" : "search terms"}
}
},
{ "$project": { "type_id" : 1, "source_id": 1 } },
{ "$facet" : { "types" : [ { "$unwind" : "$type_id"} , { "$sortByCount" : "$type_id"}] , "sources" : [ { "$unwind" : "$source_id"} , { "$sortByCount" : "$source_id"}]}}
]
);