Горизонтальне масштабування php-додатків, частина 1, php

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

До всього іншого, ваш сервер впав і не витримує постійно зростаючого навантаження. Замість придбання нових клієнтів і / або постійних відвідувачів, ви залишилися біля розбитого корита і, до того ж, з порожньою сторінкою.

Всі ваші зусилля по відновленню роботи безрезультатні - навіть після перезавантаження, сервер не може впоратися з потоком відвідувачів. Ви втрачаєте трафік!

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

Як же тоді уникнути всіх цих проблем? Для цього потрібно вирішити два питання: оптимізація і масштабування.

оптимізація

Насамперед, варто провести оновлення до останньої версії PHP (поточна версія 5.5, використовує OpCache), проіндексувати базу даних і закешовану статичний контент (рідко змінюються сторінки на кшталт About. FAQ і так далі).

Оптимізація зачіпає не тільки кешування статичних ресурсів. Також, є можливість встановити додатково не-Apache-сервер (наприклад, Nginx), спеціально призначений для обробки статичного контенту.

Ідея полягає в наступному: ви ставите Nginx перед вашим Apache-сервером (Ngiz буде frontend -Сервер, а Apache - backend), і доручаєте йому, перехоплення запитів на статичні ресурси (тобто * .jpg. * .png. *. mp4. * .html ...) і їх обслуговування БЕЗ ВІДПРАВЛЕННЯ запиту на Apache.

Така схема називається reverse proxy (її часто згадують разом з технікою балансування навантаження, про яку розказано нижче).

масштабування

Існує два типи масштабування - горизонтальне і вертикальне.

Ми говоримо, що сайт масштабується, коли він може витримувати збільшення навантаження без необхідності внесення змін до програмного забезпечення.

вертикальне масштабування

Уявіть, що у вас є веб-сервер, що обслуговує веб-додаток. Цей сервер має наступні характеристики 4GB RAM. i5 CPU і 1TB HDD.

Він добре виконує покладені на нього завдання, але щоб краще справлятися з наростаючим трафіком, ви вирішуєте замінити 4GB RAM на 16GB, встановлюєте новий i7 CPU і додаєте гібридний носій PCIe SSD / HDD.

Сервер тепер став більш потужним і може витримувати збільшені навантаження. Саме це і називається вертикальним масштабуванням або «масштабуванням вглиб» - ви покращуєте характеристики машини, щоб зробити її більш потужною.

Це добре проілюстровано на зображенні нижче:

Горизонтальне масштабування php-додатків, частина 1, php

горизонтальне масштабування

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

Це дуже фінансово затратно і часто не дає того ефекту, який ми очікуємо - більшість проблем масштабування відносяться до паралельного виконання завдань.

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

Горизонтальне масштабування передбачає побудову кластерів з машин (часто досить малопотужних), пов'язаних один з одним для обслуговування веб-сайту.

В даному випадку, використовується балансувальник навантаження (load balancer) - машина або програма, яка займається тим, що визначає, яким кластеру слід відправити черговий запит, що надійшов.

А машини в кластері автоматично розділяють завдання між собою. В цьому випадку, пропускна здатність вашого сайту зростає на порядок в порівнянні з вертикальним масштабуванням. Це також відомо як «масштабування вшир».

Є два типи балансувальник навантаження - апаратні і програмні. Програмний балансувальник встановлюється на звичайну машину і приймає весь вхідний трафік, перенаправляючи його в відповідний обробник. Як програмне балансувальника навантаження, може виступити, наприклад, Nginx.

Він приймає запити на статичні файли і самостійно їх обслуговує, не обтяжуючи цим Apache. Іншим популярним програмним забезпеченням для програмної балансування є Squid. який я використовую у своїй компанії. Він надає повний контроль над усіма можливими питаннями за допомогою дуже дружнього інтерфейсу.

Апаратні балансувальник є окремою спеціальну машину, яка виконує виключно завдання балансування і на якій, як правило, не встановленого іншого програмного забезпечення. Найбільш популярні моделі розроблені для обробки величезної кількості трафіку.

При горизонтальному масштабуванні відбувається наступне:

Горизонтальне масштабування php-додатків, частина 1, php

Зауважте, що два згадані способу масштабування не є взаємовиключними - ви можете покращувати апаратні характеристики машин (також званих нодамі - node), використовуваних в масштабированной вшир кластерної системі.

У даній статті ми сфокусуємось на горизонтальному масштабуванні, так як в більшості випадків воно краще (дешевше і ефективніше), хоча його і важче реалізувати з технічної точки зору.

Складнощі з поділом даних

