ElasticSearch 1.7.5中helpers.scan无法滚动,无法遍历全索引
解决Elasticsearch 1.7.5中helpers.scan扫描1000条后失败的问题
你碰到的是Elasticsearch 1.7.x版本里的一个常见问题:当helpers.scan遍历到1000条文档后,后续的scroll请求直接返回400错误,根源在于过长的scroll_id在HTTP GET请求中超出了服务器的URL长度限制。
为什么会这样?
你手动用POST请求能拿到正常的scroll_id,但helpers.scan默认会用GET请求发送后续的scroll操作——这个长到524字符的scroll_id会被直接拼在URL里,而大多数Web服务器(比如Nginx)对GET请求的URL长度有默认限制,加上其他参数后就触发了服务器的400错误拦截。
最直接的解决办法
修改helpers.scan的调用参数,强制后续的scroll请求使用POST方法——这样scroll_id会放在请求体里,完全避开URL长度的限制:
res = helpers.scan( es, index="twitter", query={"query": {"match_all": {}}}, request_timeout=60, request_method='POST' # 这行是关键! ) for hit in res: do_some_stuff()
额外的优化建议
如果你的处理逻辑比较复杂,或者索引数据量极大,可以再做这几个调整:
- 减小单次返回的文档数:默认
helpers.scan每次取1000条,你可以手动指定size=100,既减轻服务器压力,也能让scroll_id更短(不过用POST后这个不是必须的):res = helpers.scan( es, index="twitter", query={"query": {"match_all": {}}}, request_timeout=60, request_method='POST', size=100 ) - 延长scroll上下文的超时时间:如果你的
do_some_stuff()处理单条文档耗时较长,默认5分钟的scroll超时可能不够,改成scroll='10m'避免上下文提前失效:res = helpers.scan( es, index="twitter", query={"query": {"match_all": {}}}, request_timeout=60, request_method='POST', scroll='10m' )
验证是否生效
修改后运行代码,看日志里的请求方式——如果出现POST http://example.com:9200/_search/scroll而不是GET,就说明已经切换到正确的请求方式,应该能顺利遍历整个索引了。
内容的提问来源于stack exchange,提问作者kolurbo
相关产品推荐
相关产品推荐

