Назад | Перейти на главную страницу

Хранилище сеансов PHP в отказоустойчивом пуле Memcached

Недавно у меня была возможность переместить веб-приложение с прокси-сервера Nginx "loadbalancer" на loadbalancer F5. К сожалению, во время этой миграции стало ясно, что memcached хранилище сессий, необходимое для перемещения с прокси-сервера Nginx "куда-нибудь". Я думаю, что я должен положить memcached на всех 3 веб-серверах (серверы, которые находятся за F5 в пуле) и используют php-memcache или php-memcached для сохранения сессий. Вот в чем проблема:

Я пробовал оба php-memcache и php-memcached и ни один из них не может вести себя должным образом, если один из серверов выходит из строя. Моя последняя попытка была с такой конфигурацией:

memcached версия 2.2.0 с настройками конфигурации:

session.save_handler = memcached
session.save_path    = "172.29.104.13:11211,172.29.104.14:11211"

У меня нет ничего особенного в memcached.ini Кроме как extension=memcached.so.

С этой конфигурацией на сервере 1 и 2 (я временно удалил 3 для тестирования), я указываю JMeter на F5 VIP и начинаю трафик. я могу видеть memcached.log (демон) в обеих системах, хотя и не потратил времени на расшифровку, запустить.

Тогда, если я остановлю одну из memcached демоны, трафик начинает падать, и мой возврат

session_start(): Write of lock failed

посредством memcached что осталось.

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

Я также пробовал php-memcache но он тоже терпит неудачу. Для php-memcache конфигурация выглядит так:

memcache версия 3.0.8 (бета) с настройками конфигурации:

 
session.save_handler = memcache
session.save_path    = "tcp://172.29.104.13:11211, tcp://172.29.104.14:11211"

И в memcache.ini:

extension=memcache.so
[memcache]
memcache.dbpath="/var/lib/memcache"
memcache.maxreclevel=0
memcache.maxfiles=0
memcache.archivememlim=0
memcache.maxfilesize=0
memcache.maxratio=0
memcache.hash_strategy=consistent
memcache.allow_failover=1
memcache.session_redundancy=2

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

Я не рассматривал возможность возврата сохраняемости сеанса на F5, хотя в крайнем случае я мог бы это сделать, и клиентам, пытающимся подключиться к потерянному члену, придется повторно аутентифицироваться.

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

Видеть https://github.com/ascorbic/php-stateless-cookies для одной реализации существует множество других. Обратите внимание, что данные сеанса должны быть зашифрованы, но должен пройти аутентификацию через HMAC или шифр AEAD. Не пишите этот код самостоятельно, если вы не криптограф; используйте проверенную криотеку.

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