Optymalizacja witryn internetowych opartych na Kohana pod kątem szybkości i skalowalności

80

Witryna, którą zbudowałem z Kohana, została wczoraj zatłoczona ogromnym ruchem, co spowodowało, że cofnąłem się o krok i oceniłem część projektu. Jestem ciekawy, jakie są standardowe techniki optymalizacji aplikacji opartych na Kohanie?

Interesuje mnie też benchmarking. Czy muszę skonfigurować Benchmark::start()i Benchmark::stop()dla każdej metody kontrolera, aby zobaczyć czasy wykonywania dla wszystkich stron, czy też mogę zastosować testy porównawcze globalnie i szybko?

Będę częściej korzystał z biblioteki Cache w przyszłości, ale jestem otwarty na więcej sugestii, ponieważ jestem pewien, że mogę zrobić wiele, o których po prostu nie wiem.

Sampson
źródło
Czy próbowałeś wbudować w Kohana Profiler, aby uzyskać informacje o aplikacji? Jest całkiem nieźle
Yasen Zhelev

Odpowiedzi:

211

To, co powiem w tej odpowiedzi, nie jest specyficzne dla Kohany i prawdopodobnie może dotyczyć wielu projektów PHP.

Oto kilka punktów, które przychodzą mi na myśl, kiedy mówię o wydajności, skalowalności, PHP ...
Wiele z tych pomysłów wykorzystałem podczas pracy nad kilkoma projektami - i pomogły; więc prawdopodobnie mogliby tu pomóc.


Przede wszystkim, jeśli chodzi o występy, jest wiele aspektów / pytań, które należy wziąć pod uwagę :

  • konfiguracja serwera (zarówno Apache, PHP, MySQL, inne możliwe demony i system) ; możesz uzyskać więcej pomocy na ten temat w ServerFault ,
  • Kod PHP,
  • Zapytania do baz danych,
  • Używasz serwera internetowego czy nie?
  • Czy możesz użyć dowolnego mechanizmu buforowania? A może potrzebujesz zawsze bardziej aktualnych danych na stronie?


Korzystanie z odwrotnego serwera proxy

Pierwszą rzeczą, która może być naprawdę przydatna, jest użycie odwrotnego proxy , takiego jak varnish , przed serwerem sieciowym: niech buforuje jak najwięcej rzeczy , więc tylko żądania, które naprawdę wymagają obliczeń PHP / MySQL (i oczywiście kilka innych żądania, jeśli nie znajdują się w pamięci podręcznej serwera proxy), kierują je do Apache / PHP / MySQL.

  • Po pierwsze, Twój CSS / Javascript / Obrazy - cóż, wszystko, co jest statyczne - prawdopodobnie nie musi być zawsze obsługiwane przez Apache
    • Więc możesz mieć pamięć podręczną odwrotnego proxy.
    • Obsługa tych plików statycznych nie jest problemem dla Apache, ale im mniej musi on dla nich pracować, tym więcej będzie w stanie zrobić z PHP.
    • Pamiętaj: Apache może obsługiwać tylko skończoną, ograniczoną liczbę żądań na raz.
  • Następnie niech odwrotne proxy obsługuje jak najwięcej stron PHP z pamięci podręcznej: prawdopodobnie są strony, które nie zmieniają się tak często i mogą być obsługiwane z pamięci podręcznej. Zamiast używać pamięci podręcznej opartej na PHP, dlaczego nie pozwolić, aby inny, lżejszy serwer je obsługiwał (i pobierał je od czasu do czasu z serwera PHP, aby były zawsze prawie aktualne) ?
    • Na przykład, jeśli masz jakieś kanały RSS (zwykle zapominamy o tych, gdy próbujemy zoptymalizować pod kątem wydajności), o które są wymagane bardzo często , posiadanie ich w pamięci podręcznej przez kilka minut może zaoszczędzić setki / tysiące żądań do Apache + PHP + MySQL!
    • To samo dotyczy najczęściej odwiedzanych stron Twojej witryny, jeśli nie zmieniają się przez co najmniej kilka minut (na przykład: strona główna?) , To nie ma potrzeby marnowania procesora na ich ponowne generowanie za każdym razem, gdy użytkownik o to poprosi.
  • Może istnieje różnica między stronami obsługiwanymi dla anonimowych użytkowników (ta sama strona dla wszystkich anonimowych użytkowników) a stronami obsługiwanymi dla zidentyfikowanych użytkowników (na przykład „Witaj Panie X, masz nowe wiadomości”) ?
    • Jeśli tak, prawdopodobnie możesz skonfigurować odwrotne proxy tak, aby buforowało stronę, która jest obsługiwana dla anonimowych użytkowników (na podstawie pliku cookie, takiego jak zwykle plik cookie sesji)
    • Oznacza to, że Apache + PHP ma mniej do czynienia: tylko zidentyfikowani użytkownicy - którzy mogą stanowić tylko niewielką część Twoich użytkowników.

