簡介
Grafana Labs 簡介
Grafana 是用于時序數(shù)據(jù)的事實上的儀表盤解決方案。它支持近百個數(shù)據(jù)源。
Grafana Labs 想從一個儀表盤解決方案轉(zhuǎn)變成一個可觀察性 (observability) 平臺,成為你需要對系統(tǒng)進(jìn)行調(diào)試時的首選之地。
完整的可觀察性
可觀察性。關(guān)于這意味著什么,有很多的定義??捎^察性就是對你的系統(tǒng)以及它們的行為和表現(xiàn)的可見性。典型的是這種模式,即可觀察性可以分成三個部分(或支柱):指標(biāo) (Metrics)、日志 (Logs) 和跟蹤 (Traces);每個部分都相互補充,幫助你快速找出問題所在。
下面是在 Grafana Labs 博客和演講中反復(fù)出現(xiàn)的一張圖:

Slack 向我發(fā)出警告,說有問題,我就打開 Grafana 上服務(wù)的相關(guān)儀表盤。如果我發(fā)現(xiàn)某個面板或圖表有異常,我會在 Prometheus 的用戶界面中打開查詢,進(jìn)行更深入的研究。例如,如果我發(fā)現(xiàn)其中一個服務(wù)拋出了 500 個錯誤,我會嘗試找出是否是某個特定的處理程序/路由拋出了這個錯誤,或者是否所有的實例都拋出了這個錯誤,等等。
接下來,一旦我有了一個模糊的心理模型,知道什么地方出了問題,我就會看一下日志(比如在 splunk 上)。在 Loki 之前,我習(xí)慣于使用 kubectl 來獲取相關(guān)的日志,看看錯誤是什么,以及我是否可以做些什么。這對錯誤來說很有效,但有時我會因為高延遲而放棄。之后,我從 traces (比如 AppD) 中得到更多的信息,關(guān)于什么是慢的,哪個方法/操作/功能是慢的。或者使用 Jaeger 來獲得追蹤信息。
雖然它們并不總是直接告訴我哪里出了問題,但它們通常讓我足夠近距離地查看代碼并找出哪里出了問題。然后,我可以擴展服務(wù)(如果服務(wù)超載)或部署修復(fù)。
Loki 項目背景
Prometheus 工作得很好,Jaeger 也漸入佳境,而 kubectl 也很不錯。標(biāo)簽 (label) 模型很強大,足以讓我找到出錯服務(wù)的根源。如果我發(fā)現(xiàn) ingester 服務(wù)在出錯,我會做:kubectl --namespace prod logs -l name=ingester | grep XXX,以獲得相關(guān)的日志,并通過它們進(jìn)行 grep。
如果我發(fā)現(xiàn)某個特定的實例出錯了,或者我想跟蹤某個服務(wù)的日志,我必須使用單獨的 pod 來跟蹤,因為 kubectl 不允許你根據(jù)標(biāo)簽選擇器來跟蹤。這并不理想,但對于大多數(shù)的使用情況來說是可行的。
只要 pod 沒有崩潰或者沒有被替換,這就可以了。如果 pod 或節(jié)點被終止了,日志就會永遠(yuǎn)丟失。另外,kubectl 只存儲最近的日志,所以當(dāng)我們想要前一天或更早的日志時,我們是盲目的。此外,不得不從 Grafana 跳到 CLI 再跳回來的做法并不理想。我們需要一個能減少上下文切換的解決方案,而我們探索的許多解決方案都非常昂貴,或者不能很好地擴展。
這是意料之中的事,因為它們比 select + grep 做得更多,而這正是我們所需要的。在看了現(xiàn)有的解決方案后,Grafana Labs 決定建立自己的。
Loki
由于對任何開源的解決方案都不滿意,Grafana Labs 開始與人交談,發(fā)現(xiàn)很多人都有同樣的問題。事實上,Grafana Labs 已經(jīng)意識到,即使在今天,很多開發(fā)人員仍然在 SSH 和 grep/tail 機器上的日志。他們所使用的解決方案要么太貴,要么不夠穩(wěn)定。事實上,人們被要求減少日志,Grafana Labs 認(rèn)為這是一種反模式的日志。Grafana Labs 認(rèn)為可以建立一些 Grafana Labs 內(nèi)部和更廣泛的開源社區(qū)可以使用的東西。Grafana Labs 有一個主要目標(biāo):
- 保持簡單。只支持 grep!

Grafana Labs 還瞄準(zhǔn)了其他目標(biāo):
- 日志應(yīng)該是便宜的。不應(yīng)要求任何人少記錄日志。
- 易于操作和擴展
- 指標(biāo) (Metrics)、日志 (Logs)(以及后來的追蹤 (traces))需要一起工作
最后一點很重要。Grafana Labs 已經(jīng)從 Prometheus 收集了指標(biāo)的元數(shù)據(jù),所以想利用這些元數(shù)據(jù)進(jìn)行日志關(guān)聯(lián)。例如,Prometheus 用 namespace、service name、實例 IP 等來標(biāo)記每個指標(biāo)。當(dāng)收到警報時,使用元數(shù)據(jù)來找出尋找日志的位置。如果設(shè)法用同樣的元數(shù)據(jù)來標(biāo)記日志,我們就可以在度量和日志之間無縫切換。你可以在 這里 看到 Grafana Labs 寫的內(nèi)部設(shè)計文檔。下面是 Loki 的演示視頻鏈接:
架構(gòu)
根據(jù) Grafana Labs 建立和運行 Cortex 的經(jīng)驗--作為服務(wù)運行的 Prometheus 的水平可擴展的分布式版本--想出了以下架構(gòu):

