2014-04-21 50 views
3

我們有一個用於日誌聚合的經典Logstash + elasticsearch + kibana設置。我們使用它來聚合所有服務器和應用程序中的日誌,並且我們偶然發現了以下問題:ES第一次收到日誌行(本例中爲JSON文檔)時,會爲該文檔創建映射(請參閱http://bit.ly/1h3qwC9) 。大多數情況下,屬性被映射爲字符串,但在某些情況下,它們被映射爲日期或數字。在後一種情況下,如果另一個日誌行(來自不同的應用程序)具有相同的字段,但具有字符串值,則ES將無法爲其建立索引(向其日誌引發異常並像往常一樣繼續)。作爲一種解決方法,我們已經將ES配置爲忽略格式錯誤的文檔(index.mapping.ignore_malformed:true),但它更像是一種黑客攻擊。Logstash + ElasticSearch:初始類型映射導致缺失日誌行

任何想法如何以優雅的方式解決這個問題?

回答

2

這聽起來像你們不關心日期類型或任何類型。 我認爲最好的解決辦法是定義一個動態模板將定義所有類型爲字符串:

{ 
    "_default_" : { 
     "dynamic_templates" : [ 
      { 
       "long_to_string" : { 
        "match" : "*", 
        "match_mapping_type": "long", 
        "mapping" : { 
         "type" : "string", 
         "index" : "analyzed" 
        } 
       } 
      }, 
      { 
       "double_to_string" : { 
        "match" : "*", 
        "match_mapping_type": "double", 
        "mapping" : { 
         "type" : "string", 
         "index" : "analyzed" 
        } 
       } 
      }, 
      { 
       "float_to_string" : { 
        "match" : "*", 
        "match_mapping_type": "float", 
        "mapping" : { 
         "type" : "string", 
         "index" : "analyzed" 
        } 
       } 
      }, 
      { 
       "integer_to_string" : { 
        "match" : "*", 
        "match_mapping_type": "integer", 
        "mapping" : { 
         "type" : "string", 
         "index" : "analyzed" 
        } 
       } 
      }, 
      { 
       "date_to_string" : { 
        "match" : "*", 
        "match_mapping_type": "date", 
        "mapping" : { 
         "type" : "string", 
         "index" : "analyzed" 
        } 
       } 
      }, 
      { 
       "boolean_to_string" : { 
        "match" : "*", 
        "match_mapping_type": "boolean", 
        "mapping" : { 
         "type" : "string", 
         "index" : "analyzed" 
        } 
       } 
      } 
     ] 
    } 
} 

here

1

經過大量研究,我可以悲傷地宣佈,目前還沒有一個優雅的解決方案。雖然您可以聲明不應該分析字段,但不能指示它動態更改其類型,也不能自動忽略類型。

這實際上意味着您首先發送的任何類型將是您可以索引到該字段的唯一類型。 如果您使用某種類型預先聲明瞭該字段,那麼您將無法對該類型以外的任何其他類型進行索引。 無論哪種情況,所有不匹配類型都會下降。 另外,請注意,這經常會氾濫elasticsearch的日誌文件,您應該設置日誌輪轉或配置elasticsearch,以便不在日誌記錄中記錄這些錯誤。

你的解決方案確實是一個潛在的黑客(除非你確定未索引的數據是不相關的)。這很像是一個嘗試:除了傳入python。

作爲一般規則(從經驗來講),我建議您不要將不同類型的數據(不是不同的彈性搜索類型)編入同名的字段中,然後在嘗試時很難在Kibana中進行分析要使用基於數字/字符串的查詢(您將不能排序或顯示該特定字段上的直方圖或餅圖。)顯然,將代碼(或其他應用程序的代碼)更改爲不索引到在這種情況下,我會識別原始應用程序並使用logstash的grok(除非您已經發送json)並更改過濾器來替換該字段的名稱。

1

想知道爲什麼ignore_malformed被認爲是黑客?我想,出於完全相同的原因,他們把這個功能放進去 - 有時一個字段可能不會評估爲已聲明的數據類型。它真的會破壞什麼嗎?

編輯/更新:
日誌攝取/加工/索引,我的經驗是,攝入原木直接進入像ES商店是有很多原因一個壞主意(和隨意問那些是什麼,如果你好奇)。

總之,在將數據推送到任何數據存儲庫(如ElasticSearch或HDFS)之前,我總是使用一個接收/解析引擎。您可以使用logStash或flume等代理使用grok處理/分析數據。或者,編寫一個自定義的Spark應用程序來提取,驗證和構建數據,然後將其提供給ES。通常,我構建如下日誌管道: Producer(syslog等) - > Kafka/Kinesis(topic-1) - > Spark Streaming App(應用解析/結構化規則) - > Kafka/Kinesis(topic-2) ) - >多個代理(每個數據存儲庫一個代理組)。例如,我會部署一批訂閱topic-2並寫入HDFS的flume代理。同時,部署一堆logStash代理並寫入ES。

可能看起來有點牽扯但清潔/一致的數據的好處是多方面的。從臨時數據探索者到數據科學家的每個人都會感謝你:)

+1

上次我檢查了它,只是省略了文檔中的字段,如果你不想丟失數據,這是不可接受的。 – Shahar

+0

這是駭人的,因爲該設置是全球性的,適用於所有指標。 –

相關問題