Настройка Memcache+PHP: как истекает срок действия ключей в memcache?
Я провел некоторое исследование в этом и не нашел окончательного ответа.
У нас есть веб-приложение, использующее обработчик сессии PHP+Memcache.
У меня есть несколько вопросов, все они взаимосвязаны, но в конечном итоге моя проблема заключается в следующем: "Почему сессии PHP явно не истекают, когда мы думаем, что так и должно быть? т.е. конечный пользователь должен выйти из приложения через определенное время, но это не так.
Вот точки, пожалуйста, помогите мне соединить их и скажите, где я ошибаюсь:
- Насколько я понимаю, Memcache истекает ключи на основе установленного времени, в секундах (или метка времени Unix для больших значений).
- Истечение срока ленивый - т.е. ничего не удаляется заранее
- Обработчик сессии memecache в PHP использует sessions.gc_max_lifetime для установки срока действия ключа memcache. ИДК, может быть, это не так?
- Memcache должен, обслуживая запрошенный ключ и увидев, что срок его действия истек, не обслуживать его (а затем, возможно, также удалить?). Но, по крайней мере, не служить ему.
- Этот акт невыполнения его должен, для PHP, приравниваться к удаленному сеансу и выходу пользователя из системы.
Пользователи не выходят из системы.
Как я могу даже отладить это? Memcache не совсем прозрачен.
Примером, который не работал, является сайт с тайм-аутом сеанса, установленным на два часа. Примерный пользователь в последний раз будет использовать сайт ночью, а затем, через 8 - 10 часов, вернется на сайт и все равно будет авторизован.
1 ответ
Мы тоже с этим сталкивались, но сумели покопаться в этом и понять, что именно происходит. Симптомы, с которыми мы столкнулись, заключались в том, что memcache (с достаточно большим выделением памяти на нескольких серверах) начал вытеснять контент. Это нежелательно, так как может отрицательно повлиять на текущих посетителей сайта.
Контролируя сетевой трафик, мы видели сообщения из PHP в Memcache следующим образом:
set memc.sess.key.abcdabcdabcdabcdabcdabcd 0 0 1823 данных...
Это второй ноль, который вызывает проблемы - он определяет продолжительность кэширования элемента в memcache. Устанавливая его в ноль, memcache никогда не истекает этот пункт. В вашем случае это означало, что пользователи могут вернуться через несколько часов и продолжить доступ к вашему сайту. В нашем случае memcache заполнялся и вызывал удаление нужных данных.
Я копал дальше, и это сводится к расширению memcached PHP. Начиная с версии 1.0.2 (которую мы запускаем) этот код выглядит так:
sess_lifetime = zend_ini_long(ZEND_STRL("session.gc_maxlifetime"), 0);
if (sess_lifetime > 0) {
expiration = time(NULL) + sess_lifetime;
} else {
expiration = 0;
}
В этом отрывке это ZEND_STRL("session.gc_maxlifetime")
который не возвращает ожидаемое значение. Об этом сообщается как об ошибке в PHP, и исправление библиотеки memcached описано по адресу https://bugs.php.net/bug.php?id=59641.
Я развернул этот патч, проверил сетевой трафик и обнаружил, что он устанавливает время истечения, как и ожидалось.