Завдання Cron збору сміття для сеансів PHP займає 25 хвилин, чому?


13

У Ubuntu створена робота з кроном, яка шукає та видаляє старі сеанси PHP:

# 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

Моя проблема полягає в тому, що цей процес займає дуже багато часу, з великою кількістю дискового вводу. Ось мій графік використання процесора:

Графік використання процесора

Проведення очищення представлено слізними шипами. На початок періоду завдання очищення PHP були заплановані за замовчуванням 09 та 39 хвилин. О 15:00 я зняв 39-хвилинний час з крона, тому робота з очищення вдвічі менша за розміри вдвічі частіше (ви можете бачити, що вершини стають удвічі ширшими та наполовину частішими).

Ось відповідні графіки для IO часу:

IO час

І дискові операції:

Операції з диском

На піку, коли було активним близько 14000 сеансів, очищення можна побачити протягом повних 25 хвилин, мабуть, використовуючи 100% одного ядра центрального процесора і те, що, здається, становить 100% дискового вводу протягом всього періоду. Чому це так ресурсомістко? lsКаталогу сеансу /var/lib/php5займає всього частку секунди. То чому для обрізки старих сеансів потрібно цілих 25 хвилин? Чи можна щось зробити, щоб прискорити це?

Файлова система цього пристрою наразі ext4, працює на 64-розрядній версії Ubuntu Precision 12.04.

EDIT: Я підозрюю, що навантаження пов'язана з незвичним процесом «термозахисного пристрою» (оскільки я очікую, що простий rmбуде проклятим видовищем швидше, ніж продуктивність, яку я бачу). Я збираюся зняти використання термозапчастин і подивитися, що станеться.


Скільки трафіку отримує ваш веб-сайт, щоб створити стільки сеансів?
Майкл Хемптон

Відповіді:


9

Видалення fuserмає допомогти. Це завдання виконує fuserкоманду (перевірте, чи файл зараз відкрито) для кожного знайденого файлу сеансу , який може легко зайняти кілька хвилин у зайнятій системі з 14k сеансами. Це була помилка Debian (Ubuntu заснована на Debian).

Замість запам’ятовування ви також можете спробувати використовувати tmpfs (файлову систему в пам'яті) для файлів сеансу. Як і запишене, це призведе до недійсності сеансів при перезавантаженні (це можна вирішити, створивши резервну копію цього каталогу десь у скрипті вимкнення та відновлення в сценарії запуску), але буде набагато простіше в налаштуванні. Але це не допоможе fuserпроблемі.


Здається, що помилка у фюзері полягала в тому, що більш рання версія розщедрилася, але після завершення не була реалізована, залишаючи тисячі fuserпроцесів у зомбі-стані, що споживає пам'ять, що призводить до збою сервера. Я думаю, це вже зафіксовано у версії psmisc, яку я використовую.
тодіickdude

Це ще одна помилка. У вас є проста проблема запуску тисяч fuserпроцесів, які всі повинні шукати у цілому /proc/для відкритих файлів.
Томецький

9

Вітаємо, що користуєтеся популярним веб-сайтом і встигаєте весь цей час працювати на віртуальній машині.

Якщо ви на самому справі тягне в двох мільйонів переглядів сторінок в день, то ви збираєтеся складають ЛО PHP сесій в файлової системі, і вони збираються зайняти багато часу , щоб видалити , незалежно від того , чи використовуєте ви fuserабо rmчи в пилосос.

На даний момент я рекомендую вам переглянути альтернативні способи зберігання сеансів:

  • Один із варіантів - зберігати сеанси вmemcached . Це блискавично, але якщо сервер виходить з ладу або перезавантажується, всі ваші сеанси втрачаються, і всі виходять із системи.
  • Ви також можете зберігати сеанси в базі даних. Це буде трохи повільніше, ніж запам’ятоване, але база даних буде стійкою, і ви можете очистити старі сеанси за допомогою простого запиту SQL. Однак для цього потрібно створити спеціальний обробник сеансу .

Memcached, безумовно, є варіантом, хоча це повинно бути окремим пулом від нашого основного запам’ятованого екземпляра, інакше сеанси будуть випадково виселені з нашого тиску кешу. Я не переконаний, що для видалення 14 000 файлів потрібно 25 хвилин. Це звучить для мене занадто повільно. Я збираюсь почекати пару годин і подивитися, як rmвиглядає вистава простого .
тодібук

Не знаючи більше про вашу загальну архітектуру, я вагаюся рекомендувати одну над іншою.
Майкл Хемптон

Ви можете об'єднати сервери Memcached для надмірності, встановивши memcache.session_redundancy = 2. Дивіться сервер defaultfault.com/questions/164350/… . Redis - хороший варіант, якщо вас турбує стійкість і набагато швидше, ніж сховища баз даних SQL.
jfountain

4

Отже, варіанти зберігання сеансів Memcached та бази даних, запропоновані користувачами, тут є і хорошим вибором для підвищення продуктивності, кожен зі своїми перевагами та недоліками.

Але, перевіривши ефективність роботи, я виявив, що величезна вартість продуктивності обслуговування цього сеансу майже повністю знижується на заклик до роботи fuserз cron. Ось графіки продуктивності після повернення до завдання cron Natty / Oneiric, яке використовує rmзамість fuserобрізки старих сеансів, переключення відбувається о 2:30.

Використання процесора

Пройшов час вводу-виводу

Операції з диском

Ви можете бачити, що періодична деградація продуктивності, викликана очищенням сеансу PHP Ubuntu, майже повністю видалена. Шпилі, показані в графіку операцій з дисками, тепер значно менші за розміром, і приблизно такі ж худі, як цей графік, можливо, вимірюють, показуючи невеликий короткий зрив, коли раніше продуктивність сервера була значно погіршена протягом 25 хвилин. Додаткове використання процесора повністю виключено, тепер це робота, пов'язана з IO.

(Незалежна робота вводу-виводу працює в 05:00, а робота процесора працює в 7:40, що обоє викликають власні сплески на цих графіках)

Модифікована робота cron, яку я зараз виконую:

09 *     * * *     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) -print0 \
   | xargs -n 200 -r -0 rm

