0

我一直在使用 Elasticsearch 7.6 和 PHP 客户端 API 进行所有操作。我创建了弹性搜索索引设置和映射如下

$params = [
    'index' => $index,
    'body' => [
        'settings' => [
            "number_of_shards" => 1,
            "number_of_replicas" => 0,
            "index.queries.cache.enabled" => false,
            "index.soft_deletes.enabled" => false,
            "index.refresh_interval" => -1,
            "index.requests.cache.enable" => false,
            "index.max_result_window"=> 2000000
        ],
        'mappings' => [
            '_source' => [
                "enabled" => false
             ],
             'properties' => [
                "text" => [
                        "type" => "text",
                        "index_options" => "docs"
                ]
        ]
     ]
    ]
];

我的布尔 OR 搜索查询如下

$json = '{
"from" : 0, "size" : 2000000,
"query": {
       "bool": {
       "filter": {
        "match" : {
            "text" : {
            "query" : "apple orange grape banana",
            "operator" : "or"
            }
        }
    }
}
}
}';

我已经索引了 200 万份文档,所有文档都与查询匹配,并且我也按预期获取了所有文档。由于我匹配所有文档,因此我通过在 bool 查询中使用过滤器来避免评分。

但是在我的日志文件中,我反复收到以下消息,直到查询完成执行。有时我在批量索引文档时会收到相同的消息

[2020-05-15T19:15:45,720][INFO ][o.e.m.j.JvmGcMonitorService] [node1] [gc][14] overhead, spent [393ms] collecting in the last [1.1s]
[2020-05-15T19:15:47,822][INFO ][o.e.m.j.JvmGcMonitorService] [node1] [gc][16] overhead, spent [399ms] collecting in the last [1s]
[2020-05-15T19:15:49,827][INFO ][o.e.m.j.JvmGcMonitorService] [node1] [gc][18] overhead, spent [308ms] collecting in the last [1s]

我为我的堆内存分配了 16 GB。elasticsearch 日志中未显示其他警告。可能是什么原因?还是在检索大量文档时预期?我了解滚动 API,但我很好奇为什么当我为 index.max_result_window 使用大值时会发生这种情况。非常感谢帮助?提前致谢!

4

1 回答 1

1

您看到的是 Elasticsearch 的正常行为,特别是上述配置,以及任何 Java 应用程序。

大的ES正常index.max_result_window吗?

是的。作为index.max_result_window状态文档,生成的垃圾量与查询返回的文档数量成正比:

搜索请求占用的堆内存和时间与 from + size 成正比,这限制了该内存。

它是否也适用于批量 API 请求?

是的,如果您的批量请求很大,它可能会触发垃圾收集。

自然,ES 在堆上分配它需要发回给用户的文档,之后它们立即成为垃圾并因此成为垃圾收集的对象。

垃圾收集在 Java 中是如何工作的?

例如,您可以在此处找到一些相关信息。

有没有更好的方法来查询所有匹配的文档?

例如,有match_all查询。

与使所有文档匹配特定查询相比,它有什么好处?Elasticsearch 不必查询索引,可以立即去获取文档(更好的性能和资源使用)。

我应该使用滚动 API,还是当前的方法足够好?

Scroll API 是推荐的方式,因为它的扩展性远远超出了一个 Elasticsearch 节点的内存容量(一个可以从具有大约 16GB RAM 的几台机器的集群中下载 1TB 的数据)。

但是,如果您还想继续使用普通的搜索查询,您可以考虑使用fromsize参数并进行分页(这样可以限制每个查询获取的文档数量,并使 GC 随着时间的推移更好地分布)。

希望这可以帮助!

于 2020-05-16T15:16:35.780 回答