1. 程式人生 > >Linux 下刪除了檔案,空間為何不釋放?

Linux 下刪除了檔案,空間為何不釋放?

Linux

本文由高效運維社群核心成員投稿釋出

作者簡介

劉晨   網名 bisal,Oracle 技術愛好者,擁有 Oracle 10g/11g OCP、Oracle 11g OCM認證,Oracle YEP 成員,目前就職於一家央企,負責系統應用運維工作。

你是否碰見過 Linux 環境下,檔案已經刪除,但是空間未被釋放的情況?這篇小文就會介紹一下,這種問題的一個場景,以及相應的解決方案。

我們的一臺應用伺服器,作業系統是 Red Hat Linux,監控報警,/opt/applog檔案系統使用率超閾值,整體容量為50G,但發現實際檔案容量20G,剩下的30G空間是什麼?

我們知道,Linux 環境下,任何事物,都是以檔案的形式存在,系統在後臺,為每個應用程式,分配了一個檔案描述符,他為應用程式和作業系統之間的互動操作提供了通用的介面,既然是檔案,就會佔用空間,此時可以使用 lsof 指令,他可以列出,當前系統正在開啟的檔案。

>lsof
COMMAND      PID      USER   FD      TYPE    DEVICE  SIZE/OFF      NODE NAME
...
filebeat  111442   app  1r      REG     253,3 209715229   1040407 /opt/applog/E.20171016.info.012.log
filebeat  111442   app  2r      REG     253,3 209715254    385080 /opt/applog/E.20171015.info.001.log (deleted)
...

表頭各欄位,含義如下:

COMMAND:程序的名稱
PID:程序識別符號
USER:程序所有者
FD:檔案描述符,應用程式通過檔案描述符識別該檔案。如cwd、txt等
TYPE:檔案型別,如DIR、REG等
DEVICE:指定磁碟的名稱
SIZE:檔案的大小
NODE:索引節點(檔案在磁碟上的標識)
NAME:開啟檔案的確切名稱

可以看出,有一些行中,NAME標識了(deleted)

/opt/applog/E.20171015.info.001.log (deleted)

他的含義,就是這檔案已被刪除,但開啟檔案的控制代碼,並未關閉,再看 COMMAND 的名稱是 filebeat,USER 程序所有者是 app,這是我們的日誌採集程序,app 使用者開啟了 filebeat 程序。

插播一下日誌採集平臺

傳統的開源日誌平臺,即 ELK,由 ElasticSearch、Logstash 和 Kiabana 三個開源工具組成,其中:

  • Elasticsearch 是個開源分散式搜尋引擎,分散式,零配置,自動發現,索引自動分片,索引副本機制,restful 風格介面,多資料來源,自動搜尋負載等。
  • Logstash 是一個開源的採集工具,他可以對日誌進行收集、過濾,並將其儲存供以後使用。
  • Kibana 是一個開源的圖形 Web 工具,可以為 Logstash 和 ElasticSearch 提供日誌分析友好的 Web 介面,可以彙總、分析和搜尋重要資料日誌。

常見的部署圖,如下所示

資料

對於上面提到的 filebeat 又是什麼?和 ELK 有什麼聯絡?

知乎上有一段大牛饒琛琳的介紹(《ELKstack 權威指南》作者),非常精闢,引自 https://www.zhihu.com/question/54058964/answer/137882919

因為 logstash 是 jvm 跑的,資源消耗比較大,所以後來作者又用 golang 寫了一個功能較少但是資源消耗也小的輕量級的 logstash-forwarder。不過作者只是一個人,加入http://elastic.co公司以後,因為 es 公司本身還收購了另一個開源專案 packetbeat,而這個專案專門就是用 golang 的,有整個團隊,所以 es 公司乾脆把 logstash-forwarder 的開發工作也合併到同一個 golang 團隊來搞,於是新的專案就叫 filebeat 了。

簡單來講,filebeat 就是日誌採集的程序 agent,負責採集應用日誌檔案。

對於我上面的這個問題,之所以有大量的(deleted),未釋放檔案控制代碼,還有個背景,就是由於磁碟空間非常有限,臨時加了任務,每小時刪除12小時前的日誌,換句話說,定時任務會自動刪除此時 filebeat 正在開啟著的一些檔案,於是這些檔案,就變為了未釋放的檔案,因此實際檔案刪除了,但空間未被釋放。

解決方案1:

為了迅速釋放空間佔用,最直接的方法,就是 kill -9 filebeat 程序,此時空間會釋放。但並不是從根本解決,定時任務還會刪除這些,filebeat 開啟的檔案,導致空間滿。

解決方案2:
filebeat 的配置檔案 filebeat.yml,其實有兩個引數:

  • close_older: 1h
    說明:Close older closes the file handler for which were not modified for longer then close_older. Time strings like 2h (2 hours), 5m (5 minutes) can be used.

即如果一個檔案在某個時間段內沒有發生過更新,則關閉監控的檔案handle,預設1小時。

  • force_close_files: false
    說明:This option closes a file, as soon as the file name changes. This config option is recommended on windows only. Filebeat keeps the files it’s reading open. This can cause issues when the file is removed, as the file will not be fully removed until also Filebeat closes the reading. Filebeat closes the file handler after ignore_older. During this time no new file with the same name can be created. Turning this feature on the other hand can lead to loss of data on rotate files. It can happen that after file rotation the beginning of the new file is skipped, as the reading starts at the end. We recommend to leave this option on false but lower the ignore_older value to release files faster.

即當檔名稱有變化時,包括改名和刪除,會自動關閉一個檔案。

這兩個引數結合起來,根據應用需求,一個檔案30分鐘內不更新,則需要關閉控制代碼,檔案改名或刪除,需要關閉控制代碼

close_older: 30m
force_close_files: true

可以滿足,filebeat 採集日誌,以及定時刪除歷史檔案,這兩個任務的基本要求。