Grafana 系列文章(九):開(kāi)源云原生日志解決方案 Loki 簡(jiǎn)介

簡(jiǎn)介

Grafana Labs 簡(jiǎn)介

Grafana 是用于時(shí)序數(shù)據(jù)的事實(shí)上的儀表盤(pán)解決方案。它支持近百個(gè)數(shù)據(jù)源。
Grafana Labs 想從一個(gè)儀表盤(pán)解決方案轉(zhuǎn)變成一個(gè)可觀(guān)察性 (observability) 平臺(tái),成為你需要對(duì)系統(tǒng)進(jìn)行調(diào)試時(shí)的首選之地。

完整的可觀(guān)察性

可觀(guān)察性。關(guān)于這意味著什么,有很多的定義??捎^(guān)察性就是對(duì)你的系統(tǒng)以及它們的行為和表現(xiàn)的可見(jiàn)性。典型的是這種模式,即可觀(guān)察性可以分成三個(gè)部分(或支柱):指標(biāo) (Metrics)、日志 (Logs) 和跟蹤 (Traces);每個(gè)部分都相互補(bǔ)充,幫助你快速找出問(wèn)題所在。

下面是在 Grafana Labs 博客和演講中反復(fù)出現(xiàn)的一張圖:

今天的現(xiàn)實(shí):不同的系統(tǒng),不同的數(shù)據(jù)

Slack 向我發(fā)出警告,說(shuō)有問(wèn)題,我就打開(kāi) Grafana 上服務(wù)的相關(guān)儀表盤(pán)。如果我發(fā)現(xiàn)某個(gè)面板或圖表有異常,我會(huì)在 Prometheus 的用戶(hù)界面中打開(kāi)查詢(xún),進(jìn)行更深入的研究。例如,如果我發(fā)現(xiàn)其中一個(gè)服務(wù)拋出了 500 個(gè)錯(cuò)誤,我會(huì)嘗試找出是否是某個(gè)特定的處理程序/路由拋出了這個(gè)錯(cuò)誤,或者是否所有的實(shí)例都拋出了這個(gè)錯(cuò)誤,等等。

接下來(lái),一旦我有了一個(gè)模糊的心理模型,知道什么地方出了問(wèn)題,我就會(huì)看一下日志(比如在 splunk 上)。在 Loki 之前,我習(xí)慣于使用 kubectl 來(lái)獲取相關(guān)的日志,看看錯(cuò)誤是什么,以及我是否可以做些什么。這對(duì)錯(cuò)誤來(lái)說(shuō)很有效,但有時(shí)我會(huì)因?yàn)楦哐舆t而放棄。之后,我從 traces (比如 AppD) 中得到更多的信息,關(guān)于什么是慢的,哪個(gè)方法/操作/功能是慢的?;蛘呤褂?Jaeger 來(lái)獲得追蹤信息。

雖然它們并不總是直接告訴我哪里出了問(wèn)題,但它們通常讓我足夠近距離地查看代碼并找出哪里出了問(wèn)題。然后,我可以擴(kuò)展服務(wù)(如果服務(wù)超載)或部署修復(fù)。

Loki 項(xiàng)目背景

Prometheus 工作得很好,Jaeger 也漸入佳境,而 kubectl 也很不錯(cuò)。標(biāo)簽 (label) 模型很強(qiáng)大,足以讓我找到出錯(cuò)服務(wù)的根源。如果我發(fā)現(xiàn) ingester 服務(wù)在出錯(cuò),我會(huì)做:kubectl --namespace prod logs -l name=ingester | grep XXX,以獲得相關(guān)的日志,并通過(guò)它們進(jìn)行 grep。

如果我發(fā)現(xiàn)某個(gè)特定的實(shí)例出錯(cuò)了,或者我想跟蹤某個(gè)服務(wù)的日志,我必須使用單獨(dú)的 pod 來(lái)跟蹤,因?yàn)?kubectl 不允許你根據(jù)標(biāo)簽選擇器來(lái)跟蹤。這并不理想,但對(duì)于大多數(shù)的使用情況來(lái)說(shuō)是可行的。

只要 pod 沒(méi)有崩潰或者沒(méi)有被替換,這就可以了。如果 pod 或節(jié)點(diǎn)被終止了,日志就會(huì)永遠(yuǎn)丟失。另外,kubectl 只存儲(chǔ)最近的日志,所以當(dāng)我們想要前一天或更早的日志時(shí),我們是盲目的。此外,不得不從 Grafana 跳到 CLI 再跳回來(lái)的做法并不理想。我們需要一個(gè)能減少上下文切換的解決方案,而我們探索的許多解決方案都非常昂貴,或者不能很好地?cái)U(kuò)展。

