The Samo Log

Elasticsearch Dynamic Templates 實戰:如何讓 Kafka Log 乖乖聽話?

為什麼 Kafka Log 總是搞死 ES?

我每天透過 Kafka 處理海量的系統日誌。最讓 SRE 頭痛的不是流量,而是 「髒資料 (Dirty Data)」

舉個經典例子:某個微服務的 response_time 欄位,99% 的時間是數字 (long),但當系統出錯時,開發者直接吐了一個字串 "Timeout"。 這時候,Elasticsearch 的 Default Mapping 會因為型別衝突 (Type Mismatch) 直接拒絕寫入,甚至導致整個 Bulk Request 失敗。

這份官方文件給了我們解法:Dynamic Templates

以下是我歸納出 SRE 必備的三大黃金樣板。

1. 預設全轉 Keyword (節省 40% 空間)

官方文件提到 strings_as_keywords。這是 Log 系統最基本的優化。 大多的 Log 欄位(如 user_id, trace_id, pod_name)我們只需要「精確比對」,不需要全文檢索。預設的 text 型別會建立倒排索引,既慢又佔空間。

{
  "strings_as_keywords": {
    "match_mapping_type": "string",
    "mapping": {
      "type": "keyword",
      "ignore_above": 256
    }
  }
}

SRE 觀點: 加入這個設定後,我們的 Index Size 通常會減少 30%~40%,而且聚合查詢 (Aggregation) 速度更快。

2. 善用 path_match 隔離「高風險區」

最近遇到的 flattened 問題,其實可以用 path_match 完美解決。 假設我們知道 payload.data.* 下面的結構常常變動(一下是 Date,一下是 Object),我們可以劃定一個「無法無天區」,強制使用 flattened 型別。

{
  "payload_isolation": {
    "path_match": "payload.data.*",  // 鎖定特定路徑
    "mapping": {
      "type": "flattened"        // 不管裡面是什麼,全部壓扁
    }
  }
}

這樣一來,不管開發者在 payload.data 裡面塞了多複雜的 JSON,ES 都不會報錯,我們依然可以用 payload.data.key 進行搜尋,只是無法做數值範圍查詢而已。

結論:由 SRE 定義規則

不要讓 Elasticsearch 猜測你的資料型別,它通常會猜錯。 透過 Dynamic Templates,我們將 Kafka 來的混亂資料馴化:

  1. 穩定性: 用 path_match 把變動大的欄位鎖死。
  2. 效能: 用 keyword 取代 text
  3. 成本: 用 runtime 處理邊緣資料。

這才是高流量日誌系統該有的姿態。

寫作日曆

Mon Wed Fri
Less
More

也看看我的其他文章

載入留言中...