LINUX.ORG.RU
ФорумAdmin

mysql: master-slave репликация. что делать с лагом?

 ,


0

2

Добрый вечер. Настроил на облаке репликацию MySQL master-slave с балансировкой с помощью proxySQL: proxysql проксирует все insertы и updatы на master, а селекты на слэйвы. Проблема такая: даже при незначительном временном лаге (до 1 сек) пользователи часто сталкиваются с тем, что при авторизации (сессии modx хранит в бд) обновление сессии не успевает долететь до слэйва и юзер снова попадает на логин, или если он постит коммент, то коммент не отображается. Крч, хотелось бы добиться хоть какой-то синхронности. Пока планирую перенести сессии на отдельный сервер, без репликации, но всех проблем это не снимет.

mysql 5.7.19

А без хранения сессий на сервере modx не умеет? Мне кажется хранить сессионную инфу в куках (с подписью) как-то аккуратнее.
В mysql/mariadb есть какой-то вариант синхронной репликации, погугли.
Если перенести балансировку туда где известно к какой сессии относится запрос то можно какое-то время после записи в БД перенаправлять все запросы этой сессии на мастер

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Без хранения в бд modx нативно не умеет, можно написать свой обработчик, но беда в том, что php-узлов тоже несколько, соответственно, сессии между ними можно расшарить только через nfs, но он не умеет в блокировки, с memcached и redis такая же беда. видел решения блокировок для редис - но они все не очень, со своими проблемами.

С синхронной репликацией - говорят, не очень хорошо, но информация поточнее помогла бы, может у кого есть опыт реальный.

Про перенос балансировки - у хостера есть ограничения на установку стороннего по. так что юзать proxysql я могу только в пределах докера

JIesnik
() автор топика
Ответ на: комментарий от JIesnik

Зачем nfs? Зачем редиска? Я же говорю, хранить сессионные данные можно тупо на клиенте хранить в подписанном виде.
Грубо говоря кука содержит всю нужную инфу (идентификатор пользователя и что там ещё надо) и sha хэш от этой инфы + секрет известного только серверу (просто рандомная строка). Сервер получает куку, считает хэш от данных+секрет, сравнивает с хэшем из куки, если сходится значит данным из куки можно доверять.
Это очень огрублённое описание. Гугли HMAC и всё вокруг этого. готовая реализация вроде в WP работает

Синхронную репликацию не тестировал, но по слухам она работоспособна. Конечно должна тормозить запись, это бай дизайн

Балансировку предполагается перенести в код сайта. Т.е. вместо константы с адресом mysql сервера будет (условно) переменная с адресом содержимое которой зависит от того была-ли запись в базу в этой сессии за последние n секунд

MrClon ★★★★★
()

Для сессий (если очень хочется их в БД хранить) придётся делать синхронную репликацию. См. Galera cluster.

AlexAT
()
Ответ на: комментарий от MrClon

хранить сессионную инфу в куках (с подписью) как-то аккуратнее.

И когда пользователь захочет поменять свой пароль (потому, что старый куда-то утёк) и разлогинить все сессии — он физически не сможет этого сделать. Потому, что все старые куки останутся валидными и подписанными.

Информация о сессиях должна быть ровно на одном сервере. Не на репликах (если только при создании сессии пользователь не ждёт, пока сессия окажется на ВСЕХ репликах, а не только на мастере).

x3al ★★★★★
()
Ответ на: комментарий от x3al

На самом деле не совсем так: можно при «разлогинить всех» или смене пароля менять и ключ подписи cookie для пользователя.

AlexAT
()
Ответ на: комментарий от AlexAT

менять и ключ подписи cookie для пользователя.

То есть на каждой реплике должен быть актуальный ключ подписи cookie для каждого пользователя?

Поздравляю! Ты изобрёл хранение сессий в БД, только хуже!

x3al ★★★★★
()
Ответ на: комментарий от x3al

Даже в гугле, вродь 6-8-ми символьные данные, и чего, там может тормозить? Мне кажется порезать (в смысл. сократить) куки и на железе ИР поставить по значению ~ равным 4000, я думаю ход мысли такой.?

anonymous
()
Ответ на: комментарий от x3al

Ещё одно поле в таблице с пользователями, обновляется в среднем раз в никогда. Чем это хуже синхронизации всех сессий?

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Чем оно лучше синхронизации всех сессий? Тебе по-прежнему нужно централизованное хранилище сессий, с которым проблема в ОП-посте.

В наивном виде (как предложено: подписанные/шифрованные куки) ещё и уйма лишнего трафика и 0 преимуществ.

