Blogger Information
Blog 28
fans 0
comment 0
visits 16753
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
ElasticSearch排序引起的all shards failed异常原因分析
Coco
Original
538 people have browsed it

背景

注:ElasticSearch版本为5.4。

在我们的日志系统里需要一些系统索引,这些系统索引在应用初始化的时候就会被添加到ElasticSearch中去,这些在ElasticSearch中的系统索引在没有索引数据的时候,只有索引名和一些配置信息,没有mapping信息。当用户去根据时间区间排序搜索日志信息的时候,ElasticSearch就会产生all shards failed异常。具体异常信息如下:

Caused by: [.alert/NXa3zq5WSb-wGBKgyZibzw] QueryShardException[No mapping found for [timestamp] in order to sort on]
at org.ElasticSearch.search.sort.FieldSortBuilder.build(FieldSortBuilder.java:262)
at org.ElasticSearch.search.sort.SortBuilder.buildSort(SortBuilder.java:156)
at org.ElasticSearch.search.SearchService.parseSource(SearchService.java:617)
at org.ElasticSearch.search.SearchService.createContext(SearchService.java:468)
at org.ElasticSearch.search.SearchService.createAndPutContext(SearchService.java:444)
at org.ElasticSearch.search.SearchService.executeQueryPhase(SearchService.java:252)
at org.ElasticSearch.action.search.SearchTransportService$6.messageReceived(SearchTransportService.java:331)
at org.ElasticSearch.action.search.SearchTransportService$6.messageReceived(SearchTransportService.java:328)
at org.ElasticSearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:69)
at org.ElasticSearch.transport.TransportService$7.doRun(TransportService.java:627)
at org.ElasticSearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:638)
at org.ElasticSearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
... 3 more

查看了.alert的索引数据再结合ElasticSearch的异常信息判断,我怀疑是二手手机号码拍卖平台由于.alert系统索引没有timestamp mapping信息引起的,.alert索引初始化没有任何数据时,ElasticSearch中的信息如下:

http://dev:9200/.alert
{
   ".alert": {
       "aliases": {
           "alert": {}
       },
       "mappings": {
           "alert": {}
       },
       "settings": {
           "index": {
               "refresh_interval": "-1",
               "number_of_shards": "5",
               "provided_name": ".alert",
               "creation_date": "1533613744728",
               "store": {
                   "type": "fs"
               },
               "number_of_replicas": "1",
               "uuid": "YuPjsObOTMO6u3fEdG6hVw",
               "version": {
                   "created": "5040099"
               }
           }
       }
   }
}

看到这些信息之后,我开始了用以下方法尝试解决。

解决方法

以下方法1和方法2都以失败而告终,只有方法3可以成功解决该问题。但在解决问题中我查找了很多资料,让我对ElasticSearch的mapping有了更深地理解,因此我将解决该问题的过程记录了下来。

方法1:添加索引模板

首先,由于是没有timestamp这个mapping信息,因此我想到创建索引模板,将.alert这个索引的mappings信息用模板来设置,以便在索引创建的时候就有相应的mapping信息。模板信息如下:

{
   "alert": {
       "order": 0,
       "template": "alert",
       "settings": {
           "index": {
               "number_of_shards": "5",
               "number_of_replicas": "1",
               "refresh_interval": "2s"
           }
       },
       "mappings": {
           "alert": {
               "properties": {
                   "timestamp": {
                       "type": "date"
                   }
               }
           }
       },
       "aliases": {}
   }
}

但是,经过测试后发现,all shards failed的问题还是会产生。究其原因是由于:

索引模板只会在插入新索引数据的时候生效,如果没有索引数据,索引模板定义的mappings信息不会生效,而且对模板的改变不会影响到已存在的索引。

此时,.alert这个索引为空,还没有新数据插入,因此,模板不会生效,也就致使该方法不会解决all shards failed的问题。

方法2:创建索引时添加mapping

由于ElasticSearch允许在创建索引时就创建mapping信息,于是我想到了这个方法,经过测试后,可以解决all shards failed的问题。但是,产生了一个严重的后果,我们用.alert索引来记录服务器报警信息,当我往.alert这个索引里添加数据时,只有timestamp这个字段的数据添加进去了,其他数据像产生报警的主机、报警内容等信息添加失败。

查询官方文档发现:

mapping信息一旦被创建,就不允许被修改。改变已有的mapping就意味着使已经存在的索引数据无效,解决的办法就是使用正确的mappings信息来创建新的索引,然后重新把数据添加到新索引中。虽然官方提供了reindex方法来解决这个问题,但是,在大数据量的情况下,reindex代价比较高,因此,创建索引时添加mapping这个方法也行不通。

方法3:给排序条件加unmapped_type

ElasticSearch的search api可以设置排序时忽略字段的哪些映射。默认情况下,如果没有与排序字段关联的映射,则搜索请求将失败。unmapped_type选项允许设置忽略没有映射的字段,从而不对该字段排序。由于timestamp的mapping为date类型,因此,在搜索排序条件中增加{"timestamp":{"unmapped_type":"date"}}成功解决由于排序字段没有date映射引起的all shards failed问题。


Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post