<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Grafana Loki 架構(gòu)

          共 8137字,需瀏覽 17分鐘

           ·

          2021-05-07 01:56

          Grafana Loki 是一套可以組合成一個(gè)功能齊全的日志堆棧組件,與其他日志記錄系統(tǒng)不同,Loki 是基于僅索引有關(guān)日志元數(shù)據(jù)的想法而構(gòu)建的:標(biāo)簽(就像 Prometheus 標(biāo)簽一樣)。日志數(shù)據(jù)本身被壓縮然后并存儲(chǔ)在對(duì)象存儲(chǔ)(例如 S3 或 GCS)的塊中,甚至存儲(chǔ)在本地文件系統(tǒng)上,輕量級(jí)的索引和高度壓縮的塊簡化了操作,并顯著降低了 Loki 的成本,Loki 更適合中小團(tuán)隊(duì)。

          Grafana Loki 主要由 3 部分組成:

          • loki: 日志記錄引擎,負(fù)責(zé)存儲(chǔ)日志和處理查詢
          • promtail: 代理,負(fù)責(zé)收集日志并將其發(fā)送給 loki
          • grafana: UI 界面

          多租戶

          Loki 支持多租戶,以使租戶之間的數(shù)據(jù)完全分離。當(dāng) Loki 在多租戶模式下運(yùn)行時(shí),所有數(shù)據(jù)(包括內(nèi)存和長期存儲(chǔ)中的數(shù)據(jù))都由租戶 ID 分區(qū),該租戶 ID 是從請(qǐng)求中的 X-Scope-OrgID HTTP 頭中提取的。當(dāng) Loki 不在多租戶模式下時(shí),將忽略 Header 頭,并將租戶 ID 設(shè)置為 fake,這將顯示在索引和存儲(chǔ)的塊中。

          運(yùn)行模式

          Loki 運(yùn)行模式

          Loki 針對(duì)本地運(yùn)行(或小規(guī)模運(yùn)行)和水平擴(kuò)展進(jìn)行了優(yōu)化嗎,Loki 帶有單一進(jìn)程模式,可在一個(gè)進(jìn)程中運(yùn)行所有必需的微服務(wù)。單進(jìn)程模式非常適合測(cè)試 Loki 或以小規(guī)模運(yùn)行。為了實(shí)現(xiàn)水平可伸縮性,可以將 Loki 的微服務(wù)拆分為單獨(dú)的組件,從而使它們彼此獨(dú)立地?cái)U(kuò)展。每個(gè)組件都產(chǎn)生一個(gè)用于內(nèi)部請(qǐng)求的 gRPC 服務(wù)器和一個(gè)用于外部 API 請(qǐng)求的 HTTP 服務(wù),所有組件都帶有 HTTP 服務(wù)器,但是大多數(shù)只暴露就緒接口、運(yùn)行狀況和指標(biāo)端點(diǎn)。

          Loki 運(yùn)行哪個(gè)組件取決于命令行中的 -target 標(biāo)志或 Loki 的配置文件中的 target:<string> 部分。當(dāng) target 的值為 all 時(shí),Loki 將在單進(jìn)程中運(yùn)行其所有組件。,這稱為單進(jìn)程單體模式。使用 Helm 安裝 Loki 時(shí),單單體模式是默認(rèn)部署方式。

          當(dāng) target 未設(shè)置為 all(即被設(shè)置為 querieringesterquery-frontenddistributor),則可以說 Loki 在水平伸縮微服務(wù)模式下運(yùn)行。

          Loki 的每個(gè)組件,例如 ingesterdistributors 都使用 Loki 配置中定義的 gRPC 偵聽端口通過 gRPC 相互通信。當(dāng)以單體模式運(yùn)行組件時(shí),仍然是這樣的:盡管每個(gè)組件都以相同的進(jìn)程運(yùn)行,但它們?nèi)詫⑼ㄟ^本地網(wǎng)絡(luò)相互連接進(jìn)行組件之間的通信。

          單體模式非常適合于本地開發(fā)、小規(guī)模等場(chǎng)景,單體模式可以通過多個(gè)進(jìn)程進(jìn)行擴(kuò)展,但有以下限制:

          • 當(dāng)運(yùn)行帶有多個(gè)副本的單體模式時(shí),當(dāng)前無法使用本地索引和本地存儲(chǔ),因?yàn)槊總€(gè)副本必須能夠訪問相同的存儲(chǔ)后端,并且本地存儲(chǔ)對(duì)于并發(fā)訪問并不安全。
          • 各個(gè)組件無法獨(dú)立縮放,因此讀取組件的數(shù)量不能超過寫入組件的數(shù)量。

          組件

          Loki 組件

          Distributor

          distributor 服務(wù)負(fù)責(zé)處理客戶端寫入的日志,它本質(zhì)上是日志數(shù)據(jù)寫入路徑中的第一站,一旦 distributor 收到日志數(shù)據(jù),會(huì)將其拆分為多個(gè)批次,然后并行發(fā)送給多個(gè) ingester

          distributor 通過 gRPC 與 ingester 通信,它們都是無狀態(tài)的,可以根據(jù)需要擴(kuò)大或縮小規(guī)模。

          哈希

          Distributors 將一致性哈希和可配置的復(fù)制因子結(jié)合使用,以確定 Ingester 服務(wù)的哪些實(shí)例應(yīng)該接收指定的流。

          流是一組與租戶和唯一標(biāo)簽集關(guān)聯(lián)的日志,使用租戶 ID 和標(biāo)簽集對(duì)流進(jìn)行 hash 處理,然后使用哈希查詢要發(fā)送流的 Ingesters

          存儲(chǔ)在 Consul 中的哈希環(huán)被用來實(shí)現(xiàn)一致性哈希,所有的 ingester 都會(huì)使用自己擁有的一組 Token 注冊(cè)到哈希環(huán)中,每個(gè) Token 是一個(gè)隨機(jī)的無符號(hào) 32 位數(shù)字,與一組 Token 一起,ingester 將其狀態(tài)注冊(cè)到哈希環(huán)中,狀態(tài) JOININGACTIVE 都可以接收寫請(qǐng)求,而 ACTIVELEAVINGingesters 可以接收讀請(qǐng)求。在進(jìn)行哈希查詢時(shí),distributors 只使用處于請(qǐng)求的適當(dāng)狀態(tài)的 ingester 的 Token。

          為了進(jìn)行哈希查找,distributors 找到最小合適的 Token,其值大于日志流的哈希值,當(dāng)復(fù)制因子大于 1 時(shí),屬于不同 ingesters 的下一個(gè)后續(xù) Token(在環(huán)中順時(shí)針方向)也將被包括在結(jié)果中。

          這種哈希配置的效果是,一個(gè) ingester 擁有的每個(gè) Token 都負(fù)責(zé)一個(gè)范圍的哈希值,如果有三個(gè)值為 0、25 和 50 的 Token,那么 3 的哈希值將被給予擁有 25 這個(gè) Token 的 ingester,擁有 25 這個(gè) Token 的 ingester負(fù)責(zé)1-25的哈希值范圍。

          Quorum(仲裁)一致性

          由于所有的 distributors 共享對(duì)同一哈希環(huán)的訪問權(quán),所以寫請(qǐng)求可以被發(fā)送到任何 distributor

          為了確保查詢結(jié)果的一致性,Loki 在讀和寫上使用 Dynamo 式的仲裁一致性方式,這意味著 distributor 將等待至少一半加一個(gè) ingesters 的響應(yīng),然后再對(duì)發(fā)送的客戶端進(jìn)行響應(yīng)。

          Ingester

          ingester 服務(wù)負(fù)責(zé)將日志數(shù)據(jù)寫入長期存儲(chǔ)后端(DynamoDB、S3、Cassandra 等)。此外 ingester 會(huì)驗(yàn)證攝取的日志行是按照時(shí)間戳遞增的順序接收的(即每條日志的時(shí)間戳都比前面的日志晚一些),當(dāng) ingester 收到不符合這個(gè)順序的日志時(shí),該日志行會(huì)被拒絕并返回一個(gè)錯(cuò)誤。

          • 如果傳入的行與之前收到的行完全匹配(與之前的時(shí)間戳和日志文本都匹配),傳入的行將被視為完全重復(fù)并被忽略。
          • 如果傳入的行與前一行的時(shí)間戳相同,但內(nèi)容不同,則接受該日志行。這意味著同一時(shí)間戳有兩個(gè)不同的日志行是可能的。

          來自每個(gè)唯一標(biāo)簽集的日志在內(nèi)存中被建立成 chunks(塊),然后可以根據(jù)配置的時(shí)間間隔刷新到支持的后端存儲(chǔ)。在下列情況下,塊被壓縮并標(biāo)記為只讀:

          • 當(dāng)前塊容量已滿(該值可配置)
          • 過了太長時(shí)間沒有更新當(dāng)前塊的內(nèi)容
          • 刷新了

          每當(dāng)一個(gè)數(shù)據(jù)塊被壓縮并標(biāo)記為只讀時(shí),一個(gè)可寫的數(shù)據(jù)塊就會(huì)取代它。如果一個(gè) ingester 進(jìn)程崩潰或突然退出,所有尚未刷新的數(shù)據(jù)都會(huì)丟失。Loki 通常配置為多個(gè)副本(通常是 3 個(gè))來降低這種風(fēng)險(xiǎn)。

          當(dāng)向持久存儲(chǔ)刷新時(shí),該塊將根據(jù)其租戶、標(biāo)簽和內(nèi)容進(jìn)行哈希處理,這意味著具有相同數(shù)據(jù)副本的多個(gè) ingesters 實(shí)例不會(huì)將相同的數(shù)據(jù)兩次寫入備份存儲(chǔ)中,但如果對(duì)其中一個(gè)副本的寫入失敗,則會(huì)在備份存儲(chǔ)中創(chuàng)建多個(gè)不同的塊對(duì)象。有關(guān)如何對(duì)數(shù)據(jù)進(jìn)行重復(fù)數(shù)據(jù)刪除,請(qǐng)參閱 Querier。

          WAL

          上面我們也提到了 ingesters 將數(shù)據(jù)臨時(shí)存儲(chǔ)在內(nèi)存中,如果發(fā)生了崩潰,可能會(huì)導(dǎo)致數(shù)據(jù)丟失,而 WAL 就可以幫助我們來提高這方面的可靠性。

          在計(jì)算機(jī)領(lǐng)域,WAL(Write-ahead logging,預(yù)寫式日志)是數(shù)據(jù)庫系統(tǒng)提供原子性和持久化的一系列技術(shù)。

          在使用 WAL 的系統(tǒng)中,所有的修改都先被寫入到日志中,然后再被應(yīng)用到系統(tǒng)狀態(tài)中。通常包含 redo 和 undo 兩部分信息。為什么需要使用 WAL,然后包含 redo 和 undo 信息呢?舉個(gè)例子,如果一個(gè)系統(tǒng)直接將變更應(yīng)用到系統(tǒng)狀態(tài)中,那么在機(jī)器斷電重啟之后系統(tǒng)需要知道操作是成功了,還是只有部分成功或者是失敗了(為了恢復(fù)狀態(tài))。如果使用了 WAL,那么在重啟之后系統(tǒng)可以通過比較日志和系統(tǒng)狀態(tài)來決定是繼續(xù)完成操作還是撤銷操作。

          redo log 稱為重做日志,每當(dāng)有操作時(shí),在數(shù)據(jù)變更之前將操作寫入 redo log,這樣當(dāng)發(fā)生斷電之類的情況時(shí)系統(tǒng)可以在重啟后繼續(xù)操作。undo log 稱為撤銷日志,當(dāng)一些變更執(zhí)行到一半無法完成時(shí),可以根據(jù)撤銷日志恢復(fù)到變更之間的狀態(tài)。

          Loki 中的 WAL 記錄了傳入的數(shù)據(jù),并將其存儲(chǔ)在本地文件系統(tǒng)中,以保證在進(jìn)程崩潰的情況下持久保存已確認(rèn)的數(shù)據(jù)。重新啟動(dòng)后,Loki 將重放日志中的所有數(shù)據(jù),然后將自身注冊(cè),準(zhǔn)備進(jìn)行后續(xù)寫操作。這使得 Loki 能夠保持在內(nèi)存中緩沖數(shù)據(jù)的性能和成本優(yōu)勢(shì),以及持久性優(yōu)勢(shì)(一旦寫被確認(rèn),它就不會(huì)丟失數(shù)據(jù))。

          查詢前端

          查詢前端是一個(gè)可選的服務(wù),提供 querier 的 API 端點(diǎn),可以用來加速讀取路徑。當(dāng)查詢前端就位時(shí),應(yīng)將傳入的查詢請(qǐng)求定向到查詢前端,而不是 querier, 為了執(zhí)行實(shí)際的查詢,群集中仍需要 querier 服務(wù)。

          查詢前端在內(nèi)部執(zhí)行一些查詢調(diào)整,并在內(nèi)部隊(duì)列中保存查詢。querier 作為 workers 從隊(duì)列中提取作業(yè),執(zhí)行它們,并將它們返回到查詢前端進(jìn)行匯總。querier 需要配置查詢前端地址(通過-querier.frontend-address CLI 標(biāo)志),以便允許它們連接到查詢前端。

          查詢前端是無狀態(tài)的,然而,由于內(nèi)部隊(duì)列的工作方式,建議運(yùn)行幾個(gè)查詢前臺(tái)的副本,以獲得公平調(diào)度的好處,在大多數(shù)情況下,兩個(gè)副本應(yīng)該足夠了。

          隊(duì)列

          查詢前端的排隊(duì)機(jī)制用于:

          • 確保可能導(dǎo)致 querier 出現(xiàn)內(nèi)存不足(OOM)錯(cuò)誤的查詢?cè)谑r(shí)被重試。這允許管理員可以為查詢提供不足的內(nèi)存,或者并行運(yùn)行更多的小型查詢,這有助于降低總成本。
          • 通過使用先進(jìn)先出隊(duì)列(FIFO)將多個(gè)大型請(qǐng)求分配到所有 querier 上,以防止在單個(gè) querier 中傳送多個(gè)大型請(qǐng)求。
          • 通過在租戶之間公平調(diào)度查詢。

          分割

          查詢前端將較大的查詢分割成多個(gè)較小的查詢,在下游 querier 上并行執(zhí)行這些查詢,并將結(jié)果再次拼接起來。這可以防止大型查詢?cè)趩蝹€(gè)查詢器中造成內(nèi)存不足的問題,并有助于更快地執(zhí)行這些查詢。

          緩存

          查詢前端支持緩存指標(biāo)查詢結(jié)果,并在后續(xù)查詢中重復(fù)使用。如果緩存的結(jié)果不完整,查詢前端會(huì)計(jì)算所需的子查詢,并在下游 querier 上并行執(zhí)行這些子查詢。查詢前端可以選擇將查詢與其 step 參數(shù)對(duì)齊,以提高查詢結(jié)果的可緩存性。結(jié)果緩存與任何 loki 緩存后端(當(dāng)前為 memcached、redis 和內(nèi)存緩存)兼容。

          Querier

          Querier 查詢器服務(wù)使用 LogQL 查詢語言處理查詢,從 ingesters 和長期存儲(chǔ)中獲取日志。

          查詢器查詢所有 ingesters 的內(nèi)存數(shù)據(jù),然后再到后端存儲(chǔ)運(yùn)行相同的查詢。由于復(fù)制因子,查詢器有可能會(huì)收到重復(fù)的數(shù)據(jù)。為了解決這個(gè)問題,查詢器在內(nèi)部對(duì)具有相同納秒時(shí)間戳、標(biāo)簽集和日志信息的數(shù)據(jù)進(jìn)行重復(fù)數(shù)據(jù)刪除。

          Chunk 格式

           -------------------------------------------------------------------
          | | |
          | MagicNumber(4b) | version(1b) |
          | | |
          -------------------------------------------------------------------
          | block-1 bytes | checksum (4b) |
          -------------------------------------------------------------------
          | block-2 bytes | checksum (4b) |
          -------------------------------------------------------------------
          | block-n bytes | checksum (4b) |
          -------------------------------------------------------------------
          | #blocks (uvarint) |
          -------------------------------------------------------------------
          | #entries(uvarint) | mint, maxt (varint) | offset, len (uvarint) |
          -------------------------------------------------------------------
          | #entries(uvarint) | mint, maxt (varint) | offset, len (uvarint) |
          -------------------------------------------------------------------
          | #entries(uvarint) | mint, maxt (varint) | offset, len (uvarint) |
          -------------------------------------------------------------------
          | #entries(uvarint) | mint, maxt (varint) | offset, len (uvarint) |
          -------------------------------------------------------------------
          | checksum(from #blocks) |
          -------------------------------------------------------------------
          | #blocks section byte offset |
          -------------------------------------------------------------------

          mintmaxt分別描述了最小和最大的 Unix 納秒時(shí)間戳。

          Block 格式

          一個(gè) block 由一系列日志 entries 組成,每個(gè) entry 都是一個(gè)單獨(dú)的日志行。

          請(qǐng)注意,一個(gè) block 的字節(jié)是用 Gzip 壓縮存儲(chǔ)的。以下是它們未壓縮時(shí)的形式。

            -------------------------------------------------------------------
          | ts (varint) | len (uvarint) | log-1 bytes |
          -------------------------------------------------------------------
          | ts (varint) | len (uvarint) | log-2 bytes |
          -------------------------------------------------------------------
          | ts (varint) | len (uvarint) | log-3 bytes |
          -------------------------------------------------------------------
          | ts (varint) | len (uvarint) | log-n bytes |
          -------------------------------------------------------------------

          ts 是日志的 Unix 納秒時(shí)間戳,而 len 是日志條目的字節(jié)長度。

          Chunk 存儲(chǔ)

          Chunk 存儲(chǔ)是 Loki 的長期數(shù)據(jù)存儲(chǔ),旨在支持交互式查詢和持續(xù)寫入,不需要后臺(tái)維護(hù)任務(wù)。它由以下部分組成:

          • 一個(gè) chunks 索引,這個(gè)索引可以通過以下方式支持:Amazon DynamoDB、Google Bigtable、Apache Cassandra。
          • 一個(gè)用于 chunk 數(shù)據(jù)本身的鍵值(KV)存儲(chǔ),可以是:Amazon DynamoDB、Google Bigtable、Apache Cassandra、Amazon S3、Google Cloud Storage。

          與 Loki 的其他核心組件不同,塊存儲(chǔ)不是一個(gè)單獨(dú)的服務(wù)、任務(wù)或進(jìn)程,而是嵌入到需要訪問 Loki 數(shù)據(jù)的 ingesterquerier 服務(wù)中的一個(gè)庫。

          塊存儲(chǔ)依賴于一個(gè)統(tǒng)一的接口,用于支持塊存儲(chǔ)索引的 NoSQL 存儲(chǔ)(DynamoDB、Bigtable 和 Cassandra)。這個(gè)接口假定索引是由以下項(xiàng)構(gòu)成的鍵的條目集合。

          • 一個(gè)哈希 key,對(duì)所有的讀和寫都是必需的。
          • 一個(gè)范圍 key,寫入時(shí)需要,讀取時(shí)可以省略,可以通過前綴或范圍進(jìn)行查詢。

          該接口在支持的數(shù)據(jù)庫中的工作方式有些不同:

          • DynamoDB 原生支持范圍和哈希鍵,因此,索引條目被直接建模為 DynamoDB 條目,哈希鍵作為分布鍵,范圍作為 DynamoDB 范圍鍵。
          • 對(duì)于 BigtableCassandra,索引條目被建模為單個(gè)列值。哈希鍵成為行鍵,范圍鍵成為列鍵。

          一組模式集合被用來將讀取和寫入塊存儲(chǔ)時(shí)使用的匹配器和標(biāo)簽集映射到索引上的操作。隨著 Loki 的發(fā)展,Schemas 模式也被添加進(jìn)來,主要是為了更好地平衡寫操作和提高查詢性能。

          讀取路徑

          日志讀取路徑的流程如下所示:

          • 查詢器收到一個(gè)對(duì)數(shù)據(jù)的 HTTP 請(qǐng)求。
          • 查詢器將查詢傳遞給所有 ingesters 以獲取內(nèi)存數(shù)據(jù)。
          • ingesters 收到讀取請(qǐng)求,并返回與查詢相匹配的數(shù)據(jù)(如果有的話)。
          • 如果沒有 ingesters 返回?cái)?shù)據(jù),查詢器會(huì)從后端存儲(chǔ)加載數(shù)據(jù),并對(duì)其運(yùn)行查詢。
          • 查詢器對(duì)所有收到的數(shù)據(jù)進(jìn)行迭代和重復(fù)計(jì)算,通過 HTTP 連接返回最后一組數(shù)據(jù)。

          寫入路徑

          write path

          整體的日志寫入路徑如下所示:

          • distributor 收到一個(gè) HTTP 請(qǐng)求,以存儲(chǔ)流的數(shù)據(jù)。
          • 每個(gè)流都使用哈希環(huán)進(jìn)行哈希操作。
          • distributor 將每個(gè)流發(fā)送到合適的 ingester 和他們的副本(基于配置的復(fù)制因子)。
          • 每個(gè) ingester 將為日志流數(shù)據(jù)創(chuàng)建一個(gè)塊或附加到一個(gè)現(xiàn)有的塊上。每個(gè)租戶和每個(gè)標(biāo)簽集的塊是唯一的。
          • distributor 通過 HTTP 連接響應(yīng)一個(gè)成功代碼。



          瀏覽 105
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  要操网| 91在线视频免费观看 | 91三级在线观看 | 欧美一区二区成人电影 | 日本艹逼网站 |