Є кілька слизьких моментів, що виникають при масштабуванні PHP-додатків. Вузьким місцем тут є база даних (ми ще поговоримо про це в другій частині даного циклу).

Постійний балансувальник навантаження

Постійний балансувальник навантаження запам'ятовує, де оброблявся попередній запит того чи іншого клієнта і, при наступному запиті, відправляє запит туди ж.

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

Але що, якщо Server1 впав? Природно, всі дані сесії будуть загублені, а мені доведеться логінитися заново вже на новому сервері. Це дуже неприємно для користувача. Більш того, це зайве навантаження на балансувальник навантаження: йому потрібно буде не тільки перенаправити тисячі людей на інші сервера, але і запам'ятати, куди він їх перенаправив.

Це стає ще одним вузьким місцем. А що, якщо єдиний балансувальник навантаження сам вийде з ладу і вся інформації про розташування клієнтів на серверах буде загублена? Хто керуватиме балансуванням? Хитромудра ситуація, чи не так?

Розподіл локальних даних

Поділ даних про сесії всередині кластера виразно здається непоганим рішенням, але вимагає змін в архітектурі додатки, хоча це того варто, тому що вузьке місце стає широким. Падіння одного сервера перестає фатально впливати на всю систему.

Відомо, що дані сесії зберігаються в суперглобального PHP-масиві $ _SESSION. Також, ні для кого не секрет, що цей масив $ _SESSION зберігається на жорсткому диску.

Відповідно, так як диск належить тій чи іншій машині, то інші до нього доступу не мають. Тоді як же організувати до нього загальний доступ для декількох комп'ютерів?

Зауважу, що обробники сесій в PHP можуть бути перевизначені - ви можете визначити свій власний клас / функцію для управління сесіями.

Використання бази даних

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

Хоча даний підхід працює досить добре, в разі великого трафіку, база даних стає не просто вразливим місцем (втративши її, ви втратите все), до неї буде багато звернень через необхідність записувати і зчитувати дані сесій.

Це стає черговим вузьким місцем в нашій системі. В цьому випадку, можна застосувати масштабування вшир, що проблематично при використанні традиційних баз даних типу MySQL. Postgre і тому подібних (ця проблема буде розкрита в другій частині циклу).

Використання загальної файлової системи

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

Якщо ви все-таки хочете реалізувати варіант із загальною файлової системою, тобто набагато більше краще рішення - GlusterFS.

Ви можете використовувати memcached для зберігання даних сесій в оперативній пам'яті. Це дуже небезпечний спосіб, так як дані сесій будуть перезаписані, як тільки закінчиться вільний дисковий простір.

Будь-яке сталість відсутня - дані про вхід будуть зберігатися до тих пір, поки memcached сервер запущений і є вільний простір для зберігання цих даних.

Ви можете бути здивовані - хіба оперативна пам'ять не окрема для кожної машини? Як застосувати цей спосіб до кластеру? Memcached має можливість віртуально об'єднувати всю доступну RAM декількох машин в єдине сховище:

Горизонтальне масштабування php-додатків, частина 1, php

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

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

В кеш, крім сесій можуть потрапляти і будь-які інші дані за вашим бажанням, головне щоб вистачило вільного місця. Memcached це прекрасне рішення, яке набуло широкого поширення.

Використовувати цей спосіб в PHP-додатках дуже легко: треба змінити значення в файлі php.ini:

Redis Cluster

Redis це не SQL сховище даних, розташоване в оперативній пам'яті, подібно Memcached. проте воно має сталість і підтримує більш складні типи даних, ніж просто рядки PHP-масиву в формі пар «key => value».

Це рішення не має підтримки кластерів, тому реалізація його в горизонтальній системі масштабування не так проста, як може здатися на перший погляд, але цілком виконуваності. Насправді, альфа-версія кластерної версії вже вийшла і можна її використовувати.

Якщо порівнювати Redis з рішеннями на кшталт Memcached. то він являє собою щось середнє між звичайною базою даних і Memcached.

  • ZSCM від Zend - хороша альтернатива, але вимагає установки Zend Server на кожен нод в кластері;
  • Інші невідображені SQL сховища і системи кешування також цілком працездатні - ознайомтеся з Scache. Cassandra або Couchbase. всі вони працюють швидко і надійно.

висновок

Як ви могли зрозуміти з написаного вище, горизонтальне масштабування PHP-додатків це не пікнік на вихідних.

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

Переклад статті «Horizontal Scaling of PHP Apps, Part 1» був підготовлений дружною командою проекту Сайтобудування від А до Я.

Схожі статті