有个人长的像洋葱,走着走着就哭了…….

scroll拉取时中途出现空结果

Elasticsearch | 作者 sardineYJA | 发布于2024年08月09日 | 阅读数:3129

ES 6.1.1 使用 scroll 拉取全量数据,size:10000,每次都是将上一次返回的 scroll id 作为下一次查询条件。但是偶尔会出现中途一批次返回为空的情况,甚至连 scroll id 都没有,返回中提示分片数为 147 和实际索引的分片数也完全不一致。但如果继续使用之前的 scroll id 依然可以正常拉取数据,就是少了中间的那批数据。

例如:
{"took":84,"timed_out":false,"_shards":{"total":147,"successful":147,"skipped":140,"failed":0},"hits":{"total":0,"max_score":null,"hits":},"aggregations":{"code":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":}},"code":200}
 
GET index_name/_search?scroll=5m
{
"size": 10000
...
}
 
GET _search/scroll
{
"scroll": "5m",
"scroll_id": "上一次返回的id"
}
已邀请:

sardineYJA

赞同来自:

有时候中间一批次的scroll返回,出现了意料外的索引的数据,有人遇到过吗
 

Fred2000 - 与其抱怨世界,不如改变自己

赞同来自:

这个问题涉及使用 Elasticsearch 的 scroll API 时遇到的中途数据丢失现象,尤其是在拉取全量数据时偶尔会出现空结果的情况。这种现象可能由以下几个原因导致:

原因分析:

    1.    Scroll Context 过期:
Scroll API 在长时间运行时可能导致 scroll context 过期,特别是在多次请求之间有较长延迟时。虽然你设置了 5 分钟的 scroll,但如果执行的查询时间较长或间隔较长,scroll context 可能在服务器端被清理掉,导致下一次请求无法正常获取数据。
    2.    集群状态波动或分片重分配:
在执行 scroll 请求的过程中,如果集群发生了状态变化(如分片重分配、节点宕机等),可能会导致 scroll id 对应的部分数据不可用,从而导致返回的分片数与实际索引的分片数不一致,或者中途出现空结果。
    3.    Scroll ID 不一致:
Scroll id 是一种轻量级的快照,它保留了搜索的上下文状态。但是,由于 Elasticsearch 的内部机制或是集群内部状态的改变,scroll id 在某些情况下可能会失效或者关联的数据发生变化,导致无法继续检索到期望的数据。
    4.    分片合并或数据变化:
Elasticsearch 在后台会自动执行分片合并等维护操作,这些操作可能会影响 scroll 的一致性,从而导致偶尔的数据不一致或数据丢失。

解决方案:

    1.    增加 scroll 时间:
适当增加 scroll 的生存时间(如设置更长的时间,例如 10 分钟或以上),确保在高负载或长时间查询的场景下,scroll context 不会轻易过期。
    2.    减少查询间隔:
缩短每次 scroll 请求之间的时间间隔,尽量减少 scroll context 过期的可能性,确保数据的连续性。
    3.    检查集群健康状态:
在 scroll 操作前,检查集群的健康状态,确保在查询过程中不会发生分片重分配或节点宕机等可能导致 scroll 失效的操作。
    4.    使用 Search After 替代 Scroll:
如果 scroll 的稳定性无法满足要求,可以考虑使用 search_after 来分页查询大规模数据。这种方式避免了 scroll id 的复杂性,适用于数据相对静态且需要严格分页的场景。
    5.    日志分析:
检查 Elasticsearch 的日志文件,看是否有任何异常提示或错误信息,可以帮助定位集群在 scroll 过程中的问题。

要回复问题请先登录注册