Использование memcached для хранения сессия. Какие могут быть проблемы?

KhmelevskyY

Новичок
Использование memcached для хранения сессия. Какие могут быть проблемы?

Здравствуйте.
Решил хранить сессии не в файловой системе, а в memcached. Сессии используются только для идентификации пользователя, в принципе, там будет хранится только логин пользователя и его user_agent. Вроде проблем быть не должно, принцип такой: запускает отдельный демон мемкешд, этот демон будет использоваться исключительно для сессий, делается это с той целью, чтобы кеша всегда хватало и данные не затирались (людей не разлогиневалоне ни с того, ни с сего) и если будет несколько бэкендов, чтобы было одно место хранения сессий. При таком подходе есть какие-то невидимые грабли, люди которые реализовывали данную возможность поделитесь опытом, не будут ли данные затираться ни с того ни с сего?
 
есть у пхп стандартный механизм хранения сессия в memcached. разлогинивание решается не сессией, а автоматической авторизацией по кукам, сессии жить дольше 24 минут не должны в принципе и проблема с вытеснением из кеша не должна стоять.
 
Нашел статью http://www.softwareprojects.com/resources/programming/t-memcached-for-php-sessions-1654.html , где автор предлагает для подстраховки использовать базу данных. То есть, при каждой аутентификации данные сессии заносятся в базу данных и мемкешд. При считывании, проверяется, есть ли сессия с таким идентификатором в мемкешд, если есть - возвращает ее, иначе считывает ее с базы данных и повторно заносится в мемкешд.

Такой подход защитит от случайной потери данных сессий, но увеличиться нагрузка на субд при аутентификации пользователей, так как придется писать данные еще и в базу. Хотя, по идее, можно этим пренебречь, так как пользователь раз "запомнился", и все. Получается операций записи будет несоизмеримо меньше, чем операциями чтения, хотя в любом случае это увеличит нагрузку на субд. Стоит ли использовать такой подход? Или может не заморачиваться по этому поводу и хранить сессии только в мемкешд, и только следить чтобы места, зарезервированного под демон хватало для хранения сессий, чтобы не было вытеснения? Какой алгоритм используете вы в своих highload проектах?

-~{}~ 12.02.10 20:58:

Автор оригинала: dimagolov
есть у пхп стандартный механизм хранения сессия в memcached.
знаю про стандартный механизм хранения сессия в memcached.
Автор оригинала: dimagolov
разлогинивание решается не сессией, а автоматической авторизацией по кукам, сессии жить дольше 24 минут не должны в принципе и проблема с вытеснением из кеша не должна стоять.
непонятно, я могу сделать чтобы сессия у меня жила месяц, например, и не вижу в этом проблемы,а в куках хранить только ее идентификатор. просто и удобно ( http://habrahabr.ru/blogs/webdev/40714/ )
 
KhmelevskyY, ты %уем девушку удовлетворяешь? А омлет им взбиваешь? Нет? Почему? Движения почти те же самые?

Сессионная кука живет в браузере до его закрытия. Рассчитывать не то, что значительное кол-во пользователей будут держать месяцами открытый браузер, это как омлет %уем взбивать. А если на это не рассчитывать, то долгий срок хранения сессионных данных на сервере становится совершенно бессмысленным. Учти, что с каждым обращением пользователя к сайту, сессия обновляется и ей опять вытеснение из кеша не грозит. Раз так, то и велосипедов с "подстраховкой" придумывать нету смысла. Для долговременного хранения используй себе БД, никто не запрещает, но мешать их с сессией не нужно.
 
В базе предлагается дублировать на случай вытеснения данных из memcached, я верно понимаю?

Можно немного пропатчить memcached для продление жизни ключей при каждом get-е.

Примерно так:

http://symbi.org/misc/memcached-1.2.2-autoprolongate.patch

Смысл в том, что при определенном взведенном бите flags, при очередном get-е автоматически продлевается время жизни ключа.
Если используется библиотека, которая flags не выпячивает наружу, а использует для своих целей (как pecl/memcached), соответственно, тоже нужно патчить для поддержки этого режима.

Конечно, это не спасает от вытеснения сессионных данных при нехватке памяти в slab-е, но это тоже можно решить использованием отдельного (отдельных) инстансов memcached под сессии.

Дублировать в базе как-то жирно :) если речь идет о хайлоаде. А если высоких нагрузок нет, а нужно просто обеспечить sharing сессии между веб-мордами - дык можно и в базе хранить. Или, в конце-то концов, делать запись в memcached _каждый раз_, независимо от того, изменились ли сессионные данные.

Как это интегрировать со стандартным php-шным механизмом хранения сессий в memcached, не знаю (хотя, очевидно, либо пропатчить, либо написать свои хендлеры) - я вообще не люблю стандартный механизм сессий и его всячески избегаю, хотя многие мне говорят что это и необоснованно. =)
 
