Чи може пул демонів пам’яті використовуватись для більш ефективного обміну сеансами?


25

Ми переходимо від налаштування 1 веб-сервера до двох налаштувань веб-сервера, і мені потрібно почати обмін сеансами 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 означає, що сеанси знаходяться в оперативній пам’яті і будуть втрачені, якщо машина перезавантажиться або демон демонструє збій - мене це мало хвилює, але мене трохи більше турбує мережевий трафік між двома веб-серверами (особливо ми збільшуємо масштаб), тому що коли хтось буде завантажений збалансованим для підлеглого веб-сервера, їх сеанси будуть передаватися через мережу від головного веб-сервера. Мені було цікаво, чи можу я визначити два, 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 в пулі, повернути сеанс, якщо він знайде його, і створити лише новий сеанс, якщо він не знайде у всіх магазинах. Коли я пишу це, я думаю, що я прошу трохи від PHP, хаха ...

Припустимо : відсутність липких сеансів, балансування навантаження на кругових роботах, LAMP-сервери.


1
Документація Memcache не рекомендує використовувати Memcache для зберігання сеансу. Дивіться code.google.com/p/memcached/wiki/… !

Відповіді:


37

Відмова від відповідальності: Ви б з глузду слухали мене, не роблячи тонни тестування І не отримуючи другу думку від кваліфікованого - я новачок у цій грі .

