問題
最近在使用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所示:
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系列索引的
值中的location類型為text_default_
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
。不知道還有沒有其它方法可以實作。