這是意料之中的事,因?yàn)樗鼈儽?select + grep 做得更多,而這正是我們所需要的。在看了現(xiàn)有的解決方案后,Grafana Labs 決定建立自己的。

Loki

由于對(duì)任何開(kāi)源的解決方案都不滿(mǎn)意,Grafana Labs 開(kāi)始與人交談,發(fā)現(xiàn)很多人都有同樣的問(wèn)題。事實(shí)上,Grafana Labs 已經(jīng)意識(shí)到,即使在今天,很多開(kāi)發(fā)人員仍然在 SSH 和 grep/tail 機(jī)器上的日志。他們所使用的解決方案要么太貴,要么不夠穩(wěn)定。事實(shí)上,人們被要求減少日志,Grafana Labs 認(rèn)為這是一種反模式的日志。Grafana Labs 認(rèn)為可以建立一些 Grafana Labs 內(nèi)部和更廣泛的開(kāi)源社區(qū)可以使用的東西。Grafana Labs 有一個(gè)主要目標(biāo):

  • 保持簡(jiǎn)單。只支持 grep!
這條來(lái)自@alicegoldfuss 的推文并不是支持 Loki,只是為了說(shuō)明 Loki 試圖解決的問(wèn)題

Grafana Labs 還瞄準(zhǔn)了其他目標(biāo):

  • 日志應(yīng)該是便宜的。不應(yīng)要求任何人少記錄日志。
  • 易于操作和擴(kuò)展
  • 指標(biāo) (Metrics)、日志 (Logs)(以及后來(lái)的追蹤 (traces))需要一起工作

最后一點(diǎn)很重要。Grafana Labs 已經(jīng)從 Prometheus 收集了指標(biāo)的元數(shù)據(jù),所以想利用這些元數(shù)據(jù)進(jìn)行日志關(guān)聯(lián)。例如,Prometheus 用 namespace、service name、實(shí)例 IP 等來(lái)標(biāo)記每個(gè)指標(biāo)。當(dāng)收到警報(bào)時(shí),使用元數(shù)據(jù)來(lái)找出尋找日志的位置。如果設(shè)法用同樣的元數(shù)據(jù)來(lái)標(biāo)記日志,我們就可以在度量和日志之間無(wú)縫切換。你可以在 這里 看到 Grafana Labs 寫(xiě)的內(nèi)部設(shè)計(jì)文檔。下面是 Loki 的演示視頻鏈接:

???Loki 演示視頻

架構(gòu)

根據(jù) Grafana Labs 建立和運(yùn)行 Cortex 的經(jīng)驗(yàn)--作為服務(wù)運(yùn)行的 Prometheus 的水平可擴(kuò)展的分布式版本--想出了以下架構(gòu):

Loki 架構(gòu)

指標(biāo)和日志之間的元數(shù)據(jù)匹配對(duì)我們來(lái)說(shuō)至關(guān)重要,Grafana Labs 最初決定只針對(duì) Kubernetes。想法是在每個(gè)節(jié)點(diǎn)上運(yùn)行一個(gè)日志收集代理,用它來(lái)收集日志,與 kubernetes 的 API 對(duì)話(huà),為日志找出正確的元數(shù)據(jù),并將它們發(fā)送到一個(gè)中央服務(wù),可以用它來(lái)顯示在 Grafana 內(nèi)收集的日志。

該代理支持與 Prometheus 相同的配置(relabelling rules),以確保元數(shù)據(jù)的匹配。我們稱(chēng)這個(gè)代理為 promtail。

深入 Loki —— 可擴(kuò)展的日志收集引擎:

Loki 內(nèi)部架構(gòu)

寫(xiě)入路徑和讀取路徑(查詢(xún))是相互脫鉤的,分開(kāi)說(shuō)明:

Loki 寫(xiě)入路徑

Distributor(分發(fā)器)

一旦 promtail 收集并發(fā)送日志到 Loki,Distributor 是第一個(gè)接收日志的組件?,F(xiàn)在,Loki 可能每秒收到數(shù)百萬(wàn)條寫(xiě),我們不想在它們進(jìn)來(lái)時(shí)就把它們寫(xiě)到數(shù)據(jù)庫(kù)中。那會(huì)搞宕任何數(shù)據(jù)庫(kù)。需要在數(shù)據(jù)進(jìn)入時(shí)對(duì)其進(jìn)行批處理和壓縮。

