Как хранить сессии при условии нескольких серверов и реплики

Активист

Активист
Команда форума
Всем привет! Давно не был, много проблем было да и работы. Друзья, подскажите.

Организовано два отдельных веб сервера, на каждом поднять MySQL. Настроена master - master репликация. Все на Debian Weezy. Два независимых ЦОДа, рядом (пинг 2-3 мс), не критично. На уровне Nginx настроено обращение к соответствующему бекэнду, если один не доступен, отправляем на другой (nginx upstream), в front контроллере приложения выполняется запрос к СУБД на проверку основных параметров реплики (Slave_IO_Running, Slave_SQL_Running, Seconds_Behind_Master, Last_Errno, Last_SQL_Errno, Last_IO_Errno) на корректность, и в случае, если реплика задерживается или имеется ошибки отправляем на второй (через контроль 5xx ошибок).

Все ок, работает. Вопрос только с сессиями? Как их лучше хранить? В СУБД или что-то вроде редис (но как я понимю, он сейчас не поддерживает master-master реплику).

Вообще, первый сервер получает в основном публичные коннекты, а вот второй сервер получает обращения сотрудников компании, последние имеют приоритет.

Почему это сделано? Если веб сервер не будет обрабатывать запросы более 10 минут, мне капец. Поэтому в зоне TTL ли миниальные, и в случае выхода одного сервера все запросы отдам другому, да и в плане подключить третью реплику для RO юзеров, которые на RO сильно грузят сервера запросами на бух отчеты по разным критериям.
 
Так критично не потерять даже сессии? Ну, в couchdb есть мастер-мастер, например. Еще repcached был, но не знаю, жив ли он.
 
В Баду, если я ничего не путаю, сессии хранятся именно в БД. в Мускуле.
И именно потому что все остальное может потеряться.
 
в front контроллере приложения выполняется запрос к СУБД на проверку основных параметров реплики
ЧО??? Какое обращение к базе из контроллера? :)
Ну, в драйвер можно добавить проверку, которая бы отрабатывала при подключении, и только для некоторых запросов, вроде балланса счета.

В СУБД или что-то вроде редис (но как я понимю, он сейчас не поддерживает master-master реплику).
Поддерживает. Sentinel, называется. У редиса другая проблема - для большого количества записей нужен шардинг, иначе тупить начнет, это by design. То есть, если сессий много, надо несколько инстансов поднимать, можно на разных портах - подразумеваю, что оперативки сколько угодно.
А так, 100к одновременных сессий без проблем.

Если веб сервер не будет обрабатывать запросы более 10 минут, мне капец. Поэтому в зоне TTL ли миниальные, и в случае выхода одного сервера все запросы отдам другому
Тогда чего не делаешь нормально, почему всего 2 сервера, а не по 3 в каждом ЦОДе? Что насчет vIP, бесшовного failover?
 
Последнее редактирование:
а что такого необычного? failover в enterprize обязателен. может, там потери будут миллионами
Ну, можно построить приложение так, что в сессии нет ничего, что не продублировано в базе, и в случае чего восстанавливать ее по криптокуке.
 
Я в последнее время вообще предпочитаю обходится без сессий и делать pure stateless. Вместо session id - криптокука и криптотокен, по криптотокену auth, по криптокуке перевыпуск токена, весь стейт в хранилищах через репозитории так или иначе (база или что-то еще, неважно). Понятно, что такое не всегда подходит, особенно, если нужен сложный стейт для гостей (много возни с зачисткой). Зато тот же бэкенд подходит для мобильных аппов без изменений.
 
Последнее редактирование:
  • Like
Реакции: AmdY
Делаю вывод, что мы говорим о разных вещах.

Я говорю про "состояние" пользователя, системы, и сервис авторизации. Например, уникальный временный идентификатор платежа пользователя, на который завязана бронь авиа или жд билетов. Потеря этих идентификаторов или остановка системы бронирования стоит очень дорого. Они должны храниться в специальном микросервисе с failover.
Я не про session_start() и не про выбор хранилища, я про данные сессии.
 
Последнее редактирование:
Можно обойтись без микросервисов и прочих докеров ;)

А так да.
 
Сверху