iT邦幫忙

2021 iThome 鐵人賽

DAY 14
1
DevOps

喬叔帶你上手 Elastic Stack - 探索與實踐 Observability系列 第 14

14 - Logs - 挖掘系統內部發生的狀況 (2/4) - 使用 Filebeat 應該要了解的設計細節與原理

Logs - 挖掘系統內部發生的狀況 系列文章


本篇學習重點

  • Filebeat 的設計架構與底層運作原理
  • Filebeat Config 配置的一些建議與需注意的設定

Filebeat 的運作架構與原理

由於實務上的使用情境有許多種變化,透過了解 Filebeat 運作運作架構與原理,能幫助我們在自己所需要的情境之下,能進行比較好的配置及使用,避免效能的浪費或甚至是因為誤用而造成非預期的結果。

Filebeat 的運作原理

這是在上一篇文章我們有介紹到的 Filebeat 運作架構,接下來我們先深入的了解裡面的組成元素與運作細節。[1]

13-Filebeat-Architecture

Harvesters (收集器)

Harvester 的職責與運作特性如下:

  • 每個檔案都會有專門負責的 Harvester 進行處理,並且將新增加的資料讀出,並且交給 libbeat 進行後續處理,最終透過 Outputs 的定義將資料往外傳送。
  • 讀取檔案時,以 行 (Line) 為單位。
  • Harvester 會負責實體檔案的 openclose,也就是說只要 Harvester 還在運作時,所負責讀取的檔案的 File descriptor (檔案描述器) 會一直保持 open 的狀態,因此如果 Harvester 在保持運作時,若某個檔案被移動或改名後,這個檔案後續增加的內容,依然會被 Harvester 讀取出來,也因此如果檔案被刪除的話,磁碟空間還是會一直被佔用著,直到 Harvester close 檔案之後,才會被釋放。
  • 要讓 Harvester close 檔案的話,會依照 close_inactive 所設定的值,等到檔案持續指定的時間長度沒有寫入新資料之後,才會被關閉,而觸發檢查這個設定值會是依照 scan_frequency 所指定的時間週期。
  • close 的檔案,若是又有新的資料寫入,會等到 scan_frequency 下次執行的時間週期檢查到檔案時,才會繼續 open 並且讀取檔案。

Inputs (輸入端)

而 Inputs 的職責與運作特性如下:

  • Inputs 負責管理需要被讀取的檔案或資料來源。
  • Inputs 將要讀取的檔案及資料交給 Harvester 進行處理,也就是說 Harvesters 其實就是由 Inputs 在管理的。
  • 當有設定多組 Inputs 時,每個 Input 擁有自己的執行緒 (Thread),會併發進行處理。
  • log Input 為例,若是有指定多個 paths ,每個 paths 指定的檔案都會由 Input 負責找出來,並且每一個檔會交給一個 Harvester 去處理。
  • 同一種類型的 Input 可以重覆被定義很多次,但要留意同一個檔案不應該被重覆指定,這樣可能會發生非預期的行為。
  • Input 目前 Filebeat 有支援 20 幾種服務的實作,有興趣的可以參考 官方文件 - Filebeat Inputs [2]。

早期叫 prospector ,6.3 版之後將 prospector 改成 input

Spooler (緩衝處理器)

Spooler 其實指的是 Queue,也就是 libbeat 裡面所實作的機制,由 harvesters 所讀取出的資料,會以 events 的方式,透過 events channel 傳送給 libbeat ,並且在 libbeat 當中透過各種 Pipeline 的方式進行後續的處理,像是如果有定義 processors 就會在 pipelineProcessors 面進行指定的處理,而 libbeat 裡的 Publisher ,就負責將 event 最後透過 Output 的定義所往後傳送的機制,這邊是以 At Least Once 的方式來實作,也就是會確保資料有被正確的傳送出去,如果沒有收到正確傳送出去的回覆,就會不斷的重試,最終會透過 Registrar 將結果寫入到 Registry 檔案之中。

有興趣了解 Filebeat 與 libbeat 底層實作的,可以參考 Filebeat 原始碼淺析 [3]。

Outputs (輸出)

Output 這邊是針對 Filebeat 所支援的對外接口種類有各別的實作,目前 Filebeat 的 Output 有提供 6 種 (Elasticsearch, Logstash, Kafka, Redis, File, Console),如果有定義要批次處理,例如 Elasticsearch Output 會使用 bulk API,這個處理就會實作在 Output 當中,另外如果 Filebeat 在關閉時,還沒有成功取得 Output 所發送出去的回應時,Filebeat 不會等待,會直接關閉,一但 Filebeat 重新啟動時,這個 events 就會被重新傳送。

Filebeat 如何記錄及處理要傳送的檔案

Filebeat 會將每個處理過的檔案,記錄在他的 Registry 檔裡面,預設是存放在 ${path.data}/registry/ 的目錄裡。

裡面會有個 json 格式的檔案,記錄每一個曾被讀取過的檔案,而如果是保持在 open 的檔案,會另外獨立存在一個 active 的檔案之中,同時會記錄 inode 等實體 disk 的資訊,Filebeat 會持續在記憶體更新每個檔案被讀取過的位置,並且等到資料成功透過 Output 傳送出去之後,便會將記憶體中的記錄寫到 Disk 中,而如果 Filebeat 程式異常中止的話,也會在重新啟動的時候,從 Registry 裡將記錄讀出,就能夠知道要繼續從檔案的哪個位置往後讀取。