-print0 | xargs ...не потрібно - ви можете просто піти -deleteтуди. Але це буде працювати обома способами із порівнянною швидкістю.
Томецький

1

Я натрапив на цю посаду, коли робив кілька досліджень на сесіях. Хоча прийнята відповідь дуже хороша (і виклик термічного жителя був видалений зі скрипта gc на деякий час), я думаю, що варто відзначити кілька інших міркувань, якщо хтось ще зіткнеться з подібною проблемою.

В описаному сценарії ОП використовував ext4. Каталоги в ext4 зберігають дані файлів у форматі бази даних htree - це означає, що утримування великої кількості файлів у одному каталозі є незначним впливом порівняно з розподілом їх у кількох змішаних каталогах. Це стосується не всіх файлових систем. Обробник за замовчуванням у PHP дозволяє використовувати декілька підкаталогів для файлів сеансу (але зауважте, що ви повинні перевірити, що процес керування повторюється в ці каталоги - завдання cron вище).

Багато витрат на операцію (після вилучення дзвінка до термофіксатора) пов'язані з переглядом файлів, які ще не застаріли. Використання (наприклад) одного рівня підкаталогів та 16 завдань Cron, що шукають у кожній підкаталозі (0 /, 1 /, ... d /, e /, f /), згладить виникаючі навантаження навантаження.

Використання користувальницького обробника сеансу з більш швидким субстратом допоможе - але є багато чого вибрати (memcache, redis, mysql socket handler ...), залишаючи осторонь якість опублікованих в Інтернеті, які ви виберете, залежить від точного вимоги щодо вашого додатка, інфраструктури та навичок, не забуваючи, що часто трапляються розбіжності в обробці семантики (особливо блокування) порівняно з обробником за замовчуванням.


0

При такому трафіку ви не повинні ставити сеанси на дис. Ви повинні використовувати щось на зразок пам’яті. Все, що вам потрібно зробити - це налаштувати php, і не потрібно буде змінювати код. Див. Наприклад

http://www.dotdeb.org/2008/08/25/storing-your-php-sesions-using-memcached/

Причина, яка займає так довго, пов’язана з величезною кількістю файлів, які вона має сортувати, щоб побачити, які з них можна видалити. Memcache може автоматично закінчити їх, враховуючи тривалість сеансу, яку ви вказали у своєму коді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.