Grafana Labs 通過(guò)構(gòu)建壓縮的數(shù)據(jù)塊 (chunks),通過(guò) gzip 壓縮日志來(lái)實(shí)現(xiàn)這一點(diǎn)。ingester(采集器) 組件是一個(gè)有狀態(tài)組件,負(fù)責(zé)構(gòu)建塊,然后再刷新塊。Loki 有多個(gè) ingester,屬于每個(gè)流的日志應(yīng)該總是在同一個(gè) ingester 中結(jié)束,因?yàn)樗邢嚓P(guān)條目都在同一個(gè)塊中結(jié)束。通過(guò)構(gòu)建一個(gè) ingester 環(huán) (ring) 并使用一致性哈希來(lái)做到這一點(diǎn)。當(dāng)有條目進(jìn)入時(shí),分 Distributor 對(duì)日志的標(biāo)簽進(jìn)行哈希處理,然后根據(jù)哈希值查找將條目發(fā)送到哪個(gè) ingester。

Loki Distributor 組件

此外,為了實(shí)現(xiàn)冗余和彈性,Loki 將其復(fù)制了 n 次(默認(rèn)為 3 次)。

Ingester(采集器)

現(xiàn)在,Ingester 將接收條目并開(kāi)始構(gòu)建塊。

Loki Ingester 構(gòu)建 chunks

這基本上是對(duì)日志進(jìn)行 gzip 處理并追加。一旦塊 "填滿(mǎn) "了,我們就把它刷到數(shù)據(jù)庫(kù)中。我們?yōu)閴K(ObjectStorage)和索引使用不同的數(shù)據(jù)庫(kù),因?yàn)樗鼈兇鎯?chǔ)的數(shù)據(jù)類(lèi)型是不同的。

Loki Ingester 構(gòu)建好 chunks, 將 index 刷到索引庫(kù),將 chunks 刷到 chunks 庫(kù)

刷完一個(gè)塊后,Ingester 會(huì)創(chuàng)建一個(gè)新的空塊,并將新條目添加到該塊中。

Querier(查詢(xún)器)

讀取路徑非常簡(jiǎn)單,由 Querier 來(lái)完成大部分繁重的工作。給定一個(gè)時(shí)間范圍和標(biāo)簽選擇器,它查看索引以找出匹配的塊,并通過(guò)它們進(jìn)行搜索,給你結(jié)果。它還與 ingesters 對(duì)話(huà),以獲得尚未被刷到庫(kù)中的最新數(shù)據(jù)。

請(qǐng)注意,在 2019 年版本中,對(duì)于每個(gè)查詢(xún),一個(gè) Ingester 為你搜索所有相關(guān)的日志。Grafana Labs 已經(jīng)在 Cortex 中使用前端實(shí)現(xiàn)了查詢(xún)并行化,同樣的方法可以擴(kuò)展到 Loki,以提供分布式的 grep,這將使大型查詢(xún)變得足夠迅速。

Loki Querier 組件

可伸縮性

  1. Loki 把塊的數(shù)據(jù)放到對(duì)象存儲(chǔ)中,這樣就可以擴(kuò)展了。
  2. Loki 把索引放到 Cassandra/Bigtable/DynamoDB 或 Loki 內(nèi)置的 index db 中,這也是可以擴(kuò)展的。
  3. Distributors 和 Queriers 是無(wú)狀態(tài)組件,可以橫向擴(kuò)展。

說(shuō)到 ingester,它是一個(gè)有狀態(tài)的組件,但 Loki 已經(jīng)將完整的分片和重新分片的生命周期納入其中。當(dāng) rollout 工作完成后,或者當(dāng) ingester 被擴(kuò)大或縮小時(shí),環(huán)形拓?fù)浣Y(jié)構(gòu)會(huì)發(fā)生變化,ingester 會(huì)重新分配它們的塊,以匹配新的拓?fù)浣Y(jié)構(gòu)。這主要是取自 Cortex 的代碼,它已經(jīng)在生產(chǎn)中運(yùn)行了 5 年多。

總結(jié)

Loki: like Prometheus, but for logs.

Loki 是一個(gè)水平可擴(kuò)展、高可用、多租戶(hù)的日志聚合系統(tǒng),其靈感來(lái)自于 Prometheus。它被設(shè)計(jì)成非常具有成本效益和易于操作。它不對(duì)日志的內(nèi)容進(jìn)行索引,而是為每個(gè)日志流提供一組標(biāo)簽。

Grafana 系列文章

Grafana 系列文章

三人行, 必有我?guī)? 知識(shí)共享, 天下為公. 本文由東風(fēng)微鳴技術(shù)博客 EWhisper.cn 編寫(xiě).

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容