Coraz częściej na banerach reklamowych można zauważyć, że dostawcy usług hostingowych obiecują nam czasy odpowiedzi poniżej 0,3s dla instancji Magento. Czy jest możliwe osiągnięcie takiego wyniku, bez ingerencji w kod Magento? A może po prostu, jest to kolejny chwyt marketingowy?

Warto zweryfikować tę tezę, dlatego przeprowadziliśmy szereg testów, porównując jednocześnie wpływ ilości rdzeni, dodatkowe usługi takie jak Varnish, Redis czy HHVM, jak i bezpośrednią konfrontację Apache’a z Nginx’em. Czy zwycieżca osiągnie magiczną bariere 0.3s? Zapraszam do lektury:)

Konfiguracja

Wszystkie testy zostały wykonane na dwóch maszynach wirtualnych (VMware Player 7.1.0), jedna z Nginx 1.6.2, druga z serwerem Apache 2.4.10.

Po każdym teście (2 wywołania) były restartowane odpowiednie usługi. Każda z maszyn posiadała następującą konfigurację:

  • 2GB RAM
  • 1, 2, 4 lub 8 rdzeni (sprzętowe wsparcie dla wirtualizacji VT-x, VT-d i EPT)
  • Debian 8 (RC 1)
  • Linux 3.16.0-4-amd64
  • PHP 5.6.6-2
  • Zend Opcache v7.0.4-dev
  • Varnish 3.0.6
  • Redis 2.8.17
  • MySQL 5.6.17
  • HHVM 3.6.0
  • Magento 1.9.1.0 + Sample Data
  • Magento Redis Session Cm_RedisSession
  • Magento Varnish PageCache powered by Varnish

Konfiguracja sprzętowa:

  • Procesor Intel i7-4710HQ 2.5GHz – 3.5GHz 4C/8T
  • RAM DDR3 1600MHz 16GB
  • Karta graficzna Intel HD 4600 + NVIDIA GeForce GTX 860M 4GB
  • Dysk twardy Samsung SSD 850 PRO 256GB

Testy zostały wykonane dla strony głównej Magento 1.9.1.0 + Sample Data z włączonym cache.

Varnish – HTTP reverse proxy

Prawdopodobnie wszystkie największe serwisy korzystają z tego akceleratora. Zasada działania jest bardzo prosta – polega ona na „pośredniczeniu” pomiędzy klientem a backendem (Apache, Nginx, itp.) – jest to tzw. odwrócony serwer proxy.

W przypadku gdy mamy dynamiczną stronę, która generuje jeden układ, pierwsze żądanie przechodzi przez serwer Varnish i trafia do backendu, skąd dane są pobierane i zapisywane w cache’u Varnisha.

Każde kolejne żądanie, pobierane jest już bezpośrednio z bufora proxy, bez odwoływania się do backendu.

dig1

Oczywiście w większości sytuacji, strony zawierają bloki o zmiennej treści, takie jak np. koszyk, logowanie, które uniemożliwiają pełne buforowanie strony.

Z pomocą przychodzi tutaj ESI (Edge Side Includes), umożliwiające buforowanie pojedynczych fragmentów stron. Cały mechanizm konfiguracji został oparty o Varnish Configuration Language (VCL). Pliki VCL są tłumaczone do C, kompilowane i ładowane bezpośrednio do akceleratora podczas uruchomienia. Definiujemy w nich scenariusze buforowania, definicje zwracanych nagłówków, reguły wyjątków i powiązań, itp.

W testach został użyty moduł PageCache powered by Varnish wspierający wersję 3. Aktualnie nie ma wsparcia dla wersji 4.

Poniżej porównanie maksymalnej wydajności Varnisha w wersji 3 i 4 w połączeniu z serwerem Apache na maszynie 8-rdzeniowej.

 

dig2

 

Widać tutaj różnice na poziomie ok. 50% na korzyść Varnish’a 4. W przypadku porównania PHP-FPM z serwerem Varnish 3 dla Magento, sytuacja wygląda następująco:

dig3

Różnica to ponad 1400% na korzyść odwróconego proxy.

Redis

Jest to serwer bazodanowy typu NoSQL przechowujący dane w pamięci RAM i operujący na rekordach typu klucz-wartość.

Znacząco zwiększa szybkość działania aplikacji, korzystających z sesji oraz systemu buforowania opartego o system plików, który jest jednym z najwolniejszych elementów serwera. Nawet dyski SSD, nie są w stanie dorównać pamięci RAM, która jest obecnie szybsza nawet o ponad 40-razy. Wyjątek stanowi tutaj np. produkt RamSan 5000.

Redis wspiera ponadto replikację oraz pracę w klastrach.

dig4

Na pierwszy rzut oka widzimy 10% wzrost wydajnosci na powyższym wykresie. Otóż wywołanie testu ab nie tworzy sesji po stronie Magento. Spróbujmy więc sprawdzić czy faktycznie otrzymamy wzrost wydajności korzystając z sesji.

W tym celu wyczyścimy bazę Redis i wygenerujemy zapytanie za pomocą polecenia telnet:

redis-cli flushall

telnet vms-nginx-mag.co 80

> GET / HTTP/1.1

> host: vms-nginx-mag.co

>

Na drugiej maszynie sprawdzamy ID sesji:

redis-cli

> SELECT 2

> KEYS *

1) sess_[KLUCZ]

Klucz w przypadku korzystania z MySQL znajduje się w tabeli core_session, a w systemie plików to katalog var/session/sess_[KLUCZ].

