SearchContextMissingException: No search context found for id [xx] 问题排查
背景
需要将存放在ES系统中的IMEI信息,将全量的数据分批拉取结果集到另外的系统,处理流程大抵就是先调用ES的查询方法,Scroll查询每批次10000条数据,得到数据集合后,在转换成自己系统需要的信息,最后插入到数据库,然后再通过scrollId进行下一次的查询。
但是有的时候会报下面的问题,我观察后发现,都是在处理一些大数据量的时候查询条件时,因为要入库,可能耗时比较多一些,而期初我们的setScroll中的过期时间比较短导致的。
1 2 3 4 5 6 7 8 9 10 11 | DEBUG!! default !![ 2022 - 08 - 28 20 : 11 : 06 , 432 ][DEBUG][action.search.type ] [<Query Node Name>] [ 27419 ] Failed to execute fetch phase org.elasticsearch.transport.RemoteTransportException: [<Data Node Name>][inet[/xx.x.x.xxx: 9300 ]][search/phase/fetch/id] Caused by: org.elasticsearch.search.SearchContextMissingException: No search context found for id [ 27419 ] at org.elasticsearch.search.SearchService.findContext(SearchService.java: 481 ) at org.elasticsearch.search.SearchService.executeFetchPhase(SearchService.java: 451 ) at org.elasticsearch.search.action.SearchServiceTransportAction$SearchFetchByIdTransportHandler.messageReceived(SearchServiceTransportAction.java: 793 ) at org.elasticsearch.search.action.SearchServiceTransportAction$SearchFetchByIdTransportHandler.messageReceived(SearchServiceTransportAction.java: 782 ) at org.elasticsearch.transport.netty.MessageChannelHandler$RequestHandler.run(MessageChannelHandler.java: 275 ) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java: 1145 ) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java: 615 ) at java.lang.Thread.run(Thread.java: 724 ) |
scroll分页流程
使用ES搜索,当请求返回单个“页面”的结果时,scroll API可用于从单个搜索请求中检索大量结果(甚至所有结果),其方式与在传统数据库中使用光标的方式大致相同。
Scroll滚动不是为了实时用户请求,而是为了处理大量数据,例如为了将ES集群中的数据同步到另外的系统中去。
这个Scroll是一个快照,ES内部在这个快照中会保存于此相关的上下文信息,快照是非实时的信息。
为了使用scroll,初始搜索请求应该在查询字符串中指定scroll参数,它告诉elasticsearch它应该保持“搜索上下文”活动多长时间(参见保持搜索上下文活动)
第二次请求的时候需要带上第一次返回回来的scrollId,后面的每次查询都需要带上这个scroll_id,不过这个有时效性,超过了一定时间Scroll的搜索上下文search context alive就失效了。
结果
跟进后发现这个报错来自游标查询。之所以会出现这个报错,是由于时间已经超过游标当时设置的时间,scroll超时后自动删除了,所以才会提示:“No search context found for id”。
解决办法也简单,要么增大游标的有效时间,要么缩短获取数据后的处理时间。
setScroll()里传入的时间,表示一次处理setSize()里的数据超时时间。即处理一个分页最长不超过的时间。从你获取结果,处理请求到下一次遍历结果时间在5分钟之内即可,下面的代码表示5分钟。
1 2 3 4 5 6 7 8 9 10 11 | /** * scroll有效时间 */ public final static TimeValue SCROLL_KEEP_ALIVE = TimeValue.timeValueMinutes( 5 ); /** * 300s 超时 */ public final static TimeValue TIMEOUT_5_MINUTES = TimeValue.timeValueSeconds( 300 ); // 300s 超时 SearchResponse response = client.prepareSearchScroll(scrollId).setScroll(SCROLL_KEEP_ALIVE).execute().actionGet(TIMEOUT_5_MINUTES); |
本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。
出处:http://www.cnblogs.com/lingyejun/
若本文如对您有帮助,不妨点击一下右下角的【推荐】。
如果您喜欢或希望看到更多我的文章,可扫描二维码关注我的微信公众号《翎野君》。
转载文章请务必保留出处和署名,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!