Оптимизация хранения сессий PHP

xsequel

Новичок
Привет, всем
Пишу движок, предполагается нагрузка >= 20к уников в сутки. Стал вопрос с хранением сессий. У кого есть опыт хранения сессий в таком размере. Отзовитесь :) Как лучше подойти к этому вопросу, можно хранить на файлах или лучше перенести в память типа memcache, redis и т.п.? В память не особо желательно двигать это все так как будут много операций в памяти и хранить не основные stateful значения не особо хочется. Если хранить на файлах то будут ли тормоза в таком количество когда будет срабатывать gc? И вообще будут ли тормоза если скажем сессии в размере например 50к хранятся на файлах?
 

MiksIr

miksir@home:~$
не использовать нативную сессию, не авторизованным - все в куки, авторизованным - в базу
 

xsequel

Новичок
А чем чреваты нативные сессии? Можете более аргументировано насчет нагрузки? Потому нужно принять решение, а счас много кода завязано на них уже.
 

MiksIr

miksir@home:~$
Тем, что они, как правило не нужны. Вот что вы храните в сессиях?
 

xsequel

Новичок
Пользователя (идентификатор, настройки), сообщения пользователю (docs.djangoproject.com/en/1.3/ref/contrib/messages/), капча ключи, csrf ключи. Ну это на данный момент.
Но вопрос все таки общего плана. Почему на файлах плохо? Это обусловлено нагрузкой gc или что?
И не проще тогда например перенести на базу или memcache сессии через session_set_save_handler чем писать свою реализацию тех же самых сессий?
 

MiksIr

miksir@home:~$
Аутентификация по ключу из кук - тут сессия не нужна, достаточно положить туда уникальный id и некий хеш = функция от пароля и прочих данных.
Настройки в базу к пользователю, это персистентная информация, будет обидно пользователю, если они сбросятся.
Флеш сообщения - ну, я вообще их не очень люблю, имхо, это та гибкость, которая потом только мешает.. ну да не суть, та же приведенная ссылка умеет делать флеш сообщения в куках.
Так что просто не встает вопроса - а зачем сессии. Тормозить... ну, это зависит от многих факторов, а вот что масштабировать в share-nothing кластере не получится - это факт. Как вариант на коленке, угу, можно запихнуть в базу/мемкеш. Нужно только быть уверенным, что будет что там хранить.
 

Вурдалак

Продвинутый новичок
Короче, используй сессии обычные и не парься. При нормальном подходе, используя обёртку, ты сможешь поменять место хранения сессий за пару минут. А вот с memcached и БД надо ещё учитывать возможное состояние гонки. А 50K файлов сессий — это больно много для 20K хостов. Сессии долго хранить не имеет смысла. Аутентификация с помощью ключа автологина в куках всё равно же по-любому будет.
 

MiksIr

miksir@home:~$
Короче, используй сессии обычные и не парься. При нормальном подходе, используя обёртку, ты сможешь поменять место хранения сессий за пару минут. А вот с memcached и БД надо ещё учитывать возможное состояние гонки. А 50K файлов сессий — это больно много для 20K хостов. Сессии долго хранить не имеет смысла. Аутентификация с помощью ключа автологина в куках всё равно же по-любому будет.
Ну на правах флуда, ну объясните мне применение сессий, которые не долго живут. Ну правда, мне вот только одно применение приходит в голову - помощь ленивым программистам для возврата на страницу после формы авторизации и иной подобной, что меня, как человека не ограничивающего себя одной вкладкой, всегда жутко злило. Еще что-то, что нельзя хранить в куках, и при этом короткоживущее?
 

xsequel

Новичок
На правах флуда я отвечу уж
Настройки в базу к пользователю, это персистентная информация, будет обидно пользователю, если они сбросятся.
Настройки в БД, только при аутентификации заносятся в сессию. При любом раскладе работает быстрее, чем из базы дергать. Если конечно сама сессия не на БД... Будет обидно если куки угонят, а то что сессия сброситься через сутки не так страшно
Флеш сообщения - ну, я вообще их не очень люблю, имхо, это та гибкость, которая потом только мешает.. ну да не суть, та же приведенная ссылка умеет делать флеш сообщения в куках.
Это понятно. Я навел просто что юзается.