Mając te dane możemy wywołać ab z parametrem –C i naszym kluczem do sesji:

ab -n 1000 -c 100 -C ‚frontend=KLUCZ’ vms-nginx-mag.co/

Wyniki dla serwera Nginx, przedstawiają się następująco:

dig5

Jak widać wykorzystanie serwera Redis, nie przynosi zamierzonych wyników. Co więcej, daje najgorsze rezultaty! Prawdopodobnie jest to spowodowane błędną implementacją modułu do obsługi Redis’a.

 

HHVM – HipHop Virtual Machine

HHVM to maszyna wirtualna opracowana przez Facebooka, bazująca na kompilacji JIT i umożliwiająca wykonanie kodu napisanego w języku PHP i Hack.

Można ją jednocześnie uruchomić z usługą PHP-FPM (np. dla plików .php użyć PHP-FPM a dla plików .hh maszyny HHVM).

Cały proces uruchomienia skryptu, polega na przekształceniu kodu do HipHop bytecode (HHBC), który jest następnie tłumaczony na kod maszynowy x86-64, optymalizowany i natywnie wykonywany.

W przypadku bardzo skomplikowanego kodu PHP, możliwe jest osiągnięcie nawet ponad 14-krotnego wzrostu wydajności oraz znacznej redukcji zużycia pamięci.

Bardzo ciekawy case „Wikipedia on HHVM” ukazuje 45%-owy wzrost wydajności w porównaniu do PHP5 w środowisku produkcyjnym.

Poniżej porównanie maksymalnej wydajności Nginx’a z PHP-FPM i HHVM na maszynie 8-rdzeniowej dla pustego skryptu php, skryptu wykonującego pętle P1 oraz dla kodu Magento.

 

dig6

 

Dla Magento mamy:

 

Gdy skrypt nie ma dużych wymagań, HHVM nieznacznie przegrywa z PHP-FPM (ok. 10%). Sytuacja odwraca się diametralnie w momencie gdy skrypt robi się bardziej wymagający. Różnica dochodzi wówczas do ponad 1200%, na korzyść HHVM!

W przypadku Magento zauważamy ponad 3-krotny wzrost wydajności.

 

Pętla P1:

for ($i = 0; $i < 100000; ++$i) {

if ($i % 2) {

$j[] = $i * 1440 * 220 – 23;

}

else {

$k[] = $i * $i * time();

}

}

 

Apache mod_fastcgi i mod_proxy_fcgi + mod_proxy

Istnieje wiele sposobów na integracje serwera Apache z PHP-FPM, m.in.: mod_fcgid, mod_fastcgi, mod_proxy_fcgi i mod_authn_fcgi. Obecnie najpopularniejszymi są mod_fastcgi i mod_proxy_fcgi.

Trwają również prace nad mod_extfcgi, który jako jedyny będzie wspierał filtry (możliwość dodania dodatkowych danych do odpowiedzi). Poniżej krótkie porównanie mod_fastcgi i mod_proxy_fcgi.

 

dig8

Apache vs Nginx

Przy tej samej konfiguracji (PHP-FPM działający na porcie 9090), Apache nie jest w stanie wykonać testu ab -n 1000 -c 1000 (zaledwie po kilku requestach wyrzuca błąd!).

Nginx wykonuje ten test bez najmniejszych problemów i dopiero po 10 000 żądań zwraca błąd przy wywołaniu ab -n 100 000 -c 10 000…

W testach Magento, zwycięża Apache z przewagą 1%.

 

dig9

1, 2, 4, 8…

Ilość wykorzystywanych rdzeni ma znaczący wpływ na osiągane wyniki. Różnica pomiędzy 1 a 8 rdzeniami wynosi 309%. Trzeba pamiętać że konfiguracja sprzętowa to tylko 4 rdzenie.

 

dig10

Wyniki testów

Poniżej znajdują się pozostałe wyniki testów, z informacją o rodzaju testu, numerze wywołania (1 lub 2), liczbie użytych rdzeni i konfiguracji.

 

dig11

 

dig12

 

A + FPM + PROXY            Apache + PHP-FPM + Proxy Fastcgi

A+ FPM + FAST                 Apache + PHP-FPM + Fastcgi

A + HHVM                          Apache + HHVM

A + HHVM + REDIS          Apache + HHVM + Redis session

A + HHVM + REDIS + V  Apache + HHVM + Redis session + Varnish

N + FPM                              Nginx + PHP-FPM

N + HHVM                          Nginx + HHVM

N + HHVM + REDIS         Nginx + HHVM + Redis session

N + HHVM + REDIS + V  Nginx + HHVM + Redis session + Varnish

N + FPM + REDIS + V      Nginx + PHP-FPM + Redis session + Varnish

 

Podsumowanie

Osiągnięcie magicznej bariery 0,3s nie stwarza najmniejszego problemu, co wydawałoby się niemożliwe, biorąc pod uwagę wymagania jakie stawia Magento.

Najlepszym wyborem wydaje się być połączenie serwera Nginx z maszyną wirtualną HHVM i odwróconym serwerem proxy Varnish oraz sesją przechowywaną w bazie MySQL.
Przydatne linki:

Varnish – https://www.varnish-cache.org/
HHVM – https://github.com/facebook/hhvm
Redis – http://redis.io/
Nginx – http://nginx.org/
Apache – http://www.apache.org/

 

Chcesz przyspieszyć działanie swojej strony razem z Divante? Napisz do nas.