輕量化日誌 Loki 全攻略,運維利器要收好

網路通訊頻道發表於2022-12-02

1、前言

在對公司容器雲的日誌方案進行設計的時候,發現主流的 ELK(Elasticsearch,Logstash,Kibana)或者 EFK(Elasticsearch,Filebeat or Fluentd,Kibana)比較重,再加上現階段對於 ES 複雜的搜尋功能很多都用不上,最終選擇了 Grafana 開源的 Loki 日誌系統。

下面我們來介紹下 Loki 的一些基本概念和架構,當然 EFK 作為業界成熟的日誌聚合解決方案也是大家應該需要熟悉和掌握的。

2、簡介

Loki 是 Grafana Labs 團隊最新的開源專案,是一個水平可擴充套件,高可用性,多租戶的日誌聚合系統。它的設計非常經濟高效且易於操作,因為它不會為日誌內容編制索引,而是為每個日誌流編制一組標籤,專門為 Prometheus 和 Kubernetes 使用者做了相關最佳化。該專案受 Prometheus 啟發,官方的介紹就是:Like Prometheus,But For Logs.,類似於 Prometheus 的日誌系統;

專案地址:

與其他日誌聚合系統相比, Loki 具有下面的一些特性:

不對日誌進行全文索引。透過儲存壓縮非結構化日誌和僅索引後設資料,Loki 操作起來會更簡單,更省成本。

透過使用與 Prometheus 相同的標籤記錄流對日誌進行索引和分組,這使得日誌的擴充套件和操作效率更高,能對接 alertmanager;

特別適合儲存 Kubernetes Pod 日誌;諸如 Pod 標籤之類的後設資料會被自動刪除和編入索引;

受 Grafana 原生支援,避免kibana和grafana來回切換;

3、部署

3.1 本地化模式安裝

下載 Promtail 和 Loki

安裝 Promtail

安裝loki

4、使用

4.1 grafana上配置loki資料來源

grafana-loki-dashsource

在資料來源列表中選擇 Loki,配置 Loki 源地址:

grafana-loki-dashsource-config

源地址配置 即可,儲存。

儲存完成後,切換到 grafana 左側區域的 Explore,即可進入到 Loki 的頁面

grafana-loki

然後我們點選 Log labels 就可以把當前系統採集的日誌標籤給顯示出來,可以根據這些標籤進行日誌的過濾查詢:

grafana-loki-log-labels

比如我們這裡選擇 /var/log/messages,就會把該檔案下面的日誌過濾展示出來,不過由於時區的問題,可能還需要設定下時間才可以看到資料:

grafana-loki-logs

這裡展示的是 promtail 容器裡面 / var/log 目錄中的日誌

promtail 容器 /etc/promtail/config.yml

