ElasticSearch中的Scroll机制
Elasticsearch 中的 Scroll Id 机制是一种用于批量检索大量数据的机制。
当我们需要批量获取大量数据时,直接使用搜索 API 可能会遇到一些性能问题。此时, Scroll Id 机制则能够帮助我们优化查询性能。该机制类似于一个游标,可以通过 Scroll API 来获取每个批次的结果。每个结果都包含一个新的 Scroll Id,该 ID 可以用于检索下一个批次的结果,这样我们就可以按需逐批获取数据。
使用 Scroll Id 机制的好处在于可以取代传统的分页方式,因为它不需要在每次搜索的结果中指定大小和偏移量。
此外,由于 Elasticsearch 并不需要在每次搜索中重建内部状态,所以 Scroll Id 机制可以更高效地处理批量数据。
虽然 Elasticsearch 中的 Scroll Id 机制具有很多优点,但也存在一些缺点。
具体来说, Scroll Id 机制可能会导致以下问题:
- 1. Scroll Id 机制需要占用服务器内存以保存游标状态,如果数据量过大或者游标过多,可能会导致 Elasticsearch 的内存占用过高,从而影响其他服务的正常运行。
- 2. 使用 Scroll Id 机制获取结果时,必须在每一个批次结果返回后立即对结果进行处理。如果处理速度跟不上结果获取速度,可能会导致数据积压,导致内存不够用或磁盘 I/O 不足等问题。
- 3. Scroll Id 机制只能在游标有效期内获取数据,一旦过期则无法获取。默认的有效期为 1 分钟,但可以通过设置 Search Request 上的 scroll 参数来更改有效期。如果游标过期但未及时处理数据,可能会导致数据丢失。
- 4. Scroll Id 机制只是针对检索,无法保证数据不被修改或删除。如果数据在检索过程中被修改或删除,可能会导致 Scroll Id 所指向的数据不准确。
综上所述,Scroll Id 机制是一种不错的批量检索机制,但需要注意消耗内存、处理速度、有效期和数据修改等问题。
Elasticsearch 默认分配 512MB 的内存。这个值可以通过 elasticsearch.yml 配置文件的以下参数来修改:
- - indices.memory.index_buffer_size: 用于索引查询结果的内存缓冲区大小,默认 512MB。Scroll 查询结果会先存储在这个缓冲区中。
- - search.scroll.size: Scroll 查询结果的大小,默认 1000 条文档。这个值控制每次 Scroll 请求返回的最大文档数。
- - search.max_open_scroll_context: 最大同时打开的 Scroll 上下文数量,默认 5 个。这个值控制可以同时执行的 Scroll 查询的最大数目。
所以,如果你需要执行大量 Scroll 查询,可以适当增加这3个参数的值来提高性能:- indices.memory.index_buffer_size:增加到 1GB 或更高- search.scroll.size:增加到 5000 条或更高- search.max_open_scroll_context:增加到 10 个或更高但是,这些参数的增加也会造成更高的内存占用,所以需要根据服务器内存大小选择合理的值。
一般来说,indices.memory.index_buffer_size 不应超过内存的50%左右。
EG:
查询 1000 条数据 100 个字段预计占用的内存量取决于很多因素,无法给出一个准确的数字。但可以作出如下估计:- 每个文档对象占用 1-2KB 左右(这还不包括文档字段值的大小)
- 100 个字段,每个字段值平均 200 字节(这是一个比较保守的估计)
- 100 个字段 x 200 字节 x 1000 条文档 = 20MB 左右所以,一个粗略的估计是查询 1000 条数据 100 个字段会占用 20-30MB 左右的内存。实际上,内存占用还与:- 文档字段数据类型相关:字符串字段会占用更多空间,数字字段会占用较少空间
- 文档是否使用压缩:如果启用压缩,可以节省 30-50% 的空间
- 查询结果是否缓存在查询缓冲区:缓存的结果会额外占用查询缓冲区的空间(默认 512MB)综上,对于一个中等规模的 Scroll 查询,建议至少分配 1-2GB 的内存空间。
如果查询涉及大量字段或大量数据,内存占用可能远远超过这个范围。