Дублировать в базе как-то жирно
это просто бред, хранить сессии в БД. Это делали когда-то давно (в эпоху пхп3/4), когда не было memcache
как один из вариантов, если боитесь вытеснение сессий - хранить сессии в редисе, хотя в наше время при цене на память - можно себе позволить и мемкеш.
 
>> как один из вариантов, если боитесь вытеснение сессий - хранить сессии в редисе

Зачем? memcached можно сказать, чтобы он не вытеснял, а возвращал ошибку в случае нехватки памяти:

$ memcached -h | grep error
-M return error on memory exhausted (rather than removing items)

Это всяко лучше, чем начать люто, бешено свопиться.

Но я себе не очень представляю, как обрабатывать такую ситуацию в случае нехватки памяти.

Лучше мониторить соотношения hit/miss, выпадение из общей статистики покажет, что надо доставлять память.
 
fixxxer, можно заранее оценить какой объем памяти понадобиться для хранения сессионных данных. хотя бы приценившись на файлах при рабочей нагрузке. ну и дать запас.
 
Автор оригинала: dimagolov
KhmelevskyY, ты %уем девушку удовлетворяешь? А омлет им взбиваешь? Нет? Почему? Движения почти те же самые?

Сессионная кука живет в браузере до его закрытия. Рассчитывать не то, что значительное кол-во пользователей будут держать месяцами открытый браузер, это как омлет %уем взбивать. А если на это не рассчитывать, то долгий срок хранения сессионных данных на сервере становится совершенно бессмысленным. Учти, что с каждым обращением пользователя к сайту, сессия обновляется и ей опять вытеснение из кеша не грозит. Раз так, то и велосипедов с "подстраховкой" придумывать нету смысла. Для долговременного хранения используй себе БД, никто не запрещает, но мешать их с сессией не нужно.
Уважаемый, то ли я вас не понимаю то ли вы ошибаетесь. Выдержка с php.net
PHP:
  session.cookie_lifetime  integer     
session.cookie_lifetime specifies the lifetime of the cookie in seconds which is sent to the browser. 
The value 0 means "until the browser is closed." Defaults to 0.
Вот я установил время жизни куки у пользователя месяц.
PHP:
ini_set('session.cookie_lifetime', 2073600);
Не вижу в общем пролемы...

Автор оригинала: fixxxer
Можно немного пропатчить memcached для продление жизни ключей при каждом get-е.
Супер, не знал. Сто процентов буду патчить, спасибо за наводку.

Автор оригинала: fixxxer
Конечно, это не спасает от вытеснения сессионных данных при нехватке памяти в slab-е, но это тоже можно решить использованием отдельного (отдельных) инстансов memcached под сессии.
так и собирался делать

Автор оригинала: Alexandre
это просто бред, хранить сессии в БД. Это делали когда-то давно (в эпоху пхп3/4), когда не было memcache
как один из вариантов, если боитесь вытеснение сессий - хранить сессии в редисе, хотя в наше время при цене на память - можно себе позволить и мемкеш.
Автор оригинала: fixxxer
Зачем? memcached можно сказать, чтобы он не вытеснял, а возвращал ошибку в случае нехватки памяти:
$ memcached -h | grep error
-M return error on memory exhausted (rather than removing items)
Это всяко лучше, чем начать люто, бешено свопиться.
Но я себе не очень представляю, как обрабатывать такую ситуацию в случае нехватки памяти.
Лучше мониторить соотношения hit/miss, выпадение из общей статистики покажет, что надо доставлять память.
Спасибо за советы, помогли мне определится. Будет использоваться только memcached, отдельным инстансом, в случае нехватки памяти будет возвращать ошибку. Обязательно будут мониториться соотношения hit/miss и кол-свободной памяти забиксом, например. Единственное, что немного смущает, если использование памяти будет доходить до максимума, придется перезапускать мемкеш с увеличенным количеством выделенной для него памяти, соответственно все данные потеряются и пользователям придется заново перелогинится.
Хотя, если это так критично, можно запустить новый инстанс на другом порту с увеличенным количеством используемой памяти, перелить все данные с старого кеша в новый и в приложении изменить настройки подключения к memcached. Если и будут потери, то минимальные.

Всем спасибо!
 
ini_set('session.cookie_lifetime', 2073600);
Не вижу в общем пролемы...
Кука-то, может, и не сдохнет, а сессионные данные наверняка.

Так что лучше заводить отдельную куку для авторизации по ней, если сессионной нет или сессия сдохла. Класть туда хоть бы и что-то типа json_encode(array($user_id, md5(SALT . md5($password))). Хотя вместо password я предпочитаю отдельное поле со случайно сгенеренной при регистрации строкой.
 
Сверху