Mivel az elmúlt két hetet egy Drupal 7 Multisite (ráadásul Domain access multisite, sőt további ráadásul igazából egy Commerce Kickstart ) rendszer optimalizációjával töltöttem, most erről lesz szó. Kedvenc Windows 10-em megint félre kellett tennem 🙁
Mivel ez a terület nem ismert számomra teljesen, ezért ismét kimerítő dokumentáció és egyéb guide olvasással indítottam. Néhány dolog gyorsan kiderült. Sorolom:
- A teljes képet kevesen nézik. Magyarán, mi mire való és mitől lesz jó a végeredmény.
- Sokan keverik a szezont a fazonnal. php5-memcached vs memcache pl.
- Szokás szerint nincs normális, átfogó dokumentáció.
- A Drupal gyorsítás módja: Kerüljük el a Drupal-t 🙂 Mármint lehetőleg ne kelljen dolgoznia, mert az …nem gyors…
- Sok a párhuzamos, vagy máshogy mondva ugyanarra a feladatra való eszköz.
Elég sok összetevőből álló játék ez a PHP alkalmazás gyorsítás. Arra jutottam, hogy érdemes részegységekre szétbontani a problémát, hogy könnyebb legyen behatárolni, mi mire való és mik a teendők. Nem fogok step-by-step leírást készíteni mindenről. A cél csak az, hogy helyre tegyem a dolgokat. Íme a listám:
- Kód, végrehajtás (PHP) gyorsítás
- Adatbázis gyorsítás
- Web szerver – kiszolgáló gyorsítás
Nézzük sorban:
1.Kód, végrehajtás (PHP) gyorsítás
Első és legfontosabb, frissíteni kell a PHP-t! Az újabb PHP futtatók általában jelentős javulást hoznak a régebbiekhez képest. Ez nem csak nagyobb sebességben mutatkozhat meg (az 5.5 pl. kicsit lassabb mint az 5.3) hanem új képességekben vagy hatékonyabb memória használatban (az említett 5.5 pl. jóval kevesebb memóriát használ mint az 5.3)
Használjunk PHP gyorsítót!
PHP 5.5 OPcache / APC / APCu / Xcache 6 eAccelearator ?
Nagyon fontos! A fenti öt megoldás mind ugyanarra való! Egyet kell választani közülük! Itt található egy remek összehasonlítás: https://en.wikipedia.org/wiki/List_of_PHP_accelerators
Én szeretem az egyszerű megoldásokat. Néhány esetleg plusz százalék sebesség miatt nem forgatok fel egy rendszert sem, mert nagyobb lesz a veszteség az egyik oldalon mint a nyereség a másokon. Ennek fényében, természetesen a PHP 5.5 be immár beépített OPcache (ZEND Optimizer) használatára szavazok.
Bekapcsolni nem túl bonyolult, feltelepítés után ott vannak megfelelő „sorok” a php.ini-ben (Ubuntu -> php.ini, Centos opcache.ini) Windows/IIS rendszeren is működik: zend_extension=C:pathtophp_opcache.dll
Kb ennyi egy „sima” konfiguráció.
zend_extension=opcache.so
opcache.memory_consumption=256
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.enable_cli=1
opcache.enable=1
Aztán persze bőven lehet még kísérletezni az optimális megoldással, a szabad memória függvényében pl.
Használjuk a memóriát!
Na itt aztán nagy a káosz!
Memcached, php-memcached, php-memcache! Mik ezek, mire valók?
- Memcahed PHP nélkül!
Ez a memcache daemon. Egy általános, univerzális „tároló” a memóriában. Használhatja sok minden (mysql 5.6, php, pagespeed stb)
Nevezzük memcached szolgáltatásnak! - PHP-memcache
Az PHP modul, ami lehetővé teszi, hogy PHP-ból használjuk a Memcached szolgáltatást. - PHP-memcached
MEGLEPETÉS! Ez is! Az PHP modul, ami lehetővé teszi, hogy PHP-ból használjuk a Memcached szolgáltatást.
A php-memcached egy újabb vagy mondjuk inkább, hogy más által fejlesztett megoldás a memcached szolgáltatás használatához PHP környezetből. A kettő közül egyet kell választani. A tesztek szerint a php-memcached picit gyorsabb és többet is tud.
Nagyon fontos, hogy a memcached és a php-memcached feltelepítése és konfigurálása önmagában semmilyen sebesség növekedést nem fog hozni! Ehhez a szolgáltatáshoz a webalkalmazást hozzá kel igazítani! Az én esetemben fel kell telepíteni a Druapal-ra Memcache API and Integration vagy (igen, itt is kettőből lehet választani) a Memcache Storage nevű modult.
PHP-FPM
Jelenleg a leggyorsabbnak tűnő PHP feldolgozási megoldás a PHP-FPM szolgáltatás használata. Alternatív megoldások: Fast-CGI, CGI, Mod-PHP, SuPHP
A PHP-FPM egy folyamatosan futó szolgáltatás aminek oda lehet „dobni” a feldolgozandó PHP kódot, ami aztán visszaad. Az NGINX php proxy-nak hívja.
2. Adatbázis gyorsítás
Ez nem más mint MySql finomhangolás. Valójában ez külön tudomány és én csak a felszínt karcolgatom, de azért megmutatom mire jutottam.
A legfontosabb, hogy manapság már a MyIsam motor helyett az InnoDB a preferált.
Elméletben az InnoDB lassabb, de ez csak elmélet. A gyakorlatban jobban teljesít, mert: csak sorokat zárol, nem a teljes táblát, kezel tranzakciókat és ott van persze a Referential Integrity / foreign keys támogatás
Aztán persze kell némi finomhangolás a my.cnf-ben.
Ezen a szinten persze csak favágásról beszélhetünk, de MyIsam tábláknak főleg ezeket érdemes állítgatni: (8GM RAM és 8 CPU mag mellett ez a konfigom)
key_buffer = 1024M <-ez talán a legfontosabb.
max_allowed_packet = 64M
thread_stack = 512K
thread_cache_size = 8
table_cache = 50
thread_concurrency = 8
Nos, erről rengeteg vita manapság:
query_cache_limit = 512K
query_cache_size = 32M
Az InnoDB „nem szereti” ezt a dolgot. MySql 5.6-tól alpértelmezetten ki van kapcsolva. Helyette ugye itt is Memcached-et kellene használni, ami egy pugin a MySQL 5.6-tól.
Csakhogy itt is igaz ami a PHP – memcached páros esetén: Csak akkor hoz sebességnövekedést, ha felkészítjük az alkalmazásunkat a használatára.
Szóval nálam egyelőre marad a query_cache, de figyelni, kell rá, hogy ne állítsuk túl nagyra, mert az inkább káros mint hasznos.
InnoDB beállítások:
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 1024M <- legyen „NAGY”
innodb_log_file_size = 256M <- legyen a buffer_pool 25%-a
innodb_log_buffer_size=2M
Továbbá érdemes bekapcsolni a slow loggingot és lesni, hogy mi lassú. Ez a script is jól jön az optimalizációhoz:: http://mysqltuner.com/
Web szerver – kiszolgáló gyorsítás
Na ebbe aztán mindenféle dolog beletartozik.
Eleve lehetőleg a leggyorsabb webszervert érdemes használni. Ez lehet apache 2.4, de lehetőleg NGINX. IIS kérdésbe most nem megyek bele. Ott is van jó megoldás, de az egy külön műfaj 🙂
Aztán mondom még mi merülhet fel itt: Varnish Cache, Tömörítés, CSS, Java tömörítés, optimalizálás – Pagespeed, FastCGI cache és persze a megfelelő webszerver konfiguráció.
NGINX
Az NGINX ugye eleve jobb statikus fájok kezelésében és főleg erőforrás gazdálkodásban. Mindenekelőtt úgy kell beállítani a webszervert, hogy lehető legkevesebb alkalommal „forduljon” a webalkalmazáshoz (esetemben ugye a Drupal-hoz -> kerüljük el a Drupal-t ugye)
Mit jelent ez? Hogy kellene működni a webszervernek? Megpróbálok egy egyszerű „folyamatábrát” mutatni:
KÉRÉS -> Felesleges/amúgy is tiltott fájlokat ne szolgáljunk ki és ha nem szükséges ne is logoljunk -> ha statikus fájlról van szó ne kérdezzük meg a webalkalmazást, hanem csak toljuk oda a kliensnek a fájl -> ha lehet cache-ből -> azért ügyeljünk a biztonságra is -> ami nem megy máshogy dobjuk oda a webalkalmazásnak (try_files $uri /index.php) -> és itt is használjunk még FastCGI cache-t
Ez az NGINX által javasolt „basic” beállítás Drupal 7-hez:
Csak azért teszem ide, hogy egy-két dolgot értelmezzek
server {
server_name example.com;
root /var/www/drupal7;
#Ha nincs favicon nem logolunk
location = /favicon.ico {
log_not_found off;
access_log off;
}#Ahol nem kell ne akarjunk PHP fájlokat feldolgozni
location ~ ..*/.*.php$ {
return 403;
}
#Druapal privát fájok védelme
location ~ ^/sites/.*/private/ {
return 403;
}# Rejtett fájlok blokkolása.
location ~ (^|/). {
return 403;
}
#Standard szabály, próbáljuk „kiszolgálni”,
#ha nem megy dobjuk az index.php-nek
location / {
try_files $uri /index.php;
}
#A @ kezdetű location-ok amolyan horgony-ok
location @rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
}
#PHP fájlokat dogozza fel a PHP-FPM
location ~ .php$ {
fastcgi_split_path_info ^(.+.php)(/.+)$;
#NOTE: You should have „cgi.fix_pathinfo = 0;” in php.ini
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_intercept_errors on;
fastcgi_pass unix:/tmp/phpfpm.sock;
}#Stílus fájlokat megpróbáljuk statikusa
#és ha nem megy mehet a Drupal-nak
location ~ ^/sites/.*/files/styles/ {
try_files $uri @rewrite;
}
#Statikus fájlokat közvetlenül szolgáljuk ki és használunk cache-t is
location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
open_file_cache max=3000 inactive=120s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
}
}
A témában (Drupal – NGINX) egyébként Persurio NGINX konfigja az abszolút etalon
NGINX FastCGI cache
Az NGINX webszerver (természetesen ezt érdemes használni használni Apache helyett, mert amúgy is gyorsabb) egy speciális képessége, hogy a PHP futtatótól visszakapott dinamikus tartalmat képes cachelni. Ez FasCGI caching.
Már a leírásból is látszik, hogy eléggé vigyázni kell ezzel a megoldással, kiváltképp olyan rendszerek esetén, amiket hitelesített felhasználók is használnak. Könnyen hibás működés, adatszivárgás lehet a dolog vége.
Ha egy szerveren több alkalmazás fut, akkor azokat teljesen el kell különíteni FastCGI cache tekintetében.
A másik nagyon fontos paraméter a fastcgi_cahe_key. Ezzel lehet elszeparálni egymástól a hitelesített felhasználókat pl. a cookie belekeverésével.
A bekapcsolás első lépése egy, a következőhőz hasonló kód elhelyezése a „szerver” blokkon kívül az nginx.conf fáljban:
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=EGYEDI_ALKALMAZÁS_NÉV:100m inactive=60m;
map $http_cookie $cache_uid {
default 0;
~SESS[[:alnum:]]+=(?<session_id>[[:alnum:]]+ $cache_uid) ;
}
fastcgi_cache_key „$cache_uid$scheme$request_method$host$request_uri”;
Következő lépésben oda kell beszúrni minimum ezt a kódot, ahol feldolgozzuk a php fájlokat. Jellenzően:
location ~ .php$ {
…
fastcgi_cache MYAPP;
fastcgi_cache_valid 200 60m;
…
}
Aki komolyan akarja venni dolgot, az utána olvashat pl itt: https://serversforhackers.com/nginx-caching/
Google Pagespeed
A webszerverbe beépíthető a Google Pagespeed modul ami számos optimalizációval járul hozzá az oldal sebességéne növeléséhez. Apache webszerver esetén egy gyakorlatilag csak abból áll, hogy letöltjük és bekapcsoljuk. NGINX esetén viszont kézzel kell fordítani egy NGINX webszervert és utána lehet aktiválni a Pagespeed modult. Nem olyan bonyolult mint hangzik. A fenti linken rendesen dokumentálva vannak a teendők.
Érdekesség, hogy a Pagespeed is kombinálható a Memcached szolgáltatással, így jobb teljesítmény érhető el.
HTTP Cache – Varnish
Egy magára valamit is adó lassú webalkalmazás előtt van cache. Ebben a műfajban talán a Varnish a legjobb. A tartalom cache gyors és tehermentesíti a szervert (kisebb processzor és memória terhelés) de számos problémát is felvet. Mikor járjon le a gyorstárban tárolt tartalom? Mit lehet a gyorsítótárban tartani és mi nem? A Drupal rendszerhez pl. létezik Varnish modul, hol részletesen konfigurálható, hogy mikor mi történjen (pl. milyen Drupal eseményre törlődjön a Varnish cache). A Varnish-nak ilyenkor a default 80-as porton kell figyelni és továbbdobni a gyorsítótárban nem található vagy nem gyorsítótárazandó kéréseket a valamilyen egyéb porton (pl. 8088) figyelő webszervernek.
Természetesen nem csak Varnish használható erre a célra. Sokan pl magát az NGINX-et használják erre, sőt van aki csak erre, egy Apache előtt.
Bónusz – Drupal megoldások
Ez a fejezet nem szerepel a listában, mert ezek Drupal specifikus megoldások.
- ADVAGG
- File Cache
- Boost
- Image LazyLoader
- Fast 404
- AuthCache
- Cache Expiration
- Varnish
- Cache Warmer
- Memcache API and integration
Ezek közül egy csomó gyakorlatilag ugyanarra való másokat nagyrészt helyettesít a Google Pagespeed. Meg kell gondolni mit csinálunk!
Nekem a következő kombináció vált be PHP OPcache, PHP-FPM, Nginx, Drupal Memcache API, Boost, Pagespeed
Az NGINX FastCGI cache nagyon ígéretes, de igencsak macerás jól megcsinálni. Még várok vele.