MiksIr, как вы реализовываете csrf защиту? Если я так понял вы сессий не юзаете, вы ключи в базе храните?

Тогда как минимум получается если следовать вашим рекомендациям оверхед 2 запроса, настройки пользователя, csrf ключ. Что уже не гуд. В отличие от сессий даже на файлах или даже если на БД сессии то 1 запрос. + если все что вы предлагаете сделать на куках, то тоже не гуд, передавать метровые хидеры, тоже сеть не ускорит.
А насчет распределенной архитектуры, то вопрос счас так не стоит, но все равно сессию перенести на БД или какое распределенное хранилище один класс написать подключить, так что это не проблема. Мне кажется наоборот то что вы предлагаете как раз проблема как в поддержке так и в нагрузке на сеть.
 

MiksIr

miksir@home:~$
Использовать сессии для экономии одного запроса в базу - так себе агрумент. Во-первых, такой подход создает еще кучу неудобств по управлению пользователем со стороны администратора - попробуй, удали оперативно такого пользователя - придется еще его сессию искать, а что бы его сессию искать - придется еще ее ключ в той же базе хранить. Во-вторых, заявления, что файлы работают быстрее базы - не состоятельны, зависит от огромного числа факторов. В-третьих, рано или поздно придется (точно говорю =) убрать сессии в базу, и тут первый аргумент вообще выпадает.

Угон кук из той же серии - страшилка, с непониманием сути. Если вы делаете так называемый "автологин", то угонят ключ автологина, и пофиг на то, что ключ сессии живет 5 часов. С другой стороны, если начать думать, то понимаешь, что в ключ сессии можно подмешивать любую информацию. Юзерагент, нужное число окетов IP адреса, интервал времени, пока этот ключ валиден. Т.е. короткая сессия не защищает от "угона", если используется автологин, если же автологин не используется, время жизни можно ограничить и без сессии.

Нет, ключи я в базе не храню, вы не поняли. Ключ является итогом хеширования набора доступной программисту информации, его не нужно хранить вообще, ибо его можно опять сгенерировать на стороне сервера и сравнить с тем, что пришло. Как бонус получаете очень полезную функцию сброса "автологина" на всех компьютерах при изменении пароля - хеш пароля меняется = все ключи невалидны.

Csrf точно так же можно генерить от неких данных - банально от user_id, IP и т.д.

Понимаете, сессии - это механизм создания приложений начального уровня. Он удобен тем, что уже есть, что прост в использовании и программисту вообще не нужно ни о чем думать. Как только вы собираетесь делать сложное приложение, сессии начинают мешать. Начинается нагромождение костылей - куда сессии класть, как их чистить и т.д. и т.п. - и в итоге получается подобие того, что сделали бы изначально сами (а именно - пересистент в базе + кеширование и короткоживущее в мемкеше), только гораздо менее гибко и прозрачно - вы ограничены одним местом хранения, и не можете разбросать данные по разным, не можете назначить данным разное время жизни и т.п. Т.е. можете, конечно, но продолжением костылей.

ЗЫ И проблем в поддержке не вижу. А вот проблемы в поддержке толпы файлов на диске - вполне вижу. Но вообще-то если вы не видите преимуществ отказа от сессий - не отказывайтесь. В конце концов, мало кто умеет использовать чужой грабельный опыт.
 

xsequel