O używaniu odwrotnego proxy jako pamięci podręcznej , dla aplikacji PHP, możesz na przykład spojrzeć na Wyniki testów porównawczych pokazujące wzrost możliwości serwera o 400% -700% dzięki APC i pamięci podręcznej Squid .
(Tak, używają Squid, a ja mówiłem o lakierze - to tylko kolejna możliwość ^^ Lakier jest nowszy, ale bardziej poświęcony buforowaniu)

Jeśli zrobisz to wystarczająco dobrze i uda ci się przestać ponownie generować zbyt wiele stron, być może nie będziesz musiał nawet optymalizować żadnego z kodu ;-)
A przynajmniej może nie w pośpiechu ... Zawsze lepiej jest przeprowadzać optymalizacje, gdy nie jesteś pod zbyt dużą presją ...


Na marginesie: mówisz w PO:

Witryna, którą zbudowałem z Kohana, została wczoraj zalana ogromnym ruchem,

Jest to rodzaj nagłej sytuacji, w której odwrotne proxy może dosłownie uratować sytuację , jeśli Twoja witryna może poradzić sobie z nieaktualnością w ciągu sekundy:

  • zainstaluj, skonfiguruj, niech zawsze - każdego normalnego dnia - uruchom:
    • Skonfiguruj go tak, aby nie przechowywać stron PHP w pamięci podręcznej; lub tylko na krótki czas; w ten sposób zawsze masz aktualne dane
  • A dzień, w którym zastosujesz efekt slashdot lub digg:
    • Skonfiguruj odwrotne proxy, aby zachować strony PHP w pamięci podręcznej; lub przez dłuższy okres czasu; może Twoje strony nie będą aktualizowane w ciągu sekundy, ale pozwoli to Twojej witrynie przetrwać efekt kopania!

O tym, jak mogę wykryć i przetrwać bycie „Slashdotted”? może być ciekawą lekturą.


Po stronie PHP:

Po pierwsze: czy używasz najnowszej wersji PHP ? Nowe wersje regularnie poprawiają prędkość ;-)
Na przykład spójrz na Benchmark PHP Branches 3.0 do 5.3-CVS .

Zwróć uwagę, że wydajność jest całkiem dobrym powodem, aby używać PHP 5.3 ( zrobiłem kilka testów porównawczych (po francusku) i wyniki są świetne) ...
Kolejnym całkiem dobrym powodem jest oczywiście to, że PHP 5.2 osiągnęło koniec życia i nie jest już konserwowane!

