為什麼 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 來的混亂資料馴化:
- 穩定性: 用
path_match把變動大的欄位鎖死。 - 效能: 用
keyword取代text。 - 成本: 用
runtime處理邊緣資料。
這才是高流量日誌系統該有的姿態。