PHP session 暫存檔過多的注意事項

註: 若您已經將 session 存入 MySQL 或 存入 memcache, 此文對您就沒有幫助囉~ 🙂

PHP 預設 session 是會存成 file, 預設檔名是 sess_一串亂碼, FreeBSD 是存在 /tmp/var/tmp, Debian 會放在 /var/lib/php5. (以下都以 Debian 為例)

PHP session 設定參數(php.ini)

session 暫存檔過多可能產生的系統狀況

PHP session 暫存檔過多, 可能會造成下述的狀況:

  • 作業系統變的很慢
  • ls /var/lib/php5 (或 ls /tmp) 很慢 (檔案過多)
  • Apache 回應很慢
  • 前端頁面看到一片空白 (作業系統硬的碟滿了也會這樣)

session 暫存檔檢驗

照理說, 除非網站的量太大, 不然一般的量, sess_* 的檔案應該會自動回收清除(Debian 可見 /etc/cron.d/php5 檔, 此檔會去抓過期時間設定, 定時清除)

若沒有特別修改 php.ini, 通常 session 過期時間是 1440 秒(24分鐘), 所以要知道有沒有自動清除, 只要如下:

  1. ls -lt /var/lib/php5
  2. 看最後一個檔案的日期, 離現在時間有沒有超過 24 分鐘. (不過 PHP cron 清除時間是半小時跑一次, 所以可能要多觀察幾分鐘(Debian 是每小時的 09, 39 分跑.))
  3. 有超過就代表沒有執行自動清除動作, 沒超過 24 分鐘, 但檔案還是太多, 下面再說解法.

sess_* 檔案時間存活超過設定時間

這代表沒有執行自動清除的動作, 或者是過期時間有另外設定(暫時不考慮程式另外設定過期時間), 這時後可以去 php.ini 找

; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
session.gc_maxlifetime = 1440

; NOTE: If you are using the subdirectory option for storing session files
;       (see session.save_path above), then garbage collection does *not*
;       happen automatically.  You will need to do your own garbage
;       collection through a shell script, cron entry, or some other method.
;       For example, the following script would is the equivalent of
;       setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
;          cd /path/to/sessions; find -cmin +24 | xargs rm

這邊有個注意事項, 他有寫說, 如果你有去修改預設的 session.save_path 的話, 系統將不會自動幫你清除過期的暫存檔, 需要自己手動管理回收暫存當的動作.

若有修改 session.save_path 的話, 需要手動管理, 可以試試下面兩種方法:

  • 官方說明檔建議: cd /path/to/sessions; find -cmin +24 | xargs rm # 把這行寫入 cron, 定期清除
  • 另外一種, 可以試著去修改 /etc/cron.d/php5 (不過這個我沒改過, 理論上應該修改就能動才對. XD)

sess_* 檔案時間有定時清除, 但檔案還是過多

這代表你的網站量應該還不小, 或者就是 session.gc_maxlifetime 時間設太長, 最好的解法當然是把 session 寫到 MySQL 或 memcache, 或寫 Cookie 也是好解法(記得加密)~

在此先不考慮 MySQL 和 memcache, 用最快的方法解決有下面幾種解法:

  1. 若是每個 User 進來都會自動產生 session file 的話, 可以考慮將這行加入 cron (時間看要 3 ~ 5分鐘跑一次)


    find /var/lib/php5 -cmin +5 -name "sess_*" -and -size 0 -delete > /dev/null 2>&1 # 清除 超過 5分鐘, 且容量為 0 的檔案

  2. 另一個是修改 php.ini, 預設 session.save_path = /var/lib/php5

    當檔案太多時, 可以考慮切目錄來放那些 session file, 只要修改設定檔, 它就會自動建立目錄, 將檔案放進去囉~

    官方說明: (PHP: Runtime Configuration - Manual)

    session.save_path = "N;MODE;/path"

    There is an optional N argument to this directive that determines the number of directory levels your session files will be spread around in. For example, setting to '5;/tmp'  may end up creating a session file and location like /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If.

    依官方說明設定, 設定範例如下:

    • 設定 session.save_path = '5;/tmp'
    • session file 就會存成 /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If (切五層的目錄來存放)
    • 這樣子就可以暫時先解決檔案過多造成的系統問題囉~

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

在〈PHP session 暫存檔過多的注意事項〉中有 12 則留言

  1. 不好意思 我想請問的是
    session.save_path = '5;/tmp'
    這樣的寫法 有辦法套用在 session_save_path 這函式嗎?

  2. 請問版主:
    我連上ssh後,直接執行下面這指令(好像用錯方法)
    cd /path/to/sessions; find -cmin +24 | xargs rm
    結果...發生類似format的畫面,一直rmp xxxxxxxxx
    後來,ssh就再也連不進去,網頁好像都被刪了,但apache服務還是啓用
    去機房看主機,要打root進去,但打完root就卡住,沒有出現輸入密碼的畫面...
    不知發生了什麼原因???
    目前因為上面有公司網頁,雖還可以運作,但完全無法進入去做維護...所以也不敢重開機試
    網頁還可以用,是因為用ftp把備份丟了回去...
    不知有沒有什麼方法能進入

  3. .... 你真的是直接下 cd /path/to/sessions; find -cmin +24 | xargs rm ?
    /path/to/ 這些沒有換成真正的路徑? 而且是用 root 執行? XD
    如果你是在根目錄下做的話, 可能資料都砍掉了. Orz..

  4. 版主您好!
    我在Windows 7 電腦下,用xampp套件,安裝PHP5,並設定session_save_path('5;C:/tmp');
    但是怎麼試都不會有作用。
    直到我改成 session_save_path('C:/tmp');
    才可以。
    權限的部分,我記得有改成777全開。不知道是哪邊還有問題?

  5. 要使用 N 参数,必须在使用前先创建好这些目录。在 ext/session 目录下有个小的 shell 脚本名叫 mod_files.sh 可以用来做这件事 -官方文件

Tsung 發表迴響取消回覆

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料