Czy używasz jakiejkolwiek pamięci podręcznej kodu operacyjnego?

  • Myślę na przykład o APC - Alternative PHP Cache ( pecl , manual ) , które jest rozwiązaniem, które widziałem najczęściej - i jest używane na wszystkich serwerach, na których pracowałem.
  • W niektórych przypadkach może naprawdę znacznie obniżyć obciążenie procesora serwera (widziałem, że obciążenie procesora na niektórych serwerach spadło z 80% do 40%, po prostu instalując APC i aktywując jego funkcję pamięci podręcznej kodu operacji!)
  • Zasadniczo wykonanie skryptu PHP przebiega w dwóch etapach:
    • Kompilacja kodu źródłowego PHP do rozkazów (rodzaj odpowiednika kodu bajtowego JAVA)
    • Wykonanie tych rozkazów
    • APC przechowuje je w pamięci, więc za każdym razem, gdy wykonywany jest skrypt / plik PHP, trzeba wykonać mniej pracy: pobiera tylko kody operacyjne z pamięci RAM i wykonuje je.
  • Być może trzeba spojrzeć na APC opcji konfiguracyjnych , przy okazji
    • jest ich sporo, a niektóre mogą mieć duży wpływ zarówno na szybkość / obciążenie procesora / łatwość użycia
    • Na przykład wyłączenie [apc.stat](https://php.net/manual/en/apc.configuration.php#ini.apc.stat)może być dobre dla obciążenia systemu; ale oznacza to, że modyfikacje dokonane w plikach PHP nie będą brane pod uwagę, chyba że opróżnisz całą pamięć podręczną opcode; o tym, aby uzyskać więcej informacji, zobacz na przykład To stat () Or Not To stat ()?


Korzystanie z pamięci podręcznej danych

O ile to możliwe, lepiej unikać ciągłego robienia tego samego .

Główną rzeczą, o której myślę, są oczywiście zapytania SQL: wiele Twoich stron prawdopodobnie wykonuje te same zapytania, a wyniki niektórych z nich są prawdopodobnie prawie zawsze takie same ... Co oznacza wiele „bezużytecznych” zapytań do bazy danych, która musi poświęcać czas na ciągłe serwowanie tych samych danych.
Oczywiście dotyczy to innych rzeczy, takich jak połączenia z usługami internetowymi, pobieranie informacji z innych witryn internetowych, ciężkie obliczenia ...

Może być dla Ciebie bardzo interesujące zidentyfikowanie:

  • Jakie zapytania są uruchamiane wiele razy i zawsze zwracają te same dane
  • Jakie inne (ciężkie) obliczenia są wykonywane dużo czasu, zawsze zwracając ten sam wynik

I przechowuj te dane / wyniki w jakiejś pamięci podręcznej, aby były łatwiejsze do uzyskania - szybciej - i nie musisz iść do serwera SQL po „nic”.

Świetne mechanizmy buforowania to między innymi:

  • APC : oprócz opcode-cache, o którym mówiłem wcześniej, pozwala na przechowywanie danych w pamięci,
  • I / lub memcached ( zobacz także ) , co jest bardzo przydatne, jeśli masz dosłownie dużo danych i / lub korzystasz z wielu serwerów , ponieważ są one dystrybuowane.
  • oczywiście możesz pomyśleć o plikach; i prawdopodobnie wiele innych pomysłów.

Jestem prawie pewien, że twój framework zawiera pewne rzeczy związane z pamięcią podręczną; prawdopodobnie już to wiesz, jak powiedziałeś "Będę używał biblioteki pamięci podręcznej bardziej w przyszłości" w OP ;-)


Profilowy

Teraz fajnie byłoby użyć rozszerzenia Xdebug do profilowania aplikacji : często pozwala to dość łatwo znaleźć kilka słabych punktów - przynajmniej jeśli jest jakaś funkcja, która zajmuje dużo czasu.

Prawidłowo skonfigurowany wygeneruje pliki profilowe, które można przeanalizować za pomocą niektórych narzędzi graficznych, takich jak:

  • KCachegrind : mój ulubiony, ale działa tylko na Linuksie / KDE
  • Wincachegrind dla Windows; robi trochę mniej rzeczy niż KCacheGrind, niestety - zazwyczaj nie wyświetla callgraphów.
  • Webgrind, który działa na serwerze WWW PHP, więc działa wszędzie - ale prawdopodobnie ma mniej funkcji.

Na przykład, oto kilka zrzutów ekranu z KCacheGrind:

KCacheGrind: ekran główny
(źródło: pascal-martin.fr ) (źródło: pascal-martin.fr )
KCacheGrind: Callgraph wyeksportowane jako obraz

(Swoją drogą, callgraph przedstawiony na drugim zrzucie ekranu jest zwykle czymś, czego nie potrafi zrobić ani WinCacheGrind, ani Webgrind, jeśli dobrze pamiętam ^^)


(Dzięki @Mikushi za komentarz) Inną możliwością, z której nie korzystałem zbyt wiele, jest rozszerzenie xhprof : pomaga również w profilowaniu, może generować callgraph - ale jest lżejsze niż Xdebug, co oznacza, że ​​powinieneś być w stanie go zainstalować serwer produkcyjny.

Powinieneś móc go używać poza XHGui , co pomoże w wizualizacji danych.


Po stronie SQL:

Skoro już trochę rozmawialiśmy o PHP, zauważ, że jest więcej niż możliwe, że wąskim gardłem nie jest strona PHP , ale baza danych ...

Co najmniej dwie lub trzy rzeczy, tutaj:

  • Powinieneś określić:
    • Jakie są najczęstsze zapytania, które wykonuje Twoja aplikacja
    • Czy są one optymalizowane ( głównie przy użyciu właściwych indeksów ?) , Korzystając z EXPLAINinstrukcji, jeśli używasz MySQL
    • czy możesz buforować niektóre z tych zapytań (zobacz, co powiedziałem wcześniej)
  • Czy Twój MySQL jest dobrze skonfigurowany? Niewiele o tym wiem, ale jest kilka opcji konfiguracyjnych, które mogą mieć pewien wpływ.

Mimo to dwie najważniejsze rzeczy to:

  • Nie idź do bazy danych, jeśli nie musisz: buforować tyle, ile możesz !
  • Kiedy musisz iść do bazy danych, używaj wydajnych zapytań: używaj indeksów; i profil!


I co teraz?

Jeśli nadal czytasz, co jeszcze można zoptymalizować?

Cóż, wciąż jest miejsce na ulepszenia ... Oto kilka pomysłów na architekturę:

  • Przełącz się na architekturę n-warstwową:
    • Umieść MySQL na innym serwerze (dwupoziomowy: jeden dla PHP; drugi dla MySQL)
    • Użyj kilku serwerów PHP (i równoważ obciążenia użytkowników między nimi)
    • Użyj innego komputera do plików statycznych, z lżejszym serwerem WWW, takim jak:
      • lighttpd
      • lub nginx - przy okazji ten staje się coraz bardziej popularny.
    • Użyj kilku serwerów dla MySQL, kilku serwerów dla PHP i kilku serwerów odwrotnych proxy przed nimi
    • Oczywiście: zainstaluj demony memcached na dowolnym serwerze, na którym jest wolna pamięć RAM, i używaj ich do buforowania tak dużo, jak tylko możesz / ma sens.
  • Użyć czegoś „bardziej wydajnego” niż Apache?

Cóż, może niektóre z tych pomysłów są trochę przesadzone w twojej sytuacji ^^
Ale nadal ... Dlaczego nie przestudiować ich trochę, na wszelki wypadek? ;-)


A co z Kohaną?

Twoje pierwsze pytanie dotyczyło optymalizacji aplikacji korzystającej z Kohana ... Cóż, opublikowałem kilka pomysłów, które są prawdziwe dla każdej aplikacji PHP ... Co oznacza, że ​​są one również prawdziwe dla Kohany ;-)
(Nawet jeśli nie są dla niej specyficzne ^^)

Powiedziałem: użyj pamięci podręcznej; Wydaje się, że Kohana obsługuje trochę buforowania (sam o tym mówiłeś, więc nic nowego ...)
Jeśli jest coś, co można zrobić szybko, spróbuj ;-)

Powiedziałem też, że nie powinieneś robić niczego, co nie jest konieczne; czy jest coś włączonego domyślnie w Kohanie, czego nie potrzebujesz?
Przeglądając sieć, wydaje się, że jest przynajmniej coś o filtrowaniu XSS; potrzebujesz tego

Oto kilka linków, które mogą być przydatne:


Wniosek?

I na koniec prosta myśl:

  • Ile będzie kosztować Twoja firma, płacąc Ci 5 dni? - biorąc pod uwagę, że jest to rozsądna ilość czasu na wykonanie kilku świetnych optymalizacji
  • Ile będzie kosztować Twoją firmę zakup (opłacenie?) Drugiego serwera i jego utrzymanie?
  • A co, jeśli musisz skalować na większą skalę?
    • Ile będzie kosztowało spędzenie 10 dni? więcej? optymalizacja każdego możliwego fragmentu Twojej aplikacji?
    • A ile za kilka dodatkowych serwerów?

Nie mówię, że nie powinieneś optymalizować: zdecydowanie powinieneś!
Ale zdecyduj się na „szybkie” optymalizacje, które najpierw dadzą Ci duże korzyści : użycie pamięci podręcznej kodu operacji może pomóc Ci zmniejszyć obciążenie procesora o 10 do 50 procent ... A konfiguracja zajmuje tylko kilka minut; - ) Z drugiej strony spędzanie 3 dni za 2 proc ...

Aha, i przy okazji: zanim cokolwiek zrobisz: umieść kilka rzeczy monitorujących na miejscu , abyś wiedział, jakie ulepszenia zostały wprowadzone i jak!
Bez monitorowania nie będziesz miał pojęcia o efekcie tego, co zrobiłeś ... Nawet jeśli jest to prawdziwa optymalizacja, czy nie!

Na przykład możesz użyć czegoś takiego jak RRDtool + kaktusy .
A pokazanie szefowi ładnej grafiki ze spadkiem obciążenia procesora o 40% jest zawsze świetne ;-)