指標(biāo)和日志之間的元數(shù)據(jù)匹配對我們來說至關(guān)重要,Grafana Labs 最初決定只針對 Kubernetes。想法是在每個節(jié)點上運行一個日志收集代理,用它來收集日志,與 kubernetes 的 API 對話,為日志找出正確的元數(shù)據(jù),并將它們發(fā)送到一個中央服務(wù),可以用它來顯示在 Grafana 內(nèi)收集的日志。
該代理支持與 Prometheus 相同的配置(relabelling rules),以確保元數(shù)據(jù)的匹配。我們稱這個代理為 promtail。
深入 Loki —— 可擴展的日志收集引擎:

寫入路徑和讀取路徑(查詢)是相互脫鉤的,分開說明:

Distributor(分發(fā)器)
一旦 promtail 收集并發(fā)送日志到 Loki,Distributor 是第一個接收日志的組件?,F(xiàn)在,Loki 可能每秒收到數(shù)百萬條寫,我們不想在它們進(jìn)來時就把它們寫到數(shù)據(jù)庫中。那會搞宕任何數(shù)據(jù)庫。需要在數(shù)據(jù)進(jìn)入時對其進(jìn)行批處理和壓縮。
Grafana Labs 通過構(gòu)建壓縮的數(shù)據(jù)塊 (chunks),通過 gzip 壓縮日志來實現(xiàn)這一點。ingester(采集器) 組件是一個有狀態(tài)組件,負(fù)責(zé)構(gòu)建塊,然后再刷新塊。Loki 有多個 ingester,屬于每個流的日志應(yīng)該總是在同一個 ingester 中結(jié)束,因為所有相關(guān)條目都在同一個塊中結(jié)束。通過構(gòu)建一個 ingester 環(huán) (ring) 并使用一致性哈希來做到這一點。當(dāng)有條目進(jìn)入時,分 Distributor 對日志的標(biāo)簽進(jìn)行哈希處理,然后根據(jù)哈希值查找將條目發(fā)送到哪個 ingester。

此外,為了實現(xiàn)冗余和彈性,Loki 將其復(fù)制了 n 次(默認(rèn)為 3 次)。
Ingester(采集器)
現(xiàn)在,Ingester 將接收條目并開始構(gòu)建塊。

這基本上是對日志進(jìn)行 gzip 處理并追加。一旦塊 "填滿 "了,我們就把它刷到數(shù)據(jù)庫中。我們?yōu)閴K(ObjectStorage)和索引使用不同的數(shù)據(jù)庫,因為它們存儲的數(shù)據(jù)類型是不同的。

刷完一個塊后,Ingester 會創(chuàng)建一個新的空塊,并將新條目添加到該塊中。
Querier(查詢器)
讀取路徑非常簡單,由 Querier 來完成大部分繁重的工作。給定一個時間范圍和標(biāo)簽選擇器,它查看索引以找出匹配的塊,并通過它們進(jìn)行搜索,給你結(jié)果。它還與 ingesters 對話,以獲得尚未被刷到庫中的最新數(shù)據(jù)。
請注意,在 2019 年版本中,對于每個查詢,一個 Ingester 為你搜索所有相關(guān)的日志。Grafana Labs 已經(jīng)在 Cortex 中使用前端實現(xiàn)了查詢并行化,同樣的方法可以擴展到 Loki,以提供分布式的 grep,這將使大型查詢變得足夠迅速。

可伸縮性
- Loki 把塊的數(shù)據(jù)放到對象存儲中,這樣就可以擴展了。
- Loki 把索引放到 Cassandra/Bigtable/DynamoDB 或 Loki 內(nèi)置的 index db 中,這也是可以擴展的。
- Distributors 和 Queriers 是無狀態(tài)組件,可以橫向擴展。
說到 ingester,它是一個有狀態(tài)的組件,但 Loki 已經(jīng)將完整的分片和重新分片的生命周期納入其中。當(dāng) rollout 工作完成后,或者當(dāng) ingester 被擴大或縮小時,環(huán)形拓?fù)浣Y(jié)構(gòu)會發(fā)生變化,ingester 會重新分配它們的塊,以匹配新的拓?fù)浣Y(jié)構(gòu)。這主要是取自 Cortex 的代碼,它已經(jīng)在生產(chǎn)中運行了 5 年多。
總結(jié)
Loki: like Prometheus, but for logs.
Loki 是一個水平可擴展、高可用、多租戶的日志聚合系統(tǒng),其靈感來自于 Prometheus。它被設(shè)計成非常具有成本效益和易于操作。它不對日志的內(nèi)容進(jìn)行索引,而是為每個日志流提供一組標(biāo)簽。
Grafana 系列文章
三人行, 必有我?guī)? 知識共享, 天下為公. 本文由東風(fēng)微鳴技術(shù)博客 EWhisper.cn 編寫.