這裡的 job 就是 varlog,檔案路徑就是 /var/log/*log

4.2 在grafana explore上配置檢視日誌

算 qps rate({job=”message”} |=”kubelet” [1m])

4.3 只索引標籤

之前多次提到 loki 和 es 最大的不同是 loki 只對標籤進行索引而不對內容索引 下面我們舉例來看下。

以簡單的 promtail 配置舉例

配置解讀

上面這段配置代表啟動一個日誌採集任務

這個任務有 1 個固定標籤job=”syslog”

採集日誌路徑為 /var/log/messages,會以一個名為 filename 的固定標籤

在 promtail 的 web 頁面上可以看到類似 prometheus 的 target 資訊頁面

可以和使用 Prometheus 一樣的標籤匹配語句進行查詢

如果我們配置了兩個 job,則可以使用{job=~”apache|syslog”} 進行多 job 匹配

同時也支援正則和正則非匹配

5.3 標籤匹配模式的特點

原理

和 prometheus 一致,相同標籤對應的是一個流 prometheus 處理 series 的模式

prometheus 中標籤一致對應的同一個 hash 值和 refid(正整數遞增的 id),也就是同一個 series

時序資料不斷的 append 追加到這個 memseries 中

當有任意標籤發生變化時會產生新的 hash 值和 refid,對應新的 series

loki 處理日誌的模式 - 和 prometheus 一致,loki 一組標籤值會生成一個 stream - 日誌隨著時間的遞增會追加到這個 stream 中,最後壓縮為 chunk - 當有任意標籤發生變化時會產生新的 hash 值,對應新的 stream

查詢過程

所以 loki 先根據標籤算出 hash 值在倒排索引中找到對應的 chunk?

然後再根據查詢語句中的關鍵詞等進行過濾,這樣能大大的提速

因為這種根據標籤算雜湊在倒排中查詢 id,對應找到儲存的塊在 prometheus 中已經被驗證過了

屬於開銷低

速度快

4.5 動態標籤和高基數

所以有了上述知識,那麼就得談談動態標籤的問題了。

兩個概念

- 何為動態標籤:說白了就是標籤的 value 不固定

- 何為高基數標籤:說白了就是標籤的 value 可能性太多了,達到 10 萬,100 萬甚至更多

比如 apache 的 access 日誌

在 Promtail 中使用 regex 想要匹配 action 和 status_code 兩個標籤

那麼對應 action=get/post 和 status_code=200/400 則對應 4 個流

那四個日誌行將變成四個單獨的流,並開始填充四個單獨的塊。

如果出現另一個獨特的標籤組合(例如 status_code =“500”),則會建立另一個新流

高基數問題

就像上面,如果給 ip 設定一個標籤,現在想象一下,如果您為設定了標籤 ip,來自使用者的每個不同的 ip 請求不僅成為唯一的流,可以快速生成成千上萬的流,這是高基數,這可以殺死 Loki。

如果欄位沒有被當做標籤被索引,會不會查詢很慢。

Loki 的超級能力是將查詢分解為小塊並並行分發,以便您可以在短時間內查詢大量日誌資料

4.6 全文索引問題

大索引既複雜又昂貴。通常,日誌資料的全文索引的大小等於或大於日誌資料本身的大小。

要查詢日誌資料,需要載入此索引,並且為了提高效能,它可能應該在記憶體中。這很難擴充套件,並且隨著您攝入更多日誌,索引會迅速變大。Loki 的索引通常比攝取的日誌量小一個數量級,索引的增長非常緩慢

加速查詢沒標籤欄位

以上邊提到的 ip 欄位為例 - 使用過濾器表示式查詢

loki查詢時的分片(按時間範圍分段grep)

Loki 將把查詢分解成較小的分片,併為與標籤匹配的流開啟每個區塊,並開始尋找該 IP 地址。

這些分片的大小和並行化的數量是可配置的,並取決於您提供的資源。

如果需要,您可以將分片間隔配置為5m,部署20個查詢器,並在幾秒鐘內處理千兆位元組的日誌,或者您可以發瘋並設定 200 個查詢器並處理 TB 的日誌!

兩種索引模式對比

es 的大索引,不管你查不查詢,他都必須時刻存在。比如長時間佔用過多的記憶體

loki 的邏輯是查詢時再啟動多個分段並行查詢。

日誌量少時少加標籤

因為每多載入一個 chunk 就有額外的開銷,

舉例,如果該查詢是 {app=”loki”,level!=”debug”}

在沒加 level 標籤的情況下只需載入一個 chunk 即 app=“loki” 的標籤。

如果加了 level 的情況,則需要把 level=info,warn,error,critical 5 個 chunk 都載入再查詢

需要標籤時再去新增

當 chunk_target_size=1MB 時代表 以 1MB 的壓縮大小來切割塊,

對應的原始日誌大小在 5MB-10MB,如果日誌在 max_chunk_age 時間內能達到 10MB,考慮新增標籤。

日誌應當按時間遞增

這個問題和 tsdb 中處理舊資料是一樣的道理,目前 loki 為了效能考慮直接拒絕掉舊資料

來自 “ https://www.cnblogs.com/you-men/p/14900249.html ”, 原文作者:常見-youmen;原文連結:https://www.cnblogs.com/you-men/p/14900249.html,如有侵權,請聯絡管理員刪除。

相關文章