Новичок
Csrf точно так же можно генерить от неких данных - банально от user_id, IP и т.д.
Я понял, вы ее просто никогда не делали.
Вы рассматриваете универсальный вариант, а я вполне конкретный. Например вот зачем мне убирать по сессии пользователя когда то? Да это может пригодится, точно так же как медведю велосипед. А если я вижу что пользователь чето творит не ладное то думаю грохнуть все сессии не будет страшно из папки. Иначе это как медведю велосипед.
Во-вторых, заявления, что файлы работают быстрее базы - не состоятельны, зависит от огромного числа факторов
Смешно. Если бы знали как Си с файлами работает такого бы не заявили. Это будет работать быстрее всегда, только если БД не в памяти типа Redis.
В-третьих, рано или поздно придется (точно говорю =) убрать сессии в базу, и тут первый аргумент вообще выпадает.
Да, но можно будет убрать в базу которая работает быстро redis, mongodb а не реляционную. И все это дело 15-ти мин. В любой момент жизни проекта. Так как существует session_set_save_handler. И при этом код проекта не нужно будет переписывать, а только подключить класс. А если идти вашим путем, могут появится проблемы переброса сессий с СУБД на более быстрые хранилища. Иначе придется писать библиотеку уже и сейчас.
Угон кук из той же серии - страшилка, с непониманием сути. Если вы делаете так называемый "автологин", то угонят ключ автологина, и пофиг на то, что ключ сессии живет 5 часов. С другой стороны, если начать думать, то понимаешь, что в ключ сессии можно подмешивать любую информацию. Юзерагент, нужное число окетов IP адреса, интервал времени, пока этот ключ валиден. Т.е. короткая сессия не защищает от "угона", если используется автологин, если же автологин не используется, время жизни можно ограничить и без сессии.
Спасибо, КО. Что такое session hijacking я знаю. Я говорил о куках профиля или вы поняли что у пользователя профиль это настройки типа background body, нет, настройки профиля конкретного проекта это достаточно ценная информация и ее хранить в куках это идиотизм.

Я так и ни одного костыля с ваших слов не увидел. Увидел только что вы свои проекты не защищаете :) И при этом очень не эффективный подход к архитектуре советуете. Уж извините, но такое мое мнение.
 

MiksIr

miksir@home:~$
Думаю, диалог закончен. Дискутировать об "архитектуре" с человеком, который предлагает "грохнуть все файлы из папки" (ага, все 20 тысяч), и не сталкивался с загруженными дисками в купе с 20 тыс. файлов в одной директории как-то... забавно, что ли... но беполезно. Интересно, хоть то, что даже нативные сессии должны быть обернуты в класс доступа вы понимаете? А то так пугает написание библиотек, что даже не знаю...
 

xsequel

Новичок
согласен, думаю что дискутировать, с человеком, который даже не знает для чего csrf защита, действительно забавно (Csrf точно так же можно генерить от неких данных - банально от user_id, IP и т.д.) )))
а уж о том как интерпретатор с файлами работает, уже и подавно не знает но утверждает что файлы медленее БД. Вы сначала логику включите, потом почитайте как Си поднимает файлы в память, потом проверьте что быстрее файлы или база. И убедитесь что чепуху рассказываете.
и не сталкивался с загруженными дисками в купе с 20 тыс. файлов в одной директории как-то... забавно
И часто приходилось сбрасывать сессии? Вот и я о чем, это нужно сто лет в обед. Читайте вопрос какой был, вы уже вопрос 5 раз перекрутили. "Если хранить на файлах то будут ли тормоза в таком количество когда будет срабатывать gc?" Я спрашивал конкретно о Garbage collector. А вы мне тут курс молодого бойца устроили "Угон кук из той же серии - страшилка, с непониманием сути. " называется "В огороде бузина а в Киеве дядька". Разве я вас это спрашивал? Я возможно получше вас знаю как угнать и как подделать, но нет нужно как павлин перья растопырить.
Нужно было просто проверить gc на тестовых данных, чем дискутировать с человеком который даже не знает что такое CSRF.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
xsequel не обижайся, тут всегда есть несколько участников специальной олимпиады, которые рвут на части новичков, ничего толком не объясняя и забыв, что преждевременная оптимизация - большое зло
но есть и кто по делу может сказать (я не про себя)

imho, с "20к уников в сутки", т.е. 5 тысяч файлов в каталоге и <1млн хитов к php на dedicated, можно настроить время жизни сессий и не париться вообще
будет больше - распределить сессии по подкаталогам нативными настройками и написать скрипт для крона, который будет чистить старые файлы;

Проблема будет на VPS/хостинге с перегруженным винтом, тогда можно переключить на memcached в нативный драйвер и тоже не париться с гонкой, эта проблема на других масштабах вылазит.
Когда-то я перенес сессии в mysql heap-таблицу на vps, выделил на это 10 мб памяти из 512 и отлично бегало 450к хитов с 10+ la.
Но это надо профайлить и видеть, что проблема именно в сессиях, а пока в session_start() боттлнека нет, ничего делать и не надо.
 