由於 log 檔名可能會被修改,檔案也可能會搬位置,因此 Filebeat 會以 Disk inode 資訊產生另外的 Unique ID 並記錄在 Registry 之中,用以評估檔案是否在先前有被處理過,以防止檔案改名或搬位置之後,被重覆的讀取。

Filebeat 如何確保需傳送的資料不會漏掉

Filebeat 能確保資料 At Least Once 的使命必達,不會漏掉,是因為他會將傳送的狀態記錄在 Registry 檔案裡,所以發生錯誤沒辦法成功的傳送,就會透過前面所介紹的 libbeat 裡的 Registrar 進行重送,同樣的如果 Filebeat 非正常的關閉,也會在重新啟動的時候,透過 Registry 將檔案處理的狀態給恢復。

Filebeat 的 Config 配置方式

這邊會將一些 Config 配置上,實務上會需要留意及較常會使用到的部份與大家進行介紹。

一般設定

這部份是設定在 filebeat.yml 當中:

  • retistry.flush :預設是 0s,也就是只要 output 成功寫出,就會執行 flush 。如果有非常多的 Logs 同時在處理很大量的資料的情境下,太過頻繁的寫入 Registry 檔案會拖慢整個執行的速度,這時就應該將 registry.flush 設定 >0s
  • shutdown_timeout:預設 Filebeat 在關閉程式時,不會等待 publisher 確認 Output 的結果,這樣在大量資料不斷處理的情況下,會常有機會發生關閉 Filebeat 當下的資料,在重新啟動時重覆發送的情況,我們可以設定這個值,讓關閉的時候稍微多等待 Output 的結果,以減少重送的情況發生。
  • tagsfields:這兩個值能夠有效的幫我們分類資料的來源,善用資料來源的標示與分類,可以幫助我們在後續的資料分析。
  • processors:這個功能能讓我們透過 Filebeat 所收集的資料,在往後送之前,進行一些簡單的加工處理,例如我們想要依照一些條件刪掉不需要的 event、使用我們自訂義的 ID 欄位,讓重覆的資料進入 Elasticsearch 時能夠被 deduplicate (去重覆)、把某個 JSON 的字串解析出來並取得當中的值…等。
  • queue.disk:如果你透過 Filebeat 在處理的資料量很大,並且希望能夠在 Spooler 當中先將較大量的資料進行彙總再往後傳送,預設在 memory 當 queue 的配置,可能承受不了太量的資料彙總,這時就可以考慮將 queue 寫在 disk 中。又或著是我們透過 Filebeat 要往後傳送的資料,非常重視資料的可靠性,同時我們又有指定 flush.min_eventsflush.timeout 要使用較大量的 queue,這時也會要考慮將 queue 指定到實體的 disk 之中。[4]

實務上的配置技巧 - 切分設定檔

由於實務佈署上,我們有多台的機器時,相同性質的機器的 filebeat 的配置會是一樣的,這時候我們可以將 config 切分出來,也能夠讓我們在做組態管理時更容易,至於 filebeat 能切分的設定檔主要有以下兩種:

Input Config

filebeat.config.inputs:
  enabled: true
  path: inputs.d/*.yml

存放在 inputs.d 裡面的 yml 檔案格式,會定義如下方的例子:

- type: log
  paths:
    - /var/log/mysql.log
  scan_frequency: 10s

- type: log
  paths:
    - /var/log/apache.log
  scan_frequency: 5s

Module Config

filebeat.config.modules:
  enabled: true
  path: ${path.config}/modules.d/*.yml

這裡面的檔案格式如下:

- module: apache
  access:
    enabled: true
    var.paths: [/var/log/apache2/access.log*]
  error:
    enabled: true
    var.paths: [/var/log/apache2/error.log*]

而建議的 Config 檔案管理方式,一般有二種做法:

  • 如預設的配置,以 module 名稱來切分檔案,不同的 module 有各自的 yml 設定檔。
  • 以服務角色來切分,例如 web server、backend service、DB server…等,並在檔案中定義所有該服務使用到的 modules。

其他 Input, Output, Module 的配置

在其他 Input, Output Module 的配置上,在不同的情境下,也都有不同的配置建議設定,由於所支援的部份太多,這邊無法一一細談,會建議大家在使用之前,一定要先閱讀過官方文件的資訊,至少先把有哪些設定值看過一遍,再依照情境去判斷可能會需要調整的部份。

如果你也是使用 Filebeat 在讀取實體的 Log 檔案,至少 官方文件 Input - Log 這份的設定你應該要看過,要知道 close_*scan_frequencyharvester_limit 等配置是做什麼用的,對於效能的調效也會有所幫助。

參考資料

  1. 官方文件 - How Filebeat Works
  2. 官方文件 - Filebeat Inputs
  3. Filebeat 原始碼淺析
  4. 官方文件 - Filebeat Internal Queue

上一篇
13 - Logs - 挖掘系統內部發生的狀況 (1/4) - Logs 與 Filebeat 的基本介紹
下一篇
15 - Logs - 挖掘系統內部發生的狀況 (3/4) - 透過 Filebeat 收集 Elastic Stack 中各種服務的細節資訊
系列文
喬叔帶你上手 Elastic Stack - 探索與實踐 Observability31

尚未有邦友留言

立即登入留言