博主信息
博文 28
粉丝 0
评论 0
访问量 23015
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
ElasticSearch排序引起的all shards failed异常原因分析
Coco
原创
839人浏览过

背景

注: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问题。


本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
作者最新博文
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学