Можно ли использовать пул демонов memcache для более эффективного совместного использования сеансов?

25

Мы переходим от установки 1 веб-сервера к установке с двумя веб-серверами, и мне нужно начать совместное использование сеансов PHP между двумя компьютерами с балансировкой нагрузки. Мы уже установили ( и запустили ) memcached, и поэтому я был приятно удивлен, что смог выполнить совместное использование сеансов между новыми серверами, изменив только 3 строки в файле ( session.save_handler и session.save_path ):php.ini

Я заменил:

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.

Том
источник
1
В документации Memcache не рекомендуется использовать Memcache для хранения сеансов. Смотрите code.google.com/p/memcached/wiki/… !

Ответы:

37

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

Идея повышения эффективности, предложенная в этом вопросе, не сработает. Главная ошибка, которую я сделал, заключалась в том, что порядок, в котором хранилища 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 .
Том
источник
Не могли бы вы прокомментировать «он не масштабируется так же хорошо, как использование общей базы данных»? Я не вижу, как это отличается от типичной установки БД-подчиненный. Благодарность!
Мальчик Баукема
Это довольно крутая разбивка, хотя ходят слухи (или сообщения об ошибках), что это работает не так, как ожидалось, когда вы используете ext/memcacheверсию 3.x. Мы также играем с этой опцией, и я решил просмотреть список серверов и написать ему сам.
до
в случае совета 3: что если один из хостов memcached выйдет из строя, а затем включится, то секундный хост выйдет из строя. как я понимаю - никакие данные сеанса не будут восстановлены и некоторые из них будут потеряны, верно?
GioMac
28

Re: Совет 3 выше (для всех, кто сталкивался с этим через Google), кажется, что, по крайней мере, в настоящее время, чтобы это работало, вы должны использовать memcache.session_redundancy = N+1N серверов в вашем пуле , по крайней мере, это минимальный порог ценность, которая работает. (Протестировано с php 5.3.3 на стабильном Debian, pecl memcache 3.0.6, два сервера memcached. Сбой, session_redundancy=2как только я выключу первый сервер в save_path, session_redundancy=3работает нормально.)

Кажется, это зафиксировано в следующих отчетах об ошибках:

Майкл Джексон
источник
1
Не могу upvote вам достаточно ..
фест
1
Я рад, что прокрутил вниз. Это была проблема.
Дарен Швенке
Мне не ясно, доступна ли эта функция только в серии PECL memcache 3.x? Все они перечислены в бета-версии программного обеспечения на pecl.php.net/package/memcache , тогда как на 2.2.7, если я убью сервер, на котором я вижу лидера, все умрет.
Джо
Прошло много лет с тех пор, как я посмотрел на это, если честно. Насколько я помню, это была функция 3.x (icbw). Мы развернули много систем, используя «бета» версии этого плагина (у некоторых из них довольно высокий трафик), и у нас не было проблем, связанных с этим. YMMV, тестируй вещи до того, как они появятся, и т. Д. :) Я не работаю в PHP уже несколько лет, поэтому некоторые тонкости мелочей начинают исчезать.
Майкл Джексон
3

Наряду с настройками php.ini, показанными выше, убедитесь, что установлены следующие параметры:

memcache.allow_failover = 1  
memcache.hash_strategy = 'consistent'

Тогда вы получите полное аварийное переключение и избыточность на стороне клиента. Предостережение при таком подходе заключается в том, что если memcached отключен на локальном хосте, то всегда будет пропущено чтение, прежде чем клиент php memcache попробует следующий сервер в пуле, указанном в session.save_path.

Помните, что это влияет на глобальные настройки клиента php memcache, работающего на вашем веб-сервере.

Ян Льюис
источник
Имеет ли consistentсмысл использовать стратегию хеширования, учитывая, что session.save_pathона отличается на каждом веб-сервере?
Том
1

memcached не работает таким образом (поправьте меня, если я ошибаюсь!)

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

Надеюсь, я не ошибаюсь в этом вопросе, но это то, что я знаю о memcached, прошло несколько лет с тех пор, как я его коснулся.

tore-
источник
Мне было бы удобно, если бы ты ошибался. :-) В phpslacker.com есть статья ( phpslacker.com/2009/03/02/php-session-clustering-with-memcache ), в которой говорится, что memcached может работать, как описано в вопросе. Возможно, это зависит от того, как клиент memcache реализует стратегию хеширования?
Том
1
memcache работает не так, но кажется, что php может работать так, как вы этого хотите. Вам придется изменить php.ini или изменить приложение, как описано. Из блога: Где кластеризация, которую вы спрашиваете? Ну, по правде говоря, их нет. Пока у нас есть пул memcache, состоящий из 2 серверов. PHP настроен на запись в пул. PHP читает / записывает в пул серверов в порядке, указанном в директиве «session.save_path». Для чтения PHP запросит объект кэша по ключу из пула. Поскольку функция аварийного переключения включена, PHP будет запрашивать пул серверов memcache один за другим до [...]
2010 г.
1

memcached не реплицируется из коробки, но repcached (пропатченный memcached) делает. Однако, если вы уже используете mysql, то почему бы просто не использовать его функции репликации с репликацией master-master и получить преимущество полной репликации данных.

C.

symcbean
источник
Спасибо за информацию. Это не совсем репликация, которую я ищу. Это скорее случай, когда нужно по очереди подключиться к каждому memcached, пока не будет найден сеанс. то есть сначала проверять localhost, потому что он самый быстрый, а затем проверять другой сервер.
Том
1
Во имя всех богов, ПОЧЕМУ ???? Это абсолютно неправильное решение ... ну, примерно, любая проблема, о которой я могу подумать. В дополнение к тому, что он очень неэффективен даже с двумя серверами, производительность очень быстро ухудшается, если вы добавите больше серверов. И это не принимая во внимание тот факт, что ваше решение вызывает сбои в два раза чаще, чем с одним сервером, когда на практике добавление серверов в кластер должно снизить вероятность сбоя. (Кстати, если вы имеете в виду циклический
перебор на
Спасибо за отзыв, да, я свободно признаюсь, что я нуб на сессии обмена! :-) Однако я до сих пор не понял, почему мое предложение так безобразно. Я думал, что это будет более эффективно, чем использование совместно используемой БД, и я также думал, что это приведет к снижению вероятности простоев.
Том
Нет, это делает их более вероятными. Подобное объединение данных имеет смысл, когда у вас очень большое количество узлов, потому что вы уменьшаете объем репликации, но обычно требуется выполнить некоторую репликацию с определенным количеством пулов, чтобы сохранить доступность. Вам нужно быть очень требовательным к производительности, чтобы увидеть разницу между реплицированной репликацией и репликацией mysqld.
Symcbean
Я проверил и подтвердил, что, пока я использую allow_failover = 1, несколько зеркал действительно делают сбои МЕНЬШЕ вероятными. Я могу выключить одно зеркало, перезапустить его и выключить другое, перезапустить и снова отключить первое - и все без выхода из системы. Я думаю, что PHP-клиент memcache делает много хитрости за кулисами.
Том