Web

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

Мы переходим от установки одного веб-сервера к установке двух веб-серверов, и мне нужно начать разделять сессии PHP между двумя машинами с балансировкой нагрузки. У нас уже установлен (и запущен) memcached, поэтому я был приятно удивлен тем, что могу разделить сессии между новыми серверами, изменив всего 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.

Предполагается: балансировка нагрузки по принципу round-robin, LAMP-серверы.

Ответ 1

Идея повышения эффективности, предложенная в этом вопросе, не сработает. Основная ошибка, которую я совершил, заключалась в том, что я думал, что порядок, в котором хранилища 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"

Примечания:

  1. Этот код подчеркивает другую ошибку, которую я допустил в первоначальном вопросе я не использовал идентичный session.save_path на всех серверах.

  2. В данном случае «обход отказа» означает, что если один демон memcache выйдет из строя, клиент PHP memcache начнет использовать другой. Т.е. все, кто хранил свою сессию в хранилище, которое вышло из строя, будут выведены из системы. Это не прозрачно, для обхода отказа.

Совет 3: Если вы хотите разделять сессии с помощью memcache и иметь поддержку прозрачного обхода отказа

То же самое, что и совет 2, за исключением того, что вам нужно добавить следующее в файл /etc/php.d/memcache.ini:

memcache.session_redundancy=2

Примечания:

  1. Этот код заставляет клиента PHP memcache записывать сессии на 2 сервера. Вы получаете избыточность (подобно RAID-1), так что записи отправляются на n зеркал, а неудачные get'ы повторяются на зеркалах. Это означает, что пользователи не потеряют свои сессии в случае сбоя одного демона memcache.

  2. Запись на зеркала выполняется параллельно (с использованием неблокирующего интерфейса), поэтому скорость работы не должна сильно снижаться при увеличении числа зеркал. Однако сетевой трафик увеличится, если ваши зеркала memcache распределены по разным машинам. Например, больше не существует 50% вероятности использования localhost и избегания доступа к сети.

  3. Очевидно, что задержка при репликации записи может привести к тому, что вместо промаха кэша будут получены старые данные. Вопрос в том, имеет ли это значение для вашего приложения? Как часто вы записываете данные сессии?

  4. memcache.session_redundancy предназначен для резервирования сессий, но есть также опция memcache.redundancy ini, которая может быть использована кодом вашего PHP-приложения, если вы хотите, чтобы оно имело другой уровень резервирования.

  5. Вам нужна последняя версия клиента PHP memcache версия 3.0.3 от pecl сработала для меня.

Ответ 2

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

memcache.allow_failover = 1  

memcache.hash_strategy = 'consistent'.

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

Имейте в виду, что это влияет на глобальные настройки клиента php memcache, запущенного на вашем веб-сервере.

Ответ 3

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

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

Ответ 4

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

Схожие статьи

Cloudflare: как подключить и настроить сертификат SSL. Подробный гайд
Web

Cloudflare: как подключить и настроить сертификат SSL. Подробный гайд

Web

Проблемы при использовании $_REQUEST[]

Mobile First индекс Google: все о последнем тренде SEO-оптимизации
Web

Mobile First индекс Google: все о последнем тренде SEO-оптимизации

Web

Как выполнить запрос «INSERT IF NOT EXIST» в MySQL?