@TOC
es深分页的问题解决
背景
公司es因为容量的原因,一般日志只存储7天。对于一些日志检索要求高一点的项目,可以发流程延长索引过期时间。但是这次碰见一个项目,需要日志保存3个月,而且日志的量级不小。鉴于此项目的特殊性,或者说为了解决此类特殊需求。暂定一个将指定es日志转存到hbase上。
es的基础概念
版本 7.X es
数据库和es概念对比
Relational DB Elasticsearch
数据库(database) 索引(indices)
表(tables) types
行(rows) documents
字段(columns) fields
常用翻页
1、from size
浅分页情况下,可以考虑使用,因为是批量操作已有数据的日志转换,实测发现性能很差
2、Scroll
基于历史快照和上一页的scroll_id,查询下一页,实测scrollId 在翻页比较多的时候,会出现丢失的情况。导致记录不是完整有序的
3、Search After
本次采用的方法 1、适合顺序的从头往下分页 2、没有跳页的需求 3、占用内存少
4、游标的方式
这种方式没有深究。 使用游标方式存储状态: 在应用层,使用游标方式来存储状态,而不是依赖 Elasticsearch 来存储状态。通过这种方式,可以将搜索结果按批次获取,并存储游标以跟踪搜索状态。这样可以将搜索过程分解为多个较小的请求,并且减少深度翻页的需求。
深度翻页的问题
性能开销: 深度翻页可能导致性能开销增加,特别是当从大量数据中获取更多结果时。每次翻页都需要进行数据检索和排序,可能会影响搜索请求的响应时间。
资源消耗: 大量的深度翻页请求会消耗大量的服务器资源,包括 CPU、内存和网络带宽。
稳定性: 对于大数据集的深度翻页请求,可能会增加节点的负载,可能导致集群的不稳定性或性能下降。
结果变化: 在进行深度翻页时,如果数据集正在更新或有新的数据插入,可能导致结果的变化。这是因为 Elasticsearch 的分布式特性可能导致数据的一致性问题
Search After的实现
// Search After
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source(SearchSourceBuilder.searchSource()
.size(transConfig.getBatchCount())
.fetchSource(new String[]{"data", "timestamp", "application","className"}, null)
.timeout(TimeValue.timeValueSeconds(1200))
.sort("_doc", SortOrder.ASC));
将上一轮结果的最后一个值放到这里
searchRequest.source(SearchSourceBuilder.searchSource()
.size(transConfig.getBatchCount())
.fetchSource(new String[]{"data", "timestamp", "application","className"}, null)
.timeout(TimeValue.timeValueSeconds(1200))
.sort("_doc", SortOrder.ASC)
// searchAfter
.searchAfter(searchHits[searchHits.length - 1].getSortValues()));