Можно ли использовать пул демонов memcache для более эффективного совместного использования сеансов?
Мы переходим от установки 1 веб-сервера к установке с двумя веб-серверами, и мне нужно начать совместное использование сеансов PHP между двумя компьютерами с балансировкой нагрузки. Мы уже установили (и запустили) http://memcached.org/, и поэтому я был приятно удивлен, что смог выполнить совместное использование сеансов между новыми серверами, изменив только 3 строки в php.ini
файл ( session.save_handler и session.save_path):
Я заменил:
session.save_handler = files
с:
session.save_handler = memcache
Затем на главном веб-сервере я установил session.save_path
указать на localhost:
session.save_path="tcp://localhost:11211"
и на подчиненном веб-сервере я установил session.save_path
указать на мастера:
session.save_path="tcp://192.168.0.1:11211"
Работа выполнена, я проверил, и это работает. Но...
Очевидно, что использование memcache означает, что сеансы находятся в оперативной памяти и будут потеряны в случае перезагрузки компьютера или сбоя демона memcache - меня это немного беспокоит, но меня больше беспокоит сетевой трафик между двумя веб-серверами (особенно в связи с тем, что мы увеличиваем масштаб), потому что всякий раз, когда кто-то балансирует нагрузку на подчиненный веб-сервер, его сеансы будут передаваться по сети с главного веб-сервера. Мне было интересно, смогу ли я определить два save_paths
поэтому машины смотрят в свое собственное хранилище сеансов перед использованием сети. Например:
Мастер:
session.save_path="tcp://localhost:11211, tcp://192.168.0.2:11211"
Подчиненный:
session.save_path="tcp://localhost:11211, tcp://192.168.0.1:11211"
Будет ли это успешно разделить сеансы на серверах и помочь производительности? т.е. сэкономить сетевой трафик 50% времени. Или эта техника предназначена только для отработки отказа (например, когда один демон memcache недоступен)?
Примечание: я на самом деле не спрашиваю конкретно о репликации memcache - подробнее о том, может ли PHP-клиент memcache работать с пиками внутри каждого демона memcache в пуле, возвращать сеанс, если он находит один, и создавать новый сеанс, только если он не находит его. во всех магазинах. Когда я пишу это, я думаю, что немного спрашиваю из PHP, лол...
Предположим: нет липких сессий, циклическое распределение нагрузки, серверы LAMP.
5 ответов
Отказ от ответственности: Вы были бы сумасшедшими, если бы выслушали меня, не проводя тонны тестирования и не получив второго мнения от кого-то квалифицированного.
Идея повышения эффективности, предложенная в этом вопросе, не сработает. Главная ошибка, которую я сделал, заключалась в том, что порядок, в котором хранилища memcached определены в пуле, диктует какой-то приоритет.Это не тот случай. Когда вы определяете пул memached демонов (например, используя session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"
Вы не можете знать, какой магазин будет использоваться. Данные распределяются равномерно, это означает, что элемент может быть сохранен в первом, или это может быть последним (или это может быть и то и другое, если клиент memcache настроен для репликации - обратите внимание, что это клиент, который обрабатывает репликацию, сервер memcached делает не делай сам) В любом случае это означает, что использование localhost в качестве первого в пуле не приведет к повышению производительности - 50% -ный шанс попасть в любой магазин.
Проведя небольшое тестирование и исследования, я пришел к выводу, что вы МОЖЕТЕ делиться сессиями между серверами, используя memcache, НО вы, вероятно, этого не хотите - он, кажется, не популярен, потому что он не масштабируется, а использует общий База данных у него не такая надежная. Буду признателен за отзыв, чтобы узнать больше...
Если у вас нет приложения PHP, игнорируйте следующее:
Совет 1: если вы хотите поделиться сессиями между 2 серверами, используя memcache:
Убедитесь, что вы ответили "Да" на " Включить поддержку обработчика сессии memcache? ", Когда вы установили PHP-клиент memcache и добавили следующее в/etc/php.d/memcache.ini
файл:
session.save_handler = memcache
На веб-сервере 1 (IP: 192.168.0.1):
session.save_path="tcp://192.168.0.1:11211"
На веб-сервере 2 (IP: 192.168.0.2):
session.save_path="tcp://192.168.0.1:11211"
Совет 2: Если вы хотите совместно использовать сеансы на 2 серверах, используя memcache И иметь поддержку отработки отказа:
Добавьте следующее к вашему/etc/php.d/memcache.ini
файл:
memcache.hash_strategy = consistent
memcache.allow_failover = 1
На веб-сервере 1 (IP: 192.168.0.1):
session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"
На веб-сервере 2 (IP: 192.168.0.2):
session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"
Заметки:
- Это подчеркивает еще одну ошибку, которую я сделал в первоначальном вопросе - я не использовал идентичный
session.save_path
на всех серверах. - В этом случае "failover" означает, что в случае сбоя одного демона memcache клиент PHP memcache начнет использовать другой. т.е. любой, у кого был сеанс в магазине, который потерпел неудачу, выйдет из системы. Это не прозрачное аварийное переключение.
Совет 3: Если вы хотите поделиться сеансами, используя memcache И иметь прозрачную поддержку отработки отказа:
То же, что и совет 2, за исключением того, что вам нужно добавить следующее в ваш/etc/php.d/memcache.ini
файл:
memcache.session_redundancy=2
Заметки:
- Это заставляет PHP-клиент memcache записывать сессии на 2 сервера. Вы получаете избыточность (например, RAID-1), так что записи отправляются на n зеркал, и сбой
get's
повторяются на зеркалах. Это будет означать, что пользователи не теряют свою сессию в случае сбоя одного демона memcache. - Зеркальные записи выполняются параллельно (с использованием неблокирующего ввода-вывода), поэтому быстродействие не должно сильно снижаться при увеличении количества зеркал. Однако сетевой трафик увеличится, если ваши зеркала memcache будут распределены по разным машинам. Например, больше нет 50% шансов использовать localhost и избежать доступа к сети.
- По-видимому, задержка репликации записи может привести к тому, что старые данные будут извлечены вместо пропуска кэша. Вопрос в том, имеет ли это значение для вашего приложения? Как часто вы пишете данные сессии?
memcache.session_redundancy
для резервирования сеанса, но есть такжеmemcache.redundancy
Параметр ini, который может использоваться вашим кодом PHP-приложения, если вы хотите, чтобы он имел другой уровень избыточности.- Вам нужна последняя версия (пока ещев бета-версии) клиента memcache PHP - у меня работала версия 3.0.3 от pecl.
Re: Совет 3 выше (для всех, кто сталкивался с этим через Google), кажется, что по крайней мере в настоящее время, чтобы это работало, вы должны использовать memcache.session_redundancy = N+1
для N серверов в вашем пуле, по крайней мере, это минимальное пороговое значение, которое работает. (Протестировано с php 5.3.3 на стабильной версии Debian, pecl memcache 3.0.6, два сервера memcached. session_redundancy=2
потерпит неудачу, как только я выключу первый сервер в save_path
, session_redundancy=3
работает отлично.)
Кажется, это зафиксировано в следующих отчетах об ошибках:
Наряду с настройками php.ini, показанными выше, убедитесь, что установлены следующие параметры:
memcache.allow_failover = 1
memcache.hash_strategy = 'consistent'
Тогда вы получите полное аварийное переключение и избыточность на стороне клиента. Предостережение при таком подходе заключается в том, что если memcached отключен на локальном хосте, то всегда будет пропущено чтение, прежде чем клиент php memcache попробует следующий сервер в пуле, указанном в session.save_path.
Помните, что это влияет на глобальные настройки клиента php memcache, работающего на вашем веб-сервере.
memcached не работает таким образом (поправьте меня, если я ошибаюсь!)
Если вы хотите, чтобы у вашего приложения было избыточное хранилище сеансов, вы должны создать что-то, что изменяет / добавляет / удаляет записи в обоих экземплярах memcached. memcached не справляется с этим, единственное, что он предоставляет, это хранилище ключей. Так что без репликации, синхронизации ничего, нада.
Надеюсь, я не ошибаюсь в этом вопросе, но это то, что я знаю о memcached, прошло несколько лет с тех пор, как я его коснулся.
memcached не реплицируется из коробки, но repcached (пропатченный memcached) делает. Однако, если вы уже используете mysql, то почему бы просто не использовать его функции репликации с репликацией master-master и получить преимущество полной репликации данных.
C.