精品軟體與實用教程
Ubuntu系统Inodes耗尽,当你遇到硬盘空间不足无法写入的问题
在 Linux 伺服器中,即使硬碟空間看起來還有剩餘,但仍可能遇到無法寫入文件的情況。這通常是由於 inodes 已用完導致的。
當遇到硬碟無法寫入而磁碟空間還有剩餘時,很可能是inodes 用盡導致。可以透過清理小文件、調整檔案系統或歸檔儲存等方法解決問題,同時配合監控和最佳化設計來避免類似問題再次發生。
什麼是inodes?
inodes 是檔案系統中的資料結構,用於儲存檔案的元資訊(例如檔案權限、擁有者、建立時間等)。
每個檔案都會佔用一個inode,無論檔案的大小是多少。如果inodes 耗盡,即使硬碟還有剩餘空間,也無法建立新的檔案。
如何檢查硬碟和inodes 使用情況?
檢查磁碟空間
df -h
這會顯示硬碟的使用情況(以人類可讀的格式)。
檢查inodes 使用情況
df -i
輸出範例:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 1000000 999999 1 100% /
IUse% 表示inodes 的使用率,如果IUse% 達到100%,表示inodes 已耗盡。
- 小檔案過多,大量小檔案會消耗大量inodes,特別是日誌檔案、暫存檔案等。
- 檔案系統類型,某些檔案系統(如ext4)在建立時會固定分配inodes 數量,無法動態調整。
- 應用問題,應用程式可能會不斷產生小文件,導致inodes 被迅速耗盡。
inodes 佔用100%的解決方法
首先刪除系統的日誌文件
sudo rm -rf /var/log/*.log
刪除系統日誌檔案後,發現inodes 的使用率依舊是100%或只減少了一點點,這時,需要找出在系統中哪些目錄檔案佔用過大。
一般在Linux中,/home存放的是網站程式文件,系統程式文件一般在/var目錄中。
下面排查哪些目錄佔用過大,查看一下根目錄下資料夾大小,依大小排序。
du -h --max-depth=1 / | sort -hr
依目錄大小進一步排查在var目錄中哪些目錄佔用檔案大,依照這個方法,排查其它目錄。
du -h --max-depth=1 /var | sort -hr
在檢查過程中,發現/usr/local/lsws/logs 佔用了9.4G,進入目錄中看到一個auditmodsec.log 檔案就佔了差不多8G
auditmodsec.log 是ModSecurity 的稽核日誌文件,記錄了觸發安全規則的HTTP 請求及其回應資料。
繼續排查發現/var/lib/lsphp/session/lsphp83 目錄佔用空間過大,而且檔案數量太多。
/var/lib/lsphp/session/lsphp83 目錄是與LiteSpeed PHP (lsphp) 會話相關的儲存目錄。這個目錄通常與LSAPI (LiteSpeed SAPI) 相關,它是LiteSpeed Web Server 用來處理PHP 腳本的API。
/var/lib/lsphp/session是LiteSpeed PHP 會話檔案存放的目錄。 PHP 會話檔案在這裡儲存並按會話ID 命名。
如果會話目錄中的檔案過多或過大,可能會導致儲存空間不足問題。定期清理無效的會話文件。
上面提到的inodes佔用100%。大多就是這個目錄的問題,由於/var/lib/lsphp/session資料夾內的文件數量巨大,導致inodes佔用100%,硬碟無法寫入文件,除了硬碟滿了之外還有一個就是inodes佔用100%
這兩種問題都會導致硬碟無法寫入內容,當硬碟無法寫入檔案後,web或資料庫在運作過程中都需要寫入暫存檔案。無法寫入臨時檔案會導致網站癱瘓,資料庫癱瘓等等問題。
清理和管理會話文件
可以使用cron 定期清理過期的會話文件,防止目錄佔用過多空間。通常,過期會話檔案會根據系統設定自動清理,或者可以透過設定session.gc_maxlifetime 來控制。
首先在php的設定檔中啟用回收管理。
在PHP 中,Session 垃圾回收(Garbage Collection, GC) 是用來清理過期會話資料的機制。根據你的環境需求(例如開發環境、高流量生產伺服器等),可以對session.gc_probability、session.gc_divisor 和session.gc_maxlifetime 做出最佳化設定。
以下是啟用回收的最佳設定建議,具體視你的實際場景而定。
關鍵參數最佳化解釋
session.gc_probability
作用: 控制每次會話初始化時觸發垃圾回收的機率。
推薦設定:
開發環境: 1,便於頻繁清理會話資料以減少調試幹擾。
生產環境: 1,確保垃圾回收機制開啟。
session.gc_divisor
作用: 與session.gc_probability 一起決定垃圾回收的觸發機率。垃圾回收的機率公式為:
複製程式碼
垃圾回收機率= gc_probability / gc_divisor
推薦設定:
開發環境: 100(即1/100 的機率觸發垃圾回收)。
高流量生產環境: 1000(即1/1000 的機率觸發垃圾回收,降低效能開銷)。
session.gc_maxlifetime
作用: 設定會話檔案的最大存活時間(秒)。超過此時間未使用的會話將被視為“垃圾”。
推薦設定:
開發環境: 依需求調整,通常設定較短時間(如1440 秒= 24 分鐘)。
生產環境: 較長時間,根據應用程式需求和使用者習慣設定。
例如:
普通電商平台:3600(1 小時)
企業後台系統:7200(2 小時)或更高,如14400(4 小時)。
; 啟用垃圾回收機制,生產環境推薦設定session.gc_probability = 1 session.gc_divisor = 1000 session.gc_maxlifetime = 14400 ; 設定為4 小時,依業務需求可調整
或使用cron 作業或其他工具定期清理會話數據,而非依賴PHP 的垃圾回收機制
编辑 crontab
sudo crontab -e
0 */6 * * * find /var/lib/lsphp/session/lsphp83 -type f -mmin +240 -delete # 每 6 小时清理 4 小时前文件
解释:0 */6 * * * 表示每 6 小时执行一次;find 命令扫描目录,-type f 只限文件,-mmin +240 过滤 240 分钟(4 小时)前修改的文件,-delete 直接删除。调整 +240 为您的 session 有效期(PHP session.gc_maxlifetime 默认 1440 秒 = 24 分钟)。
保存后验证:
sudo crontab -l
上述指令清理最後修改時間超過240 分鐘的會話檔案。
PHP 垃圾回收机制:内置与外部结合
PHP 的 session 垃圾回收(GC)是文件级机制,默认 gc_probability=1(1% 几率触发),gc_divisor=100,gc_maxlifetime=1440 秒。但在高并发下,触发率低,文件堆积严重。
配置调整:编辑 php.ini(CyberPanel 面板 > PHP > Edit Configs):
session.gc_probability = 1 session.gc_divisor = 1000 session.gc_maxlifetime = 14400 session.save_handler = files
重启 PHP-FPM:sudo systemctl restart lsphp83(替换版本)。这提升 GC 效率,但仍依赖随机性。
外部结合:Cron 作为补充,确保 100% 覆盖。自定义 handler 如 Redis(session.save_handler = redis)可完全取代文件存储,减少 I/O:安装 pecl install redis,php.ini session.save_handler = redis; session.save_path = "tcp://127.0.0.1:6379"。
监控:用 find /var/lib/lsphp/session/lsphp83 -type f | wc -l 统计文件数,cron 脚本中添加警报:if [ $(find ... | wc -l) -gt 10000 ]; then mail -s "Session Overflow" [email protected]; fi。
通过 cron 作业的定时清理和 PHP GC 机制的精细调优,您能构建一个高效、自动化的会话管理系统,避免文件堆积带来的性能隐患。在 CyberPanel 等环境中,这种双管齐下策略不仅简单可靠,还能将系统负载降 30%+,确保高并发下稳定运行。定期监控日志和文件数,结合负载测试(如 ab 工具),您的应用将更具弹性。优化会话管理,从现在开始——您的服务器值得更好的表现。
好了,到這裡Ubuntu系統遇到硬碟空間不足無法寫入的問題已經解決完了!
附:性能最优设置建议
针对高流量服务器,目标:平衡 GC 频率、减少 I/O、提升回收率 90%+。编辑 php.ini(CyberPanel 面板 > PHP > Edit Configs),重启 PHP-FPM。
基础调优(文件存储模式):
session.gc_probability = 10 # 提升到 1% 触发率 session.gc_divisor = 100 # 实际率 = 10/100 = 10%,每 10 会话触发一次 session.gc_maxlifetime = 3600 # 1 小时过期,减少文件存活 session.save_handler = files
高级优化:切换外部存储(推荐高并发): 用 Redis 取代文件,零 I/O 开销:
session.gc_probability = 0 # 禁用文件 GC session.gc_divisor = 1000 session.gc_maxlifetime = 3600 session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379?auth=yourpassword" # Redis 配置
先安装 Redis:sudo apt install redis-server php-redis,配置 /etc/redis/redis.conf(bind 127.0.0.1)。
效果:会话存内存/Redis,回收率 100%,性能提升 5 倍。