Ідея підвищення ефективності, запропонована в цьому питанні, не спрацює. Основна помилка, яку я зробив, - це думати, що порядок визначення визначених магазинів у пулі диктує певний пріоритет. Це не так . Коли ви визначаєте пул згаданих демонів (наприклад, використовуючи session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"), ви не можете знати, який магазин буде використовуватися. Дані розподіляються рівномірно, це означає, що елемент може бути збережений у першому, або він може бути останнім (або це може бути і те, і інше, якщо клієнт-мемошам налаштований для реплікації - зауважте, що клієнт обробляє реплікацію не робити це самостійно). Так чи інакше, це означає, що використання localhost як першого в пулі не покращить продуктивність - є 50% шансів потрапити в будь-який магазин.

Зробивши трохи тестування та дослідження, я прийшов до висновку, що ви МОЖЕ обмінюватися сеансами на серверах за допомогою memcache, Але ви, мабуть, цього не хочете - це, здається, не користується популярністю, оскільки воно не масштабує, а також використовує спільне використання база даних у неї не така надійна. Буду вдячний відгуками про це, щоб я міг дізнатися більше ...

Ігноруйте наступне, якщо у вас немає програми PHP:


Порада 1: Якщо ви хочете поділитися сеансами на двох серверах, використовуючи мемаш:

Переконайтесь, що ви відповіли " Так" на " Увімкнути підтримку обробника сеансу memcache? ", Коли ви встановили клієнт пам'яті PHP і додайте у /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: Якщо ви хочете ділитися сеансами на двох серверах, використовуючи memcache AND, маєте підтримку відмови:

Додайте у /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на всіх серверах.
  • У цьому випадку "аварійний перемикач" означає, що у випадку невдачі одного демона пам'яті, клієнт пам'яті PHP почне використовувати інший. тобто кожен, хто провів сеанс в магазині, який не вдався, вийде з системи. Це не прозора відмова.

Порада 3: Якщо ви хочете ділитися сеансами, використовуючи memcache AND, мати прозору підтримку відмови:

Те саме, що підказка 2, за винятком того, що вам потрібно додати у /etc/php.d/memcache.iniфайл наступне :

memcache.session_redundancy=2

Примітки:

  • Це змушує клієнта PHP-пам'яті записувати сеанси на 2 сервери. Ви отримуєте надмірність (як RAID-1), так що записи надсилаються до n дзеркал, а get'sпомилки - повторюються на дзеркалах. Це буде означати, що користувачі не втрачають сеанс у разі відмови демона пам'яті.
  • Зеркальні записи виконуються паралельно (використовуючи не блокуючий-IO), тому швидкість роботи не повинна значно знижуватися, оскільки кількість дзеркал збільшується. Однак мережевий трафік збільшиться, якщо ваші дзеркала-мембрани будуть розповсюджені на різних машинах. Наприклад, більше немає 50% шансів використовувати localhost та уникати доступу до мережі.
    • Мабуть, затримка реплікації запису може призвести до отримання старих даних замість пропуску кешу. Питання в тому, чи це стосується вашої заявки? Як часто ви пишете дані сеансу?
  • memcache.session_redundancyпризначений для надмірності сеансу, але є також memcache.redundancyваріант ini, який може використовуватися вашим кодом програми PHP, якщо ви хочете, щоб він мав інший рівень надмірності.
  • Вам потрібна остання версія (все ще знаходиться в бета-версії ) клієнта PHP memcache - для мене працювала версія 3.0.3 від pecl .

Чи можете ви прокоментувати "він не масштабується, а також використовує спільну базу даних"? Я не бачу, чим вона відрізняється від типової установки БД-ведучого. Спасибі!
Хлопчик Баукема

Це досить класна поломка, хоча ходять чутки (ака-звіти про помилки), що це не працює так, як очікувалося, коли ви використовуєте ext/memcacheверсію 3.x. Ми також граємо з цим варіантом, і я вирішив переглянути список серверів і написати йому сам.
До

у разі підказки 3: що робити, якщо один зведений хост знизиться, а потім він з'явиться, то секунда хоста знизиться. наскільки я розумію - дані сеансу не будуть відновлені, а частина з них буде втрачена, правда?
GioMac

28

Відповідь: Порада 3 вище (для всіх, хто трапляється зіткнутися з цим через Google), здається, що принаймні зараз для того, щоб це працювало, ви повинні використовувати memcache.session_redundancy = N+1для N серверів у вашому пулі , принаймні, це здається, що це мінімальний поріг значення, яке працює. (Тестовано на php 5.3.3 на стабільній системі debian, pecl memcache 3.0.6, двох серверах, що запам'ятовуються. Не session_redundancy=2вдалося б, як тільки я вимкнув перший сервер у save_path, session_redundancy=3працює нормально.)

Схоже, це відображено в цих звітах про помилки:


1
Не можу вас достатньо підняти ..
fest

1
Я радий, що прокрутився вниз. У цьому і була проблема.
Дарен Швенке

Мені не зрозуміло, чи доступна ця функція лише у пам’яті PECL 3.x? Все це перераховано у програмі Beta на 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 не працює на localhost, завжди буде пропущено читання, перш ніж клієнт php memcache спробує наступний сервер у пулі, вказаний у session.save_path

Просто майте на увазі, що це впливає на глобальні налаштування клієнта php memcache, який працює на вашому веб-сервері.


Чи consistentмає сенс використання стратегії хешування, враховуючи, що session.save_pathрізниця на кожному веб-сервері?
Том

1

memcached не працює таким чином (будь ласка, виправте мене, якщо я помиляюся!)

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

Я сподіваюсь, що я не помиляюся з цього приводу, але це те, що я знаю, що я запам'ятав, пройшло кілька років, як я торкнувся його.


Для мене було б корисно, якби ви помилялися. :-) На phpslacker.com ( phpslacker.com/2009/03/02/php-session-clustering-with-memcache ) є стаття, в якій висловлено припущення, що складені файли можуть працювати як описано в питанні. Можливо, це залежить від того, як клієнт memcache реалізує стратегію хешування?
Том

1
memcache не працює так, але здається, що php може працювати так, як ви хочете. Вам доведеться змінити php.ini або змінити додаток, як описано. З блогу: Де кластеризація, яку ви запитуєте? Ну, правдиво сказати, немає. На сьогодні у нас є пул memcache, що складається з 2 серверів. PHP налаштований для запису в пул. PHP читає / записує в пул серверів у порядку, визначеному директивою "session.save_path" ini. Для читань PHP запитує кеш-об’єкт за ключем від пулу. Оскільки увімкнено функцію "відмова", PHP запитуватиме пул серверів пам’яті один за одним до [...]
зірвано

1

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

C.


Дякуємо за інформацію. Це насправді не тиражування. Це більше випадків, коли ви хочете ввійти в кожен запам'ятований по черзі, поки сеанс не буде знайдений. тобто перевірка localhost спочатку, тому що це найшвидше, а потім наступна перевірка іншого сервера.
Том

1
В ім'я всіх богів ЧОМУ ???? Це абсолютно неправильне рішення .... ну майже про будь-яку проблему, про яку я можу придумати. Окрім того, що дуже неефективно, навіть за допомогою двох серверів продуктивність буде дуже швидко погіршуватися, якщо ви коли-небудь додасте більше серверів. І це не враховуючи той факт, що ваше рішення робить відключення вдвічі більші, ніж вони були на одному сервері, коли на практиці додавання серверів до кластеру повинно зменшити ймовірність відключення. (BTW, якщо ви маєте на увазі DNS-круглий робін, то спорідненість сесії неявна!)
symcbean

Дякую за відгук, так, я вільно визнаю, що я нобіль на спільному сеансі! :-) Однак я досі не зрозумів, чому моя пропозиція така негарна. Я думав, що це буде більш ефективно, ніж використання спільного БД, і я також подумав, що це зробить відключення менш імовірними.
Том

Ні, це робить їх більш імовірними. З'єднувати подібні дані має сенс, коли у вас дуже велика кількість вузлів, оскільки ви зменшуєте кількість реплікацій, але, як правило, можна виконати певну реплікацію із визначеною кількістю пулів, щоб зберегти доступність. Вам потрібно бути дуже прискіпливим щодо продуктивності, щоб побачити різницю між реплікаційною реплікацією та реплікацією mysqld.
symcbean

Я перевірив і підтвердив, що доки я використовую дозволений_файловер = 1, кілька дзеркал роблять перебої меншими, ймовірно. Я можу вимкнути одне дзеркало, перезапустити його та вимкнути інше, перезапустити його та знову відключити перше - все без виходу з системи. Я думаю, що клієнт PHP-пам’яті робить багато хитрощів за кадром.
Том
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.