@JohnDidact
Нуб во всём

Где хранить сессии? SQLite? MySQL? Memcached? Redis? FS?

Храню сессии в ФС. Для авторизованных пользователей - в одной папке, для неавторизованных - в другой. В папке неавторизованных демоном хожу и удаляю старые сессии. Вроде бы норм… Но решил я взглянуть в будущее: там директории, что с неавторизованными, что, особенно, с авторизованными сессиями, забиты в край! В этом я увидел много минусов: чтение директории усложнится, могу превысить лимит кол-ва файлов (я на shared-хостинге, так как на большее у меня нет ни денег, ни мозгов).
В общем, решил, что нужно искать другое хранилище. Почитал о способах хранения…
Какие выводы я сделал для себя? От худшего к лучшему, на мой взгляд:

1) Хранить дальше в ФС
Минусы: операция открытия и чтения файла, как я понял, слегка дороговата… Ограничение файлов, сложность чтения огроменного каталога.
Плюсы: лёгкая реализация и надёжность сохранности.
2) MySQL
Минусы: я вообще хочу минимизировать запросы к MySQL. В MySQL храню, в основном, большие данные, которые не редко меняются или данные, которые потом храню в сессии. Опять же, как я понял, множество запросов к мускулу и получение результа дольше, чем чтение файла (я не говорю, что соединение с мускулом дольше, чем открытие и чтение файла… я именно про запросы и получение результа). Соединение с сервером БД может по какой-либо причине оборваться.
Плюсы: лёгкая реализация, надёжность сохранения сессии (если считать, что соединение всегда установится)
3) Memcache/Redis
Ну об этих штуках я мало что знаю… Говоря про кэш, раньше я хранил кэш тупо в ФС. Вчера понял, что это не Найс и на кэш написал класс, который принимает данные кэша и класс сам определяет, по мере доступности, где его сохранить, в Memcached, SQLite или в ФС. С Memcached я ещё особо не разобрался. На своем хостинге я не нашел класс Memcache, зато нашёл Memcached, его нужно было принудительно врубить… От куда взять сервер - я вообще без понятий)) Написал localhost с портом 11211… хз, вроде работает. С Redis'ом вообще ещё даже не ознокамливался. Ну это на потом. С кэшем я разберусь… Хотел бы в ОП хранить его, и буду. Но вот сессии…
Минусы: я пока ещё не разобрался с Memcached и это минус (скорее минус мне, но всё же). Как я понял, Memcached может упасть в любой момент. И там уже нужно поднапречься, чтобы создавать дампы, цепочки северов и прочее. Жизнь и без этого сложна, не хочется ещё больше её усложнять. В Memcached я буду хранить кэш, который не критично потерять, не хотелось бы всё это смешивать в одной области.
Плюсы: всё довольно быстро (как я понял)
4) SQLite
Как по мне, в соотношении надёжный / быстрый / лёгкий - самый молодец!
Минусы: почти те же, что и у ФС за исключением размера каталога и кол-ва файлов. На счёт открытия и чтения файла я не вдавался в подробности, как там всё это происходит. Но, думаю, тоже так же, как обычное открытие и чтение. Здесь это не критично. Мне более важны размер каталога и кол-во файлов. Вот на счёт блокировки файла таблицы я ещё не совсем понял. Если 100 пользователей одновременно зайдут на сайт, что произойдёт? Они в очередь встанут или сломаются? За тайм-аут не выйдут?
Плюсы: легко, быстро…

Ещё читал про хранение на стороне клиента в куках, зашифровано, с ключом и т.д. но мне вообще это не подходит. Я не доверяю данным клиента, даже id сессии из Кук проверяю. Да и ограничение данных в куках. В общем, от этого сразу отказался.

Предпочел я SQLite. Какие камни меня ждут? И что посоветуете для хранения сессий, кроме ФС?
  • Вопрос задан
  • 669 просмотров
Решения вопроса 1
@FanatPHP
Чебуратор тега PHP
Храни в мускуле.

Файлы, действительно - самый неудачный вариант. Сара Големон, отвечая недавно на подобный вопрос, написала
File storage is only a default because the runtime doesn't know in advance what database engine or credentials you're going to use unless you tell it. So... ya know.... tell it.

То есть файлы - это от безысходности, и по-хорошему пхп бы хранил в базе, но просто не знает, в какой и как с ней соединяться.

Редис и мемкеш - это кэш, а не хранилище. Подумай над тем, что такое кэш и для чего он используется. И подходит ли кэш для хранения сессий.

Про скулиту ты все правильно написал. Те же файлы, вид сбоку.

А про мускуль очень смешно. Какая-то прямо повальная датабазебоязнь. Откуда это "я вообще хочу минимизировать запросы к MySQL"? Что за ерунда про "соединение может оборваться"? И как ты вообще можешь сравнивать по производительности файл на диске, который открывается при каждом запросе, с демоном, который держит все данные в памяти и отдает по сокету?
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@deliro
Агрессивное программирование
SQLite и ФС — абсолютно не подходят, если приложение будет масштабироваться

Серверы БД (MySQL/PostgreSQL/etc.) — надёжный но самый медленный вариант

In-memory БД (Redis/memcached) — отличный вариант, из всех выше, самый производительный, но можно упереться в оперативку

Signed Cookie Session (и его частный случай — JWT) — неописанный тобой вариант, самый экономный по памяти и диску и самый производительный. Сессия хранится прямо в куке. Сами данные сериализуются, например, JSON'ом и сжимаются, например, gzip'ом (но можно и msgpack + lzma взять, как угодно). После, чтобы пользователь (или хакер) не поменял куку по своему желанию, она подписывается, например, HMAC'ом + любой криптостойкой хэш-функцией
Из плюсов: 0 байт занятой оперативы (кроме момента выполнения запроса), 0 байт занимаемого места на диске, нет зависимостей от баз данных
Из минусов: нет возможности "разлогинить все остальные сессии" по запросу пользователя, небольшой сетевой оверхэд, так как сессия от браузера отправляется на каждый запрос, ограничение на размер данных в сессии, потому что данных должны влезть в куку, включая подпись и разделители. Но ради эксперимента, мне удалось засунуть в такую сессию первую главу Войны и мира сжатой, прежде чем упереться в лимит.
Ответ написан
Driver86
@Driver86
Немодератор toster.ru
(я на shared-хостинге, так как на большее у меня нет ни денег, ни мозгов).

Если проект мелкий, то файлов будет достаточно. Если не настроена автоочиска - настроить.
В остальном, можно использовать Redis. Это база данных, а не кэш, как, например, memcache.

Про скулиту ты все правильно написал. Те же файлы, вид сбоку.

Это больше про MySQL. Sqlite - это только один файл и проблема тут может быть только с горизонтальной масштабируемостью (например, при кластеризации проекта).
И не самая лучшая идея хранить часто удаляемые/изменяемые данные в БД - это приведёт к её дефрагментации.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы