Оптимізація веб-сайтів на базі Kohana для швидкості та масштабованості


80

Сайт, який я побудував із Коханою, вчора був завалений величезним обсягом трафіку, змусивши мене зробити крок назад і оцінити частину дизайну. Мені цікаво, які стандартні методи оптимізації програм на базі Kohana?

Мене цікавить і бенчмаркінг. Чи потрібно мені налаштовувати Benchmark::start()і Benchmark::stop()для кожного методу контролера, щоб бачити час виконання для всіх сторінок, чи я можу застосувати порівняльний аналіз глобально та швидко?

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


Ви пробували вбудовувати Kohana Profiler, щоб отримати деяку інформацію про програму? Це цілком непогано
Ясен Желєв

Відповіді:


211

Те, що я скажу у цій відповіді, не є специфічним для Kohana, і, ймовірно, може стосуватися багатьох проектів PHP.

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


Перш за все, що стосується вистав, є багато аспектів / питань, які слід врахувати :

  • конфігурація сервера (як Apache, PHP, MySQL, інші можливі демони, так і система) ; Ви можете отримати додаткову допомогу щодо цього на ServerFault , я гадаю,
  • Код PHP,
  • Запити до бази даних,
  • Використовуєте чи ні свій веб-сервер?
  • Чи можете ви використовувати будь-який механізм кешування? Або вам завжди потрібно більше сучасних даних на веб-сайті?


Використання зворотного проксі

Перше, що може бути справді корисним, - це використання зворотного проксі-сервера , наприклад, лаку , перед вашим веб-сервером: нехай він кешує якомога більше речей , тому лише запити, які дійсно потребують обчислень PHP / MySQL (і, звичайно, деякі інші запити, коли їх немає в кеші проксі), перейдіть до Apache / PHP / MySQL.

  • Перш за все, ваш CSS / Javascript / Images - ну, все, що є статичним - мабуть, не потрібно завжди обслуговувати Apache
    • Отже, ви можете мати кеш зворотного проксі-сервера.
    • Обслуговування цих статичних файлів для Apache не становить великої праці, але чим менше для них потрібно працювати, тим більше він зможе зробити з PHP.
    • Пам'ятайте: Apache може одночасно подавати лише обмежену кількість запитів.
  • Потім, нехай зворотний проксі обслуговує якомога більше PHP-сторінок із кешу: можливо, є нехай деякі сторінки, які змінюються не так часто , і їх можна обслуговувати з кешу. Замість того, щоб використовувати кеш на основі PHP, чому б не дозволити іншому, легшому серверу обслуговувати їх (і час від часу отримувати їх з сервера PHP, тому вони завжди майже в курсі) ?
    • Наприклад, якщо у вас є деякі RSS-канали (ми, як правило, забуваємо про ті, намагаючись оптимізувати показники) , які дуже часто запитуються , наявність їх у кеші протягом декількох хвилин може заощадити сотні / тисячі запитів до Apache + PHP + MySQL!
    • Те саме стосується найбільш відвідуваних сторінок вашого сайту, якщо вони не змінюються принаймні пару хвилин (приклад: домашня сторінка?) , Тоді не потрібно витрачати витрати процесора на їх повторне генерування кожного разу, коли користувач запитує їх.
  • Можливо, існує різниця між сторінками, що обслуговуються для анонімних користувачів (однакова сторінка для всіх анонімних користувачів), та сторінками, що обслуговуються для ідентифікованих користувачів ("Привіт, пане X, у вас є нові повідомлення", наприклад) ?
    • Якщо так, можливо, ви можете налаштувати зворотний проксі для кешування сторінки, яка обслуговується для анонімних користувачів (на основі файлу cookie, як, наприклад, сеансовий файл cookie)
    • Це означатиме, що Apache + PHP має менше справи: лише ідентифіковані користувачі - які можуть бути лише невеликою частиною ваших користувачів.

Щодо використання зворотного проксі-сервера в якості кешу , для програми PHP ви можете, наприклад, поглянути на результати бенчмарк-показів Показати 400% -700% збільшення можливостей серверів за допомогою APC та Squid Cache .
(Так, вони використовують Squid, і я говорив про лак - це просто ще одна можливість ^^ Лак є недавнім, але більше присвяченим кешуванню)

Якщо ви зробите це досить добре і вам вдасться припинити повторне генерування занадто багато сторінок знову і знову, можливо, вам навіть не доведеться оптимізувати будь-який свій код ;-)
Принаймні, можливо, не в будь-якому поспіху ... І завжди краще проводити оптимізацію, коли у вас не надто тиск ...


Як сторона: ви говорите в ОП:

Сайт, який я побудував із Коханою, вчора був завалений величезним трафіком

Це така раптова ситуація, коли зворотний проксі може буквально врятувати день , якщо ваш веб-сайт може впоратися з тим, що не оновлюється до секунди:

  • встановіть його, налаштуйте, нехай завжди - щодня - запускається:
    • Налаштуйте його, щоб не зберігати сторінки PHP в кеші; або лише на короткий час; таким чином, у вас завжди відображаються актуальні дані
  • І в той день, коли ви зробите ефект косої риски або копання:
    • Налаштуйте зворотний проксі-сервер для збереження сторінок PHP в кеші; або на більш тривалий проміжок часу; можливо, ваші сторінки не будуть оновлені на секунду, але це дозволить вашому веб-сайту пережити ефект digg!

Про те, як я можу виявити та вижити, коли я “Slashdotted”? може бути цікавим читанням.


Стосовно PHP:

Перш за все: чи використовуєте ви останню версію PHP ? Регулярно покращуються швидкості, з новими версіями ;-)
Наприклад, погляньте на Benchmark PHP Branches 3.0 до 5.3-CVS .

Зауважте, що продуктивність є досить вагомою причиною для використання PHP 5.3 ( я зробив кілька еталонів (французькою мовою) , і результати чудові) ...
Ще однією досить вагомою причиною є, звичайно, те, що PHP 5.2 досягла кінця , і більше не підтримується!

Чи використовуєте ви який-небудь кеш операційного коду?

  • Я думаю про APC - альтернативний кеш PHP , наприклад ( pecl , посібник ) , який є рішенням, яке я бачив найбільше - і яке використовується на всіх серверах, на яких я працював.
  • У деяких випадках це дійсно може значно знизити завантаження процесора сервера (я бачив, як завантаження процесора на деяких серверах змінюється від 80% до 40%, просто встановивши APC та активувавши функціональність кешування opcode!)
  • В основному, виконання PHP-скрипту складається з двох кроків:
    • Компіляція вихідного коду PHP з кодами операцій (різновид еквівалента байт-коду JAVA)
    • Виконання цих кодів операцій
    • APC зберігає їх у пам'яті, тому щоразу, коли виконується PHP-скрипт / файл, потрібно робити менше роботи: лише дістаньте коди оперативної пам'яті з оперативної пам'яті та виконайте їх.
  • Можливо, вам доведеться поглянути на параметри конфігурації APC , до речі
    • таких є досить багато, і деякі можуть мати великий вплив як на швидкість / завантаження процесора, так і на зручність використання для вас
    • Наприклад, відключення [apc.stat](https://php.net/manual/en/apc.configuration.php#ini.apc.stat)може бути корисним для завантаження системи; але це означає, що зміни, внесені у файли PHP, не будуть враховуватися, якщо ви не очистите весь кеш opcode; про це, для більш докладної інформації див., наприклад, To stat () Або Not To stat ()?


Використання кешу для даних

Наскільки це можливо, краще уникати робити одне і те ж знову і знову .

Головне, про що я думаю, це, звичайно, SQL-запити: багато ваших сторінок, ймовірно, роблять однакові запити, а результати деяких із них, мабуть, майже завжди однакові ... Що означає безліч "марних" запитів зроблений до бази даних, якій доводиться витрачати час на обслуговування тих самих даних знову і знову.
Звичайно, це вірно для інших речей, таких як дзвінки веб-служб, отримання інформації з інших веб-сайтів, важкі розрахунки ...

Вам може бути дуже цікаво визначити:

  • Які запити виконуються багато разів, завжди повертаючи однакові дані
  • Які інші (важкі) обчислення виконуються багато часу, завжди повертаючи однаковий результат

І зберігайте ці дані / результати у якомусь кеші, щоб їх було легше отримати - швидше - і вам не доведеться переходити на свій SQL-сервер нічого.

Чудовими механізмами кешування є, наприклад:

  • APC : на додаток до кешу opcode, про який я вже говорив раніше, це дозволяє зберігати дані в пам'яті,
  • І / або memcached ( див. Також ) , що дуже корисно, якщо у вас буквально багато даних та / або ви використовуєте кілька серверів , оскільки вони розподіляються.
  • звичайно, ви можете подумати про файли; і, мабуть, багато інших ідей.

Я майже впевнений, що ваш фреймворк містить деякі речі, пов'язані з кешем; ви, напевно, це вже знаєте, як ви сказали: "Я буду використовувати бібліотеку кеш-пам'яті ще в майбутньому" в OP ;-)


Профілювання

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

Налаштований належним чином , він генерує файли профілювання, які можна аналізувати за допомогою деяких графічних інструментів, таких як:

  • KCachegrind : мій улюблений, але працює лише на Linux / KDE
  • Wincachegrind для вікон; він робить трохи менше речей, ніж KCacheGrind, на жаль - як правило, він не відображає графіки.
  • Webgrind, який працює на веб-сервері PHP, тому працює де завгодно, але, ймовірно, має менше можливостей.

Наприклад, ось кілька скріншотів KCacheGrind:

KCacheGrind: головний екран
(джерело: pascal-martin.fr ) (джерело: pascal-martin.fr )
KCacheGrind: Callgraph експортується як зображення

(До речі, графік виклику, представлений на другому скріншоті, як правило, не може зробити ні WinCacheGrind, ні Webgrind, якщо я правильно пам’ятаю ^^)


(Дякую @Mikushi за коментар) Ще однією можливістю, яку я мало використовував, є розширення xhprof : воно також допомагає при профілюванні, може генерувати callgraphs - але легше, ніж Xdebug, що означає, що ви повинні мати можливість встановити його на виробничий сервер.

Ви повинні мати можливість використовувати його поряд із XHGui , що допоможе для візуалізації даних.


З боку SQL:

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

Тут принаймні дві-три речі:

  • Вам слід визначити:
    • Які найпоширеніші запити робить ваша програма
    • Чи оптимізовані вони (використовуючи правильні індекси , головним чином?) , Використовуючи EXPLAINінструкцію, якщо ви використовуєте MySQL
    • чи можете ви кешувати деякі з цих запитів (див. те, що я сказав раніше)
  • Чи добре налаштований ваш MySQL? Я не знаю багато про це, але є деякі варіанти конфігурації, які можуть мати певний вплив.

І все-таки дві найважливіші речі:

  • Не переходьте до БД, якщо вам не потрібно: кешуйте якомога більше !
  • Коли вам потрібно перейти до БД, використовуйте ефективні запити: використовуйте індекси; і профіль!


А що тепер?

Якщо ви все ще читаєте, що ще можна оптимізувати?

Ну, ще є місце для вдосконалення ... Кілька архітектурно-орієнтованих ідей можуть бути:

  • Перехід на архітектуру n-рівня:
    • Помістіть MySQL на інший сервер (дворівневий: один для PHP; інший для MySQL)
    • Використовуйте кілька серверів PHP (і балансуйте навантаження користувачів між ними)
    • Використовуйте інші машини для статичних файлів із легшим веб-сервером, наприклад:
      • lighttpd
      • або nginx - цей стає все більш популярним, до речі.
    • Використовуйте кілька серверів для MySQL, кілька серверів для PHP та кілька зворотних проксі-серверів перед ними
    • Звичайно: встановлюйте memcached демони на будь-який сервер, який має будь-яку кількість вільної оперативної пам’яті, і використовуйте їх для кешування, скільки зможете / має сенсу.
  • Використовувати щось "більш ефективне", ніж Apache?
    • Я все частіше чую про nginx , який повинен бути чудовим, коли мова йде про PHP та великі веб-сайти; Я сам ніколи цим не користувався, але ви можете знайти кілька цікавих статей про це в мережі;

Ну, можливо, деякі з цих ідей у ​​вашій ситуації трохи надмірні ^^
Але, все ж ... Чому б не вивчити їх трохи, про всяк випадок? ;-)


А як щодо Кохани?

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

Я сказав: використовувати кеш; Здається, Кохана підтримує деякі речі для кешування (Ви самі про це говорили, тож тут нічого нового ...)
Якщо є щось, що можна зробити швидко, спробуйте ;-)

Я також сказав, що ви не повинні робити нічого, що не потрібно; чи є щось увімкнене за замовчуванням у Kohana, що вам не потрібно?
Переглядаючи мережу, здається, є щонайменше щось про фільтрацію XSS; вам це потрібно?

Проте, ось кілька посилань, які можуть бути корисними:


Висновок?

І, на закінчення, проста думка:

  • Скільки коштуватиме вашій компанії платити вам 5 днів? - враховуючи, що для розумної кількості часу потрібно провести деякі великі оптимізації
  • Скільки коштуватиме вашій компанії придбання (оплата?) Другого сервера та його обслуговування?
  • Що робити, якщо вам доведеться масштабувати більше?
    • Скільки буде коштувати витратити 10 днів? більше? оптимізувати кожен можливий біт вашої програми?
    • А скільки ще на пару серверів?

Я не кажу, що вам не слід оптимізувати: ви точно повинні!
Але перейдіть за "швидкою" оптимізацією, яка принесе вам перші великі винагороди : використання деякого кешу коду операційного коду може допомогти вам отримати від 10 до 50 відсотків від завантаження процесора вашого сервера ... І для налаштування потрібно всього пару хвилин; - ) З іншого боку, витратити 3 дні на 2 відсотки ...

О, і, до речі: перед тим, як щось робити: встановіть кілька моніторингових матеріалів , щоб ви знали, які вдосконалення були зроблені, і як!
Без моніторингу ви не уявляєте ефекту від того, що зробили ... Навіть якщо це справжня оптимізація чи ні!

Наприклад, ви можете використовувати щось на зразок RRDtool + кактуси .
А показати начальникові якусь приємну графіку із зниженням завантаження процесора на 40% - це завжди чудово ;-)


У будь-якому разі, і, щоб справді зробити висновок: веселіться!
(Так, оптимізація - це весело!)
(Е-е, я не думав, що писатиму так багато ... Сподіваюся, принаймні деякі частини цього корисні ... І я повинен пам’ятати цю відповідь: може бути корисним інший раз. ..)


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

16
Чудове пояснення! У вас є щоденник, на який я можу підписатися? :-)
Сіра пантера

@ dnh828: Я написав його, сподіваючись повторно використовувати його в інших випадках (я насправді вже робив це) ;; @MathieuK: безумовно правда (про сесії, хоча замість БД ви також можете передбачити використання memcache) ;; @ Cd-MaN: Дякую! У мене насправді є щоденник, але це французька мова, і я справді не часто веду
Паскаль МАРТІН

Подумайте про те, щоб поглянути на XHProf ( pecl.php.net/package/xhprof ), я вважаю, що краще, ніж XDebug, профілювати свій код, особливо на робочих серверах, у поєднанні з XHGui ( github.com/preinheimer/xhprof ), це справжнє задоволення. для роботи.
Mikushi

Шкода, чи не так? ;-) ;; Щось, що ви можете зробити, це скористатися посиланням stackoverflow.com/q/1260134/138475, щоб поділитися цим питанням - так більше людей зможуть прочитати цю відповідь (саме тому я написав таку довгу відповідь: читати ^^)
Паскаль МАРТІН


5

Код профілю за допомогою XDebug .

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


5

Kohana виходить з коробки дуже швидко, за винятком використання об'єктів бази даних. Процитуючи Zombor: "Ви можете зменшити використання пам'яті, переконавшись, що використовуєте об'єкт результату бази даних замість масивів результатів." Це робить ВЕЛИЧЕЗНУ різницю в продуктивності на веб-сайті, який загрожує. Він не тільки використовує більше пам'яті, але і уповільнює виконання сценаріїв.

Також - ви повинні використовувати кешування. Я віддаю перевагу memcache і використовую його в своїх моделях так:

public function get($e_id)
{
    $event_data = $this->cache->get('event_get_'.$e_id.Kohana::config('config.site_domain'));

    if ($event_data === NULL)
    {
        $this->db_slave
            ->select('e_id,e_name')
            ->from('Events')
            ->where('e_id', $e_id);

        $result = $this->db_slave->get();
        $event_data = ($result->count() ==1)? $result->current() : FALSE;

        $this->cache->set('event_get_'.$e_id.Kohana::config('config.site_domain'), $event_data, NULL, 300); // 5 minutes
    }

    return $event_data;
}

Це також різко збільшить продуктивність. Зазначені два способи покращили продуктивність сайтів на 80%.

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

Також перевірте yslow (google it), щоб отримати деякі інші поради щодо ефективності.


1

Суворо пов’язане з Коханою (ви, мабуть, це вже робили чи ні):

У виробничому режимі:

  1. Увімкніть внутрішнє кешування (це буде кешувати лише результати Kohana :: find_file, але це насправді може дуже допомогти.
  2. Вимкнути профайлер

Тільки мої 2 центи :)


0

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

XDebug повідомить вам, що ви витрачаєте більшу частину свого часу, та визначить «гарячі точки» у своєму коді. Зберігайте цю інформацію про профілювання, щоб мати змогу визначати базові показники та вимірювати покращення продуктивності.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.