自從用 Filebeat 後發現在系統中常常被 logrotate 掉的檔案還存在系統中,即使已經刪除了,但還是會被 Filebeat 抓住不放掉,導致硬碟常常爆滿。
要檢查是否有被 Filebeat 抓住被刪除的檔案,可以用 lsof 去查看
$ lsof | grep filebeat
如果看到類似以下訊息,尤其是最後有出現 (deleted) 的話,恭喜你刪除的檔案依然被 Filebeat 抓著不放,所以硬碟空間並沒有被釋放掉。
filebeat 8442 filebeat 29u REG 253,17 3926560 0 1499 /var/log/apache2/access.log (deleted)
這個問題其實在 elastic 有蠻多人提出來的:
- Filebeat holds on to a file descriptor too long even after a file was deleted?
- [SOLVED] Filebeat keeps open files forever
然後你的硬碟就會呈現飛高高的狀態,一直下不來。
如果重啟 Filebeat 服務,就會發現硬碟空間瞬間被釋放掉 XDD …
Harvester Close
其實原因就是 Filebeat harvester 並不知道什麼時候該放掉你的檔案,在官方文件中有談到 close_* 參數是有關於 Filebeat 如何放掉檔案的參數
- close_inactive 如果檔案在多久的時間沒有新資料就會關閉 harvester (依最後一筆資料進入的時間點為基準),如果超過 close_inactive 時間後再有資料進入,則會重新開啟一個 harvester 進行收集,所以 close_inactive 通常不建議設定太短。
- close_renamed 如果檔案被 rename 後,則關閉 harvester,這個設定通常會發生在 logrotate 機制。
- close_removed 如果檔案被 remove 後,則關閉 harvester,預設啟用,但是如果 logrotate 機制是先 rename 再 delete 的話,close_removed 就無法作用。
- close_eof 當檔案被寫入結束時,則關閉 harvester,通常適用在一次寫入的情況下,如果你的 Log 檔是持續有資料寫入,則不建議開啟這個功能。
- close_timeout 可以在當你後端的 logstash 或 elasticsearch 忙碌時,適時的關閉 harvester 而不是卡在那邊。
可以從每一個參數的特性去調整不同的 Log 性質,減少 harvester 佔用的系統資源,在我的環境多是以 Web 為主的服務,我的設定提供參考:
close_inactive: 5m
close_renamed: true
close_removed: true
close_eof: false
close_timeout: 3600
Harvester Clean
Harvester 的採集依據主要是以 registry 作為記錄每個檔案採集到的位置,registry 會記錄每個檔案的狀態,如果 Clean 設定不當,則有可能造成:
- registry 過大 (通常是監控的 Log 數量太多)
- 承上,因為檔案多,所以 inode 也有可能因此佔用。
- registry 太早進行 clean 導致新資料寫入時 harvester 不曉得最後的採集點而傳送重複的資料。
除非你要採集的 Log 檔案多到炸掉,否則 registry 的問題比較小,但在這裡也了解一下 clean_* 的參數意義:
- clean_inactive 超過設定的時間則刪除該檔案的 registry 狀態,預設關閉。
- clean_removed 當檔案被 remove 時刪除該檔案的 registry 狀態,預設開啟。但是如果 Log 是以 NFS / iSCSI 或者可能會有暫時無法讀取 Log 的情況,就會導致 registry 被清掉後重送重複資料。
如果沒有特殊狀況,clean 的參數可以保持預設即可。
參考資料: