Ubuntu memiliki pengaturan tugas cron yang mencari dan menghapus sesi PHP lama:
# Look for and purge old sessions every 30 minutes
09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] \
&& [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
-maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) ! -execdir \
fuser -s {} 2> /dev/null \; -delete
Masalah saya adalah bahwa proses ini memakan waktu sangat lama untuk dijalankan, dengan banyak IO disk. Inilah grafik penggunaan CPU saya:
Pembersihan berjalan diwakili oleh paku kecil. Pada awal periode, pekerjaan pembersihan PHP dijadwalkan pada waktu default 09 dan 39 menit. Pada pukul 15:00 saya menghapus waktu 39 menit dari cron, jadi pekerjaan pembersihan dua kali ukuran berjalan setengah sering (Anda dapat melihat puncak mendapatkan dua kali lebih lebar dan setengah sering).
Berikut adalah grafik yang sesuai untuk waktu IO:
Dan operasi disk:
Pada puncak di mana terdapat sekitar 14.000 sesi aktif, pembersihan dapat terlihat berjalan selama 25 menit penuh, tampaknya menggunakan 100% dari satu inti CPU dan apa yang tampaknya 100% dari disk IO untuk seluruh periode. Mengapa sumber daya begitu intensif? Sebuah ls
direktori sesi /var/lib/php5
hanya butuh sepersekian detik. Jadi mengapa perlu 25 menit penuh untuk memotong sesi lama? Apakah ada yang bisa saya lakukan untuk mempercepat ini?
Sistem file untuk perangkat ini saat ini adalah ext4, berjalan pada Ubuntu Precise 12.04 64-bit.
EDIT: Saya menduga bahwa beban ini disebabkan oleh proses "fuser" yang tidak biasa (karena saya berharap yang sederhana rm
menjadi pemandangan yang lebih cepat daripada kinerja yang saya lihat). Saya akan menghapus penggunaan fuser dan melihat apa yang terjadi.
sumber
Jawaban:
Menghapus
fuser
harus membantu. Pekerjaan ini menjalankanfuser
perintah (periksa apakah file saat ini dibuka) untuk setiap file sesi yang ditemukan , yang dapat dengan mudah memakan waktu beberapa menit pada sistem yang sibuk dengan 14k sesi. Ini adalah bug Debian (Ubuntu didasarkan pada Debian).Alih-alih memcached Anda juga dapat mencoba menggunakan tmpfs (sistem file dalam memori) untuk file sesi. Seperti memcached ini akan membatalkan sesi pada reboot (ini dapat dikerjakan dengan membuat cadangan direktori ini di suatu tempat dalam skrip shutdown dan mengembalikan dalam skrip startup), tetapi akan jauh lebih mudah untuk setup. Tapi itu tidak akan membantu
fuser
masalah.sumber
fuser
proses dalam keadaan mengkonsumsi memori zombie, yang menyebabkan server crash. Saya pikir itu sudah diperbaiki dalam versi psmisc yang saya gunakan.fuser
proses, yang semuanya harus mencari keseluruhan/proc/
file terbuka.Selamat telah memiliki situs web populer dan mengelola agar tetap berjalan di mesin virtual selama ini.
Jika Anda benar-benar menarik dalam dua juta tampilan halaman per hari, maka Anda akan menumpuk BANYAK sesi PHP di filesystem, dan mereka akan memakan waktu lama untuk menghapus tidak peduli apakah Anda menggunakan
fuser
ataurm
atau penyedot debu.Pada titik ini saya sarankan Anda mencari cara alternatif untuk menyimpan sesi Anda:
memcached
. Ini sangat cepat, tetapi jika server crash atau restart, semua sesi Anda hilang dan semua orang keluar.sumber
rm
itu.Jadi, opsi penyimpanan Memcached dan sesi basis data yang disarankan oleh pengguna di sini adalah pilihan yang baik untuk meningkatkan kinerja, masing-masing dengan kelebihan dan kekurangannya sendiri.
Tetapi dengan pengujian kinerja, saya menemukan bahwa biaya kinerja yang sangat besar dari pemeliharaan sesi ini hampir seluruhnya tergantung pada panggilan ke
fuser
dalam pekerjaan cron. Berikut grafik kinerja setelah kembali ke tugas cron Natty / Oneiric yang menggunakanrm
alih-alihfuser
untuk memangkas sesi lama, peralihan terjadi pada 2:30.Anda dapat melihat bahwa penurunan kinerja berkala yang disebabkan oleh pembersihan sesi PHP Ubuntu hampir seluruhnya dihapus. Lonjakan yang diperlihatkan dalam grafik Operasi Disk sekarang jauh lebih kecil dalam besarnya, dan sekitar setipis yang dapat diukur oleh grafik ini, menunjukkan gangguan kecil, pendek di mana kinerja server sebelumnya terdegradasi secara signifikan selama 25 menit. Penggunaan CPU ekstra sepenuhnya dihilangkan, sekarang ini adalah pekerjaan yang terikat IO.
(pekerjaan IO yang tidak terkait berjalan pada 05:00 dan pekerjaan CPU berjalan pada 7.40 yang keduanya menyebabkan lonjakan mereka sendiri pada grafik ini)
Pekerjaan cron yang dimodifikasi yang saya jalankan sekarang adalah:
sumber
-print0 | xargs ...
tidak perlu - Anda bisa pergi begitu saja-delete
. Tapi itu akan bekerja dua arah dengan kecepatan yang sebanding.Saya menemukan posting ini ketika melakukan penelitian pada sesi. Sementara jawaban yang diterima sangat bagus (dan panggilan fuser telah dihapus dari skrip gc untuk beberapa waktu) saya pikir perlu dicatat beberapa pertimbangan lain jika orang lain menemukan masalah yang sama.
Dalam skenario yang dijelaskan, OP menggunakan ext4. Direktori di ext4 menyimpan data file dalam format database htree - yang berarti ada dampak yang dapat diabaikan dalam menyimpan banyak file dalam direktori tunggal dibandingkan dengan mendistribusikannya di direktori mutliple. Ini tidak berlaku untuk semua sistem file. Penangan default dalam PHP memungkinkan Anda untuk menggunakan beberapa sub-direktori untuk file sesi (tetapi perhatikan bahwa Anda harus memeriksa bahwa proses pengendalian berulang ke direktori tersebut - pekerjaan cron di atas tidak).
Banyak biaya operasi (setelah menghapus panggilan ke fuser) timbul dari melihat file yang belum basi. Menggunakan (misalnya) satu tingkat subdirektori, dan 16 pekerjaan cron yang mencari di setiap sub direktori (0 /, 1 /, ... d /, e /, f /) akan memuluskan beban gundukan yang timbul.
Menggunakan pengatur sesi khusus dengan substrat yang lebih cepat akan membantu - tetapi ada banyak yang bisa dipilih (memcache, redis, socket mysql handler ...) mengesampingkan kisaran kualitas yang dipublikasikan di internet, yang Anda pilih tergantung pada tepat persyaratan sehubungan dengan aplikasi Anda, infrastruktur dan keterampilan, jangan lupa bahwa sering ada perbedaan dalam penanganan semantik (terutama mengunci) dibandingkan dengan penangan default.
sumber
Dengan lalu lintas semacam itu, Anda seharusnya tidak membuat sesi tentang dis. Anda harus menggunakan sesuatu seperti memcache. Yang harus Anda lakukan adalah mengatur php dan tidak akan ada perubahan kode yang diperlukan. Lihat misalnya
http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/
Alasannya memakan waktu begitu lama adalah karena besarnya jumlah file yang harus disortir untuk melihat mana yang dapat dihapus. Memcache dapat kedaluwarsa secara otomatis karena lamanya sesi Anda ditetapkan dalam kode Anda.
sumber