- 浏览: 2183586 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
最近线上的es查询的某个微服务接口,报了一个异常,如下:
``` nested: SearchParseException[No mapping found for [count] in order to sort on]; Caused by: SearchParseException[failed to parse search source ```
直接从异常上看,可以得到是因为mapping里面不存在排序字段的时候,而抛出的异常,正常的情况,如果某个索引不存在并且还去查询该索引,我们可以通过对索引名字后面加*通配,来避免查询报错,如下:
``` SearchRequestBuilder search=client.prepareSearch("log2019-07-11*"); search.setQuery(QueryBuilders.queryStringQuery("uid:111")); search.addSort("count", SortOrder.DESC); ```
经询问,我们的代码里面已经加了*通配符,那么又为什么会出现这个问题呢?经过对场景的分析总结,对某个字段进行sort时,可能会报上述异常,主要在两种情况下:
(1)count字段在mapping中无定义,并没有在索引名字后缀加*通配符时,必定每次都报异常
(2)count字段在mapping中有定义,使用前面的排序方法,排序有时候报错,有时候不报
对于第一种情况,mapping里不存在定义,并且没有使用通配容错,直接使用该字段排序报错很正常。
接下来主要分析第二种情况,因为这里面有个概率事件,即大多数时候都没问题,但在少数时候会抛出异常。通过分析log发现在凌晨12点刚过的时候,会有几率出现这种问题,为了找到更多的排查线索,我让运维给出了线上当时服务端es的log文件,毕竟单纯从微服务的log里面,很难观察到这个异常前后,有没有更多的上下文log输出,想要找到这个,只能查看服务端部署es节点的log了,在拿到log之后,果然从上下文里面,发现了一些关键的信息,如下:
``` [2019-07-11 00:00:05,044][INFO ][cluster.metadata ] [my_es] [log2019-07-11] creating index, cause [auto(index api)], templates [log], shards [3]/[2], mappings [_default_, log] [2019-07-11 00:00:05,409][INFO ][cluster.routing.allocation] [my_es] Cluster health status changed from [RED] to [YELLOW] (reason: [shards started [[log2019-07-11][0], [log2019-07-11][2], [log2019-07-11][1]] ...]). [2019-07-11 00:00:06,232][INFO ][cluster.routing.allocation] [my_es] Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[log2019-07-11][1], [log2019-07-11][1]] ...]). [2019-07-11 00:00:06,374][INFO ][cluster.metadata ] [my_es] [log2019-07-11] update_mapping [log] [2019-07-11 00:00:07,153][DEBUG][action.search ] [my_es] [log2019-07-11][0], node[QlHmfObMRg2K6FUuAaXXTw], [R], v[2], s[INITIALIZING], a[id=3aenuvbUQtGrFDBBxjJvCA], unassigned_info[[reason=INDEX_CREATED], at[2019-07-10T16:00:06.574Z]]: Failed to execute [org.elasticsearch.action.search.SearchRequest@22e9ea6f] lastShard [trueRemoteTransportException[[my_es_02][192.168.10.152:9300][indices:data/read/search[phase/query]]]; nested: SearchParseException[failed to parse search source [{"size":3,"query":{"bool":{"should":[{"term":{"uid":"44733065"}}]}},"sort":[{"count":{"order":"desc"}}]}]]; nested: SearchParseException[No mapping found for [count] in order to sort on]; Caused by: SearchParseException[failed to parse search source ```
注意,在报这个异常之前,有两行关键的log:
``` [2019-07-11 00:00:05,409][INFO ][cluster.routing.allocation] [my_es] Cluster health status changed from [RED] to [YELLOW] (reason: [shards started [[log2019-07-11][0], [log2019-07-11][2], [log2019-07-11][1]] ...]). [2019-07-11 00:00:06,232][INFO ][cluster.routing.allocation] [my_es] Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[log2019-07-11][1], [log2019-07-11][1]] ...]). ```
期间报异常的前2秒,es集群状态经历了从red到yellow再到green,虽然只有短暂的1秒,但却是排查问题非常关键的信息,我们知道出现这种信息的时候,代表的是es的主分片和副本分片正在做初始化或者出现了异常等待恢复,由此可以推论出这样一个场景,当凌晨12点刚过的第5秒,有写入该索引的es数据,触发了es动态索引的创建,由于这个索引有3个shard,每个shard分别有2个副本shard,也就是说共有6个shard需要初始化,假设初始化需要的时间为2秒,那么,恰巧在第6秒的时候,有个查询带排序的请求过来了,这个时候由于索引初始化并没有完成,所以在当天部分shard的mapping里面并没有查到该字段的信息,故产生了异常,之后当这个索引创建完成之后,再次收到的新查询请求是没有问题的。为了验证我们这个猜想,我们需要一段程序来做测试:
设计的复现场景有如下两步:
(1)A线程模拟查询请求,一直都在查询某一天的索引数据,起初这个索引并不存在,因为不存在所以查询使用通配符的方法,即使有排序字段,也并不会报错。
A线程的查询代码如下:
``` SearchRequestBuilder search=client.prepareSearch("log2019-07-11*"); search.setQuery(QueryBuilders.queryStringQuery("uid:111")); search.addSort("count", SortOrder.DESC); SearchResponse sr=search.get(); for ( SearchHit hit: sr.getHits()){ System.out.println(hit.getSource().toString()); } System.out.println(Thread.currentThread().getName()+"=>query"+" hit="+sr.getHits().getTotalHits()); ```
(2)B线程在A线程启动3秒后执行,然后向这个不存在的索引插入一条数据,由于第一次插入数据,这天的索引会被自动创建,里面就会涉及shard的初始化过程,这个时候同时A线程在查询就会复现出问题:
``` [No mapping found for [count] in order to sort on] ```
B线程的写入代码如下:
``` IndexRequestBuilder builder = client.prepareIndex("log2019-07-11", "log").setId("111"); builder.setCreate(true); java.util.Map<String , Object> map=new HashMap<>(); map.put("uid","111"); map.put("count","3"); builder.setSource(map); builder.execute().actionGet(); System.out.println(Thread.currentThread().getName()+" => " + "create index finished. " ); ```
知道问题后,那么如何解决这个问题呢?其实非常简单,我们只需要对于排序不存在的字段,作一下缺失容错即可,如下:
``` search.addSort("count", SortOrder.DESC); ```
改为
``` search.addSort(SortBuilders.fieldSort("count").unmappedType("integer").order(SortOrder.DESC)); ```
上面的代码,告诉es如果在排序时,遇到一个不存在的字段,我们只需要给其设置正确的排序类型即可,这样就能避免前面提到的2个导致排序失败的原因:
(1)count排序字段在mapping中无定义,并没有在索引名字后缀加*通配符时,必定每次都报异常(查询一个不存在字段,是不会报异常的,不管索引名有无后缀通配符)
(2)count排序字段在mapping中有定义,使用前面的排序方法,排序有时候报错,有时候不报(真正原因是当时shard正在做初始化导致的)
es索引本身是shemeless的结构,对于正常查询一个不存在的字段,是不会报错的,但是对于排序的字段,则有可能出现异常,所以我们在写相关的代码时,可以对排序字段加个容错处理,以提高我们程序的健壮性。
发表评论
-
elasticsearch里面bulk的用法
2018-04-09 20:23 1423上篇文章介绍了在es里 ... -
elasticsearch里面的关于批量读取mget的用法
2018-04-04 16:01 1833es的api除了提供了基本 ... -
elasticsearch的查询流程分析
2018-04-02 20:29 1329我们都知道es是一个分 ... -
如何在elasticsearch里面使用深度分页功能
2018-03-28 18:13 2021前面的文章提到过es默认的from+size的分页方式返回的结 ... -
如何在Elasticsearch里面使用索引别名
2018-03-27 20:37 1680在elasticsearch里面给index起一个alias ... -
如何优雅的全量读取Elasticsearch索引里面的数据
2018-03-26 20:27 7653### (一)scroll的介绍 有时候我们可能想要读取整个 ... -
关于elaticsearch中更新数据的几种方式
2018-03-21 19:00 967作为一个成熟的框架, ... -
Elasticsearch里面的segment合并
2018-03-20 17:50 2092通过前面的文章,我 ... -
Elasticsearch如何保证数据不丢失?
2018-03-19 20:52 2143上篇文章提到过,在elasticsearch和磁盘之间还有一层 ... -
为什么说Elasticsearch搜索是近实时的?
2018-03-16 19:41 9457通过前面两篇文章的介绍,我们大概已经知道了 Elasticse ... -
Elasticsearch如何动态维护一个不可变的倒排索引
2018-03-15 21:34 1138上一篇文章中介绍了Elasticsearch中是如何搜索文本 ... -
Elasticsearch如何检索数据
2018-03-14 20:11 1070我们都知道Elasticsearch是一个全文检索引擎,那么它 ... -
如何备份ElasticSearch索引数据到HDFS上
2018-02-09 18:19 2423在ElasticSearch里面备份策略已经比较成熟了 ... -
Elasticsearch5.6.4集群搭建
2018-02-07 20:13 1341本次搭建的是一个三节点的集群 (一)es的安装 (1)下 ... -
如何使log4j生成json格式的log
2017-09-15 17:44 3826使用java开发项目时,log日志一般都是应用程序必不可少的一 ... -
理解elasticsearch的parent-child关系
2017-09-04 18:43 2841前面文章介绍了,在es里面的几种数据组织关系,包括array ... -
简述ElasticSearch里面复杂关系数据的存储方式
2017-08-18 20:10 2414在传统的数据库里面,对数据关系描述无外乎三种,一对一,一对多和 ... -
使用Java Rest Client操作Elasticsearch
2017-08-09 19:42 2271Elasticsearch作为一个成熟的开源框架,对主流的多种 ... -
ElasticSearch里面的偏好查询
2017-06-22 17:17 1304在es查询的时候我们可 ... -
ElasticSearch里面的路由功能介绍
2017-06-21 18:17 2249在ElaticSearch里面,路由 ...
相关推荐
springboot整合elasticsearch7,进行数据同步。elasticsearch相关度查询、排序。高亮显示;自动补全等功能。代码仅供参考,代码中有具体的注释,可以根据代码及注释内容,对自己项目架构及业务进行修改、整合。
- **Elasticsearch Head**:一个基于Web的轻量级工具,可以查看集群信息、索引、文档等,适合快速调试和简单分析。 - **Marvel**:Elastic公司的一个付费服务,提供全面的性能监控和可视化功能。 **3. 使用Elastic...
需要注意的是,在下载过程中可能会遇到网络不稳定的情况,建议选择一个可靠的下载工具或者在网络环境较好的情况下进行下载。下载完成后,解压文件并按照官方文档中的步骤进行安装配置即可。 此外,对于初次接触...
Multi-Elasticsearch-Head是一个用于管理多个Elasticsearch集群的Web界面工具。它基于Elasticsearch-Head或者Kibana的Dev Tools Console概念,但是增加了同时连接和管理多个Elasticsearch实例或集群的能力。这意味着...
Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的...
好记性不如烂笔头哦~,ElasticSearch,简称es,es是一个开源的高拓展的分布式全文搜索引擎它可以近乎实时的存储、检索数据;本身拓展性很好,可以拓展到上百台服务器,处理PB级别的数据。es也是用Java开发并使用...
Elasticsearch 是一个开源的、高扩展的、分布式的、提供多用户能力的全文搜索引擎,也是一个基于 Lucene 搜索的服务器,可以近乎实时地存储和搜索数据。Elasticsearch 能很方便地用于对大量数据进行搜索和分析,充分...
Elasticsearch是一个开源的全文搜索引擎,它以分布式、RESTful接口和实时性为特点,广泛应用于数据搜索、分析和监控。这个"elasticsearch服务器安装包"包含了一个用于部署Elasticsearch服务的jar包,以及可能的配置...
总的来说,Elasticsearch-head是一个强大的Elasticsearch管理工具,能够极大地提高对Elasticsearch集群的操作效率。0.1.5_0版本提供了稳定的性能和用户体验,通过谷歌浏览器插件形式,使得在谷歌浏览器上使用更为...
Elasticsearch 是一个开源的全文搜索引擎,常用于大数据分析和实时搜索。为了确保系统重启后能够自动启动 Elasticsearch,我们需要配置一个开机自启脚本。在Linux系统中,这通常通过在 `/etc/init.d` 目录下创建一个...
Elasticsearch 是一个开源的全文搜索引擎,基于 Lucene 库,提供分布式、实时、可扩展的数据搜索和分析能力。在6.8.0版本中,Elasticsearch 提供了强大的索引管理和查询功能,支持多种数据类型,如文本、数值、日期...
Elasticsearch(ES)是一种流行的开源全文搜索引擎,它基于Lucene构建,提供了分布式、RESTful风格的搜索和分析引擎服务。在中文环境下,为了实现精确的分词和搜索,我们需要安装适合版本的分词插件,如“elastic...
在使用Spring Data Elasticsearch框架时,可能会遇到一个常见的问题,即版本兼容性问题。Spring Data Elasticsearch 5.4.0设计时可能并未考虑到与Elasticsearch 5.4.1的完全兼容,导致在升级Elasticsearch到5.4.1后...
elasticsearch-analysis-ik 是一个常用的中文分词器,在 Elasticsearch 中广泛应用于中文文本的分析和搜索。下面是 elasticsearch-analysis-ik 分词器的几个主要特点: 中文分词:elasticsearch-analysis-ik 是基于...
SortScript是Elasticsearch的一个增强组件,它提供了一个安全的环境来执行排序脚本,避免了对整个系统的性能影响。插件通常需要安装在每个节点上,并且支持配置以限制脚本的执行时间和内存使用,以防止资源消耗过大...
es-head是一个针对Elasticsearch的可视化操作插件。它提供了一个便捷的操作工具,可以连接Elasticsearch搜索引擎,并提供可视化的操作页面,对Elasticsearch进行各种设置和数据检索功能的管理。 es-head 插件可以在...
Elasticsearch是一个强大的开源搜索引擎,基于Apache Lucene构建,它为开发者和数据分析师提供了高效、可扩展、实时的搜索和分析功能。6.8.18版本是Elasticsearch的一个稳定版本,它在前几个版本的基础上进行了优化...
Elasticsearch 7.14.0 是一个高度可扩展的全文搜索引擎,广泛应用于日志分析、实时数据分析和全文检索等多个领域。这个压缩包包含了针对Windows和Linux操作系统的安装包,便于在不同环境下部署和使用Elasticsearch。...
Elasticsearch 是一个开源的分布式搜索引擎,以其高可伸缩性、实时性、灵活性以及强大的数据分析能力而闻名。在Windows平台上部署Elasticsearch,用户可以利用其强大的搜索和分析功能来处理大量数据。8.11版本带来了...
Elasticsearch(简称ES)是一款基于Lucene的分布式、RESTful搜索引擎,广泛应用于日志收集、数据分析等领域,是ELK(Elasticsearch、Logstash、Kibana)堆栈的重要组成部分。在处理中文数据时,合理的分词对于提升...