W każdym razie, i naprawdę podsumowując: baw się dobrze!
(Tak, optymalizacja jest fajna!)
(Ech, nie sądziłem, żebym tak dużo pisał ... Mam nadzieję, że przynajmniej niektóre części są przydatne ... I powinienem pamiętać o tej odpowiedzi: może się przydać innym razem. ..)

Pascal MARTIN
źródło
Chociaż dodanie nowych serwerów może być tańsze niż praca programisty przez 5 dni, nie zapominaj, że oprogramowanie może nie działać poprawnie, gdy jest uruchamiane z wielu serwerów (być może będziesz musiał w jakiś sposób udostępniać pliki między serwerami - NFS może być uciążliwe, ale korzystasz z sesji? lepiej przenieś je do bazy danych itp.). a to samo w sobie będzie wymagało od programisty pracy nad rzeczami.
NSSec
16
Świetne wyjaśnienie! Czy masz bloga, którego mogę subskrybować? :-)
Gray Panther
@ dnh828: Napisałem go z nadzieją, że wykorzystam go ponownie przy innych okazjach (właściwie już to zrobiłem) ;; @MathieuK: zdecydowanie prawda (jeśli chodzi o sesje, ale zamiast DB można sobie wyobrazić użycie memcache) ;; @ Cd-MaN: Dzięki! Właściwie mam blog, ale jest po francusku i naprawdę nie bloguję
Pascal MARTIN
Rozważ przyjrzenie się XHProf ( pecl.php.net/package/xhprof ), uważam, że lepiej niż XDebug profilować mój kod, szczególnie na serwerach produkcyjnych, w połączeniu z XHGui ( github.com/preinheimer/xhprof ) to prawdziwa przyjemność pracować z.
Mikushi
Szkoda, prawda? ;-) ;; coś, co możesz zrobić, to użyć linku stackoverflow.com/q/1260134/138475, aby udostępnić to pytanie - aby więcej osób mogło przeczytać tę odpowiedź (właśnie dlatego napisałem tak długą odpowiedź: aby czytać ^^)
Pascal MARTIN
5

Kod profilu z XDebug .

Używaj dużo pamięci podręcznej. Jeśli Twoje strony są względnie statyczne, najlepszym sposobem na to może być odwrotne proxy.

Kornel
źródło
5

Kohana jest po wyjęciu z pudełka bardzo, bardzo szybko, z wyjątkiem użycia obiektów bazy danych. Cytując Zombor: „Możesz zmniejszyć zużycie pamięci, upewniając się, że używasz obiektu bazy danych zamiast tablic wyników”. To powoduje OGROMNĄ różnicę w wydajności witryny, która jest atakowana. Nie tylko zużywa więcej pamięci, ale także spowalnia wykonywanie skryptów.

Ponadto - musisz użyć buforowania. Wolę memcache i używam go w moich modelach w ten sposób:

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;
}

To również znacznie zwiększy wydajność. Powyższe dwie techniki poprawiły wydajność witryn o 80%.

Jeśli podasz więcej informacji o tym, gdzie Twoim zdaniem znajduje się wąskie gardło, jestem pewien, że moglibyśmy podać lepsze pomysły.

Sprawdź również yslow (google it), aby uzyskać inne wskazówki dotyczące wydajności.

ae.
źródło
1

Ściśle związane z Kohaną (prawdopodobnie już to zrobiłeś lub nie):

W trybie produkcyjnym:

  1. Włącz wewnętrzne buforowanie (spowoduje to tylko buforowanie wyników Kohana :: find_file, ale w rzeczywistości może to bardzo pomóc.
  2. Wyłącz profiler

Tylko moje 2 centy :)

Tamás Pap
źródło
0

Całkowicie zgadzam się z XDebug i buforowaniem odpowiedzi. Nie zaglądaj do warstwy Kohana w celu optymalizacji, dopóki nie zidentyfikujesz największych wąskich gardeł w zakresie szybkości i skali.

XDebug powie Ci, gdzie spędzałeś najwięcej czasu i zidentyfikuje „punkty aktywne” w kodzie. Zachowaj te informacje profilowania, aby móc bazować i mierzyć ulepszenia wydajności.

Przykładowy problem i rozwiązanie: Jeśli zauważysz, że za każdym razem tworzysz drogie obiekty z bazy danych, które tak naprawdę nie zmieniają się często, możesz spojrzeć na buforowanie ich za pomocą memcached lub innego mechanizmu. Wszystkie te poprawki wydajności wymagają czasu i komplikują system, więc zanim zaczniesz je naprawiać, upewnij się, że występują wąskie gardła.

Ozten
źródło