В одно поле в таблице можно и всю сессию в, скажем, JSON запихнуть.

x3al ★★★★★
()

хотелось бы добиться хоть какой-то синхронности.

Обычно такую проблему решают, направляя одного юзера через load balancer всегда на один сервер. Например, по хешу IP.

KRoN73 ★★★★★
()

снять бампера и вложить между ними новую машину. в том смысле, что сессии в реплицируемой базе хранить - это боль в любом случае, хоть репликация синхронная (больно в базе) либо асинхронаая (больно в приложении)

либо отказаться от репликации хотя бы сессий, либо хранить сессиии в памяти как нормальные люди и не париться с их сохранностью

anonymous
()
Ответ на: комментарий от x3al

В любом случае нужно синхронизировать таблицу с пользователями, так? Ну хотя-бы что-бы на страницах выводить «бобро пожаловать, $username». В этой таблице допустим логин, пароль и всякая лабуда вроде даты рождения. Всё это обычно обновляется редко, реже чем сессии. Что мешает добавить в эту таблицу ещё одну колонку с ключом для подписи кук? Изменяется он только при необходимости дропнуть все сессии, что бывает редко. Проблемы из-за задержки синхронизации будут возникать только при дропе сессий. В таких случаях можно покрутить перед пользователем спинером пару секунд со словами «подождите, удаляем сессии».
Централизовано хранить ничего не нужно, достаточно более-мене оперативно синхронизировать маленькие и редко меняющиеся данные

На счёт трафика… ты сайты современные видел? Это что-же нужно пихать в сессию что-бы сравниться с ЭТИМ?

MrClon ★★★★★
()

Мы для этого делали так: после update/insert брали master pos из show slave status а затем на слейве вызывали MASTER_POS_WAIT() с нужной позицией, и только после этого отдавали юзеру страницу

anonymous7
()
Ответ на: комментарий от x3al

Ну да, только не смотря на жесткое кэширование всей статики и тотальный аякс во имя не-передачи избыточного html они всё-равно умудряются весить весьма немало, а uid + hash это (минимальный вариант достаточный в большинстве случаев) это сотня-другая байт (если использовать жирный хэш)

И ты так и не объяснил откуда по твоему в описанной мной схеме взялась необходимость в централизованном хранилище

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

uid + hash это (минимальный вариант достаточный в большинстве случаев)

Вот это — классическая сессия. А вариант «вся сессия целиком в куках, а в базе один ключ для подписи», который предложили — хуже.

необходимость в централизованном хранилище

Так в нём и будут ключи для подписи. Если тебе проще, то назовём его CP-хранилищем.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Забыл про id сессии, сутки без сна, котелок туго варит. Т.е. если к userid и подписи добавить sessionid (рандомная строка) то всё резко станет ужасно и реплицируемая/партиционированная/какаяугодно база данных резко превратится в централизованное хранилище CP?
Чего ты там такого монструозного в сессии обычно хранишь?

MrClon ★★★★★
()
Ответ на: комментарий от x3al

Не совсем. При этом в БД вообще ничего не хранится, кроме ID сессии, пользователя и ключа. Всё остальное - в клиенте, подписанными кусочками, которые запрашиваются «по требованию».

AlexAT
()
Ответ на: комментарий от AlexAT

Зачем? Если мы можем хранить в БД ID/пользователя/ключа, мы можем с тем же успехом хранить там всю сессию, а ID перетащить на клиента. Это лучше, особенно когда захочется глобально отрефакторить что-нибудь в сессиях.

x3al ★★★★★
()
Ответ на: комментарий от x3al

А, тут больше вопрос того, чего надо похранить и как. Если нужен перзист между браузерами и локациями юзера - да, лучше хранить у себя. Если нужны +/- большие объемы данных, требующиеся мелкими порциями, и можно их похранить в браузере - лучше похранить в браузере. Иногда гибридный вариант, активное хранение данных для локального юзерского JS на клиенте, а обновляемая копия - на сервере.

AlexAT
()
Ответ на: комментарий от AlexAT

Удобство в том, что если данные уже похранены на клиенте, то не надо их заново с сервера выбирать и тащить. Кэш локальный, короче.

AlexAT
()
Ответ на: комментарий от x3al

Ну и прелесть хранения на сервере только ключа в том, что репликация реально может отставать - мы же не держим никаких данных, и ключ не меняем долго. Другое дело, что не всегда удаётся это реализовать без существенных потерь в удобстве.

AlexAT
()
Ответ на: комментарий от x3al

Ключ обновляется гораздо реже - только при форсированных логаутах и сменах пароля, вот в чём соль.

AlexAT
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.