ElasticSearch偶尔查询不到数据
1.数据刷新策略
现象:每次insert之后,立刻查询es的数据是有可能查不到的,因为es从内存写到磁盘需要时间
原因:es默认每1s执行一次refresh,因此文档实时性被提高到1s,这也是es被称为近实时的原因
解决方法:写的时候指定数据刷新策略, request().setRefreshPolicy(RefreshPolicy.IMMEDIATE);
枚举org.elasticsearch.action.support.WriteRequest.RefreshPolicy定义了三种策略:
NONE, IMMEDIATE, WAIT_UNTIL;
2.查询条件中含有中文导致查询不到数据
elasticsearch 里默认的IK分词器是会将每一个中文都进行了分词的切割,
所以你直接想查一整个词,或者一整句话是无返回结果的。
解决办法:
查询条件字增加.keyword后缀
QueryBuilders.termQuery("filed.keyword", "查询中文内容")
解释:ElasticSearch 5.0以后,string类型有重大变更,移除了string类型,string字段被拆分成两种新的数据类型: text用于全文搜索的,而keyword用于关键词搜索
参考文章:https://www.jianshu.com/p/26744eb914a8
每次查询最大只能查10000条
通过资料的查阅,发现默认值是10000,如果要查询大于10000条,我们就需要修改es的max_result_window默认值
解决方法:
我们在创建索引的时候 设置:"index.max_result_window": "10000", 这个值默认一万,我们可以改成自己想要的值
ES性能优化
1. 因为ES不能改变分片数量,所以创建索引的时候要指定好分片数量
ES 默认为一个索引创建 5 个主分片, 并分别为每个分片创建一个副本分片。
解决办法:合理的分片数量可以提高写入性能和稳定性。
分片数可以理解为MySQL中的分库分表
ES查询主要分为两类:单ID查询以及分页查询。
分片数越大,集群横向扩容规模也更大,根据分片路由的单ID查询吞吐量也能大大提升,但聚合的分页查询性能则将降低;
分片数越小,集群横向扩容规模也更小,单ID的查询性能也会下降,但分页查询的性能将会提升。
2、避免深分页查询ES集群的分页查询支持from和size参数,
查询的时候,每个分片必须构造一个长度为from+size的优先队列,
然后回传到网关节点,网关节点再对这些优先队列进行排序找到正确的size个文档。
假设在一个有6个主分片的索引中,from为10000,size为10,每个分片必须产生10010个结果,
在网关节点中汇聚合并60060个结果,最终找到符合要求的10个文档。
由此可见,当from足够大的时候,就算不发生OOM,也会影响到CPU和带宽等,从而影响到整个集群的性能。
所以应该避免深分页查询,尽量不去使用。
解决办法:可以使用ES的Scroll滚动查询
scroll 可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,
相当于一个锚标记 ,随后再次滚动搜索会需要上一次搜索滚动id,根据这个进行下一次的搜索请求。
每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的。
性能会比上面说的分页性能要高很多,基本上都是毫秒级的。
这个适合于那种类似微博下拉翻页的,不能随意跳到任何一页的场景。
具体官网文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/scroll.html