Elasticsearch 大量滚动查询 断路器报错
在调用es api查询时,当使用游标滚动查询大批数据时, 或者深度分页总数超过10000条时, 或者其它查询时,可能报429错误(以 .net 的es客户端为例,见下面代码)
var res = _esGoodsClient.Search(query, sort, pageindex, pagesize); if (!res.IsValid) { PringMsgInfo($"{nameof(SkuGoodsCheck)}分页获取型号错误会自动重试:{res.DebugInformation}"); Thread.Sleep(1000); }
在DebugInformation中输出关键信息如下:
"reason" : "[parent] Data too large, data for [<http_request>] would be [12447091198/11.5gb], which is larger than the limit of [12240656793/11.3gb], real usage: [12447090688/11.5gb], new bytes reserved: [510/510b], usages [request=0/0b, fielddata=24588/24kb, in_flight_requests=510/510b, accounting=26343256/25.1mb]", "bytes_wanted" : 12447091198, "bytes_limit" : 12240656793, "durability" : "PERMANENT",
原因:
触发了断路器,Elasticsearch 包含多个断路器,用于防止操作导致内存泄露错误(OutOfMemoryError)具体参考资料:Elasticsearch 断路器报错了,怎么办?
内存分析:
解决方案思路:
1)清空索引(没用),代码如下
清除特定索引的缓存:POST /<索引名>/_cache/clear?fielddata=true 清除所有缓存:POST /_cache/clear
2.添加内存,在jvm.options文件中配置(当查询的数据越来越多时也没用,如上面超过了12gb)
# Xms represents the initial size of total heap space # Xmx represents the maximum size of total heap space -Xms12g -Xmx12g
3.重启es,能暂时有用,后续也会出现429错误
4.目前的解决方案是重试,代码如下:
private List<SkuGoodsEsModel> GetDataAll(int pageindex, int pagesize) { var result = new List<SkuGoodsEsModel>(); while (true) { Func<SortDescriptor<SkuGoodsEsModel>, IPromise<IList<ISort>>> sort = s => { s.Ascending(o => o.CreateTimeStamp); return s; }; var query = GetQueryWhere(); var res = _esGoodsClient.Search(query, sort, pageindex, pagesize); if (!res.IsValid) { PringMsgInfo($"{nameof(SkuGoodsCheck)}分页获取型号错误会自动重试:{res.DebugInformation}"); Thread.Sleep(1000); } else { result = res.Documents.ToList(); break; } } PringMsgInfo($"sku_goods索引获取{result.Count}条,时间范围是{MinUpdateTime}~{MaxUpdateTime}"); return result; }