有效地获取弹性搜索索引中的所有文档

efficiently getting all documents in an elasticsearch index

我想从 elasticsearch 集群中的全匹配查询中获取所有结果。我不在乎结果是不是最新的,也不在乎顺序,我只想稳步把所有的结果都过一遍,然后从头再来。滚动和扫描最适合这个,拍一张我不需要的快照似乎有点成功。我将着眼于处理数千万个文档。

有点像 elasticsearch query to return all records 的副本。但我们可以添加更多细节来解决开销问题。 (即,"it seems like a bit of a hit taking a snapshot that I don't need.")

在这种情况下,

A scroll-scan search 绝对是您想要的。这 "snapshot" 这里的开销并不大。该文档将其比喻为“ 就像 及时的快照”(强调)。实际的实现细节更微妙,也更巧妙。

文档后面会有更详细的解释:

Normally, the background merge process optimizes the index by merging together smaller segments to create new bigger segments, at which time the smaller segments are deleted. This process continues during scrolling, but an open search context prevents the old segments from being deleted while they are still in use. This is how Elasticsearch is able to return the results of the initial search request, regardless of subsequent changes to documents.

所以保存上下文成本低的原因是 Lucene 索引段的行为方式。 Lucene 索引被分成多个段,每个段就像一个独立的迷你索引。随着文档的添加(和更新),Lucene 只是将一个新段附加到索引中。段是一次性写入的:创建后,将不再更新。

随着时间的推移,随着段的积累,Lucene 将定期在后台进行一些内务处理。它扫描片段并合并片段以刷新已删除和过时的信息,最终合并为一组更小的更新和更新的片段。当新的合并段替换旧的段时,Lucene 将移除所有索引不再主动使用的段。

这种分段索引设计是 Lucene 比简单的 B 树具有更高性能和弹性的原因之一。在 long 运行 中连续附加段比直接在磁盘上更新文件的累积 IO 更便宜。此外,一次写入设计还有其他有用的特性。

Elasticsearch 此处使用的类似快照的行为是在滚动搜索开始时维护对所有活动段的引用。所以开销很小:一些对少数文件的引用。另外,也许还有磁盘上这些文件的大小,因为索引会随着时间的推移而更新。

可能 是一笔昂贵的开销,如果 磁盘space 是服务器上的一个严重问题。可以想象,当滚动搜索上下文处于活动状态时,索引更新得足够快可能会使索引所需的磁盘大小增加一倍。为此,确保您有足够的容量以便索引可以增长到其预期大小的 2-3 倍是很有帮助的。