xsequel

Новичок
grigori, да я не обижаюсь. мне просто была удивительна неприязнь к нативным сессиям MiksIr, поучения не по вопросу, но при этому предлагающего написать такой же велосипед 1 к 1-ому.
Сначала будет скорее всего vds, потом отдельный сервер. Но вот памяти сначала будет не думаю что много, + будут более приоритетные операции в памяти поэтому и ее не хочется лишний раз грузить.
Ладно спасибо всем, я уже решил почитав и другие источники, оставлю на файлах, потому перекину на память если будут проблемы.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
это наша добрая традиция :) тут каждый может быть начальником, welcome to the club

не экономь на vps, проверяй загрузку I/O-системы перед деплойментом, это их самое больное место
 

MiksIr

miksir@home:~$
Ну может grigori объяснит смысл короткоживущих сессий? Пока все, что я понял, это утопичная идея использования сессий в качестве файлового кеша для экономии 1-2 запросов в базу? А как же принцип "применяем по мере необходимости", т.е. кешируем тогда, когда это становится нужно?
Т.е. разрабатывать движок, в котором предусмотрены механизмы кеширования чего мы хотим куда мы хотим - это не круто, а запихать все в сессию - круто? Т.е. мы пишем обертку над сессией, потом пишем "распределение по каталогам нативными настройками" (гора костылей с генерированием своего id и установки session_save_path, я правильно понял?), потом пишем еще кучку функций для реализации своих действий на сохранение сессий... и это все вместо того, что бы написать сразу простой и понятный класс кеширования и использовать его _когда_ нужно? Ну-ну.
Вы сначала логику включите, потом почитайте как Си поднимает файлы в память
Си ничего не поднимает. Си - это язык программирования, он сам ничего поднимать не умеет, это делают написанные программистом программы. Это раз.
"Поднимает в память" не интерпретатор, а операционная система - используя _свободную_ память в системе. Мало свободной памяти - почти нет кеша. К тому же операционная система ничего не знает о ваших приоритетах, по-этому в этой памяти еще много чего сидеть будет - картинки, файлики... жуть. В лучшем случае файловая система закеширует таблицу файлов, что бы быстро искать их на диске. В худшем - и онная будет вылетать по недостатку памяти. Не найденный в кеше файл (что вполне реальная ситуация) череват несколькими сиками головок по диску - сначала к таблице размещения файлов, потом к файлу. Если вы тестируете на домашнем десктопе - то это будет мега-быстро. Если у вас реальный сервер - это может быть в диапазоне от супер-быстро до супер-медленно. Реально у меня есть примеры с VDS-ок, когда банальная ls по каталогу в тысячу-другую файлов работала 20-30 секунд. И при этом ("не экономь на vps") - это был один из самых крупных и дорогих провайдеров. А у вас таких примеров нет, зато вы умный и готовы спорить. Молодец, чо.
В случае с своим кешированием вы имеете гораздо больше возможностей по управлению - сколько памяти под какие цели выделить.
А вы мне тут курс молодого бойца устроили "Угон кук из той же серии - страшилка, с непониманием сути. "
Извините, а разве не вы первый это начали? "Будет обидно если куки угонят, а то что сессия сброситься через сутки не так страшно"... вам ответили, а вы теперь обижаетесь?
который даже не знает что такое CSRF
Расскажите, чем же мой вариант хуже вашего (ваш, как я понимаю, генерация произвольного ключа и хранение в сессиях, ага).
 

MiksIr

miksir@home:~$
Да не, просто надо вопрос ставить изначально верно. "Ваяю движок по-быстрому, но когда-то у меня будет 20к уников, а потом и больше - стоит мне парится из-за этого сейчас?" Даже я ответил бы, что нет. А когда человек спрашивает, что ему нужно спроектировать движок под >= 20к уников, как-то думается, что он уже вырос немного из говнокода.
 

baev

‹°°¬•
Команда форума
Вы сначала логику включите, потом почитайте как Си поднимает файлы в память, потом проверьте что быстрее файлы или база.
«База» на каком языке написана?..
 
Сверху