天天看點

elasticsearch 索引出現值沖突,用戶端報400錯誤

問題

最近在使用kibana時,發現管理索引那裡,某個索引下面有字段沖突的提示,然後去檢視fluentd用戶端的運作情況,發現在fluent程式自己的日志裡,偶爾會出現幾條錯誤資訊:’ElasticsearchError error=“400 - Rejected by Elasticsearch”’ , 這是怎麼回事呢?下面是錯誤的日志:

2018-08-13 18:02:55 +0800 [warn]: #0 dump an error event: error_class=Fluent::Plugin::ElasticsearchErrorHandler::ElasticsearchError error="400 - Rejected by Elasticsearch" location=nil tag="athena" time=2018-08-13 18:01:51.000000000 +0800 record={"method"=>"GET", "path"=>"/", "format"=>"html", "controller"=>"HomeController", "action"=>"home", "status"=>302, "duration"=>26.69, "view"=>0.0, "db"=>10.06, "location"=>"https://x.x.com/x/xxoo", "params"=>"{}", "referrer"=>"https://x.o.com/x/ooooo/166888", "user_id"=>101010101010, "session_id"=>"199000000000000"}      

分析

在kibana 那裡,對提示conflict 的

location

字段進行編輯,發現頁面最下方有些重要提示,如圖1所示:

elasticsearch 索引出現值沖突,用戶端報400錯誤

kibana 沖突提示

從上面提示可以看出,location 字段在不同索引裡的類型發生了變化,之前是

text

類型,後來變成了

geo_point

. 為了确認這點,我們可以通過es用戶端,或者直接用curl,對es的mapping進行檢視。

驗證

我這裡使用curl方式,先檢視為text類型的索引。

curl -X GET "localhost:9200/logs-app-athena-2018.08.10/_mapping/" -H 'Content-Type: application/json' | jq '.'      

這是location字段的定義:

"location": {
  "type": "text",
  "fields": {
    "keyword": {
      "type": "keyword",
      "ignore_above": 256
    }
  }
},      

然後再去看下提示location 為geo_point 類型的索引看下。還是用上面的指令,隻是改下索引的名字。得到的結果如預期一樣。

"location": {
  "type": "geo_point"
},      

但為什麼從12号開始的索引裡,這個值的類型就變成

geo_ip

了呢?仔細想了想,我11号好像做了一點操作。就是在

logs-app-nginx*

索引模版裡都添加了一個

_default_

,但為什麼這個會影響到logs-app-athena 的索引呢?這個問題一直沒想明白。這個是我當時做的操作:

curl -X GET "localhost:9200/_template/logs-app-nginx-* -d '{"order":0,"template":"*","settings":{},"mappings":{"_default_":{"properties":{"location":{"type":"geo_point"}}}}}'      

解決方案

  • 修改logs-app-athena系列索引的

    _default_

    值中的location類型為text
curl -X PUT "localhost:9200/logs-app-athena-*/_mappings/"  -H 'Content-Type: application/json' -d'
{
  "_default_": {
    "properties": {
      "location": {
        "type": "text"
      }
    }
  }
}      

Note: 在elasticsearch 6.0以後預設不在使用_default_ mappings.

default mapping

總結

這次問題的出現,對es又多了一點點了解,還要多看看官方文檔釋出的更新日志,可能某些功能在相應的版本裡就不推薦使用了。

另外做這次改動的根本原因是nginx日志都在

logs-app-nginx-*

索引裡,而location 字段沒有被自動解析成

geo_point

類型。後來不得已,換成了

logstash-*

為字首的索引後,類型才自動變成了

geo_point

。不知道還有沒有其它方法可以實作。

參考

change lat lon from float to geo_point geo point for all indexs template-mappings logstash lesson elasticsearch mapping

繼續閱讀