Varnish: érd el a maximális oldalbetöltési sebességet!

Mielőtt belefognánk…

A webről érkező kérések kezelése (különösen, ha dinamikusak) a webszervereken (pl. Apache) a rendszer-erőforrásokat igencsak igénybe veheti, emiatt egyre többen kezdték használni a könnyűsúlyú webszervereket (pl. ngix, nginx vagy lighttpd). Ezek az Apache rendszerrel összekötve statikus tartalomnál frontendként, vagy önállóan is működhetnek.

Azonban a weboldalad vagy webshopod javítására létezik egy másik módszer is: használhatsz webszerever-gyorsítót, mint a Varnish Cache, melyet a Varnish Software fejlesztett.

A Varnish Cache folyamatainak ismerete többféleképpen is elsajátítható: Varnish Book olvasása, Hivatalos dokumentáció, sok gyakorlás és kísérletezés. Különösen ajánlott az első kettővel kezdeni. Ennek a cikknek az anyaga mindegyik forrásból merít: pl. stackoverflow-n és más szakmai oldalakon található anyagokból, valamint személyes tapasztalatból is.

 

Mi a Varnish?

 

A VARNISH: egy nyílt forráskódú, fordított HTTP proxy cachelési szoftver, olykor webapplikáció-gyorsítóként is említik. A fordított proxy egy olyan proxy szerver, amely a látogatók számára egy szokásos szervernek tűnik. A memóriában fájlokat vagy részállományokat tárol (cache-el), melynek köszönhetően lecsökken a válaszidő és a hálózati sávszélesség-használat.

A Varnish Software szakmai támogatást is nyújt a Varnish-t használatához, amit egyébként egy kétzáradékos BSD-licensz szabályoz. A Varnish 1.0 2006-ban, a Varnish 2.0 2008-ban, a Varnish 3.0 2011-ben, a Varnish 4.0 pedig 2014-ben jelent meg.

A Varnis igen rugalmas, hiszen saját magad tudod hozzá megírni a cache-elési eljárást a Varnish Konfigurációs Nyelven (Varnish Configuration Language /VCL/), ami egy C nyelven alapuló alkalmazásspecifikus nyelv. Ez később aztán C kóddá fordul kompilálás előtt.

 

Hogyan működik a Varnish?

 

Tegyük fel, hogy a látogató egy kérést küld a szerveredre. Ezt először a Varnish kapja meg és a gyorsítótárban keres rá választ: ha talál érvényes tartalmat, akkor elküldi válaszként, ha nem, akkor továbbítja a kérést a backend felé. A backend válaszát a gyorsítótárba helyezi, aztán elküldi a látogatónak. Így ha legközelebb ugyanaz a kérés érkezik, már lesz kész válasz a gyorsítótárban.

Ezt a folyamatot egy egyszerű ábrán is szemléltethetjük:

 

varnish cache folyamat

 

A Varnish telepítése és alap konfigurálása

 

A Varnish legkönnyebben a szervered csomagkezelőjével tudod telepíteni, de ott lehet, hogy nem a legfrissebb verziója lesz elérhető. Ha a legfrissebb verziót szeretnéd, ahhoz is könnyen találhatsz megfelelő bináris csomagokat vagy forgathatsz egyet forráskódból; a hivatalos oldalról letölthető az aktuális verzió. Az egyszerűség kedvéért a példáink csomagkezelő használatát feltételezik, például a Debian 8 („Jessie”) rendszereken elég begépelni ezt:

 

[code]

apt-get install apt-transport-https
curl https://repo.varnish-cache.org/GPG-key.txt | apt-key add -
echo "deb https://repo.varnish-cache.org/debian/ jessie varnish-4.1" >> /etc/apt/sources.list.d/varnish-cache.list
apt-get update
apt-get install varnish

[/code]

Ha forrásból állítod össze, ellenőrizd, hogy a függőségek már jelen legyenek és nézd át a hivatalos dokumentációt is.

A következő lépés a konfiguráció. Először nézzük a konfigurációs fájlt:

/etc/default/varnish (Debian)

/etc/sysconfig/varnish (Red Hat)

 

Jó néhány hasznos és fontos beállítást találunk itt a Varnish daemonra vonatkozóan, mint pl. zárolt megosztott memória, alap TTL, szálak száma stb.

Nézzünk egy egyszerű példát:

[code]

NFILES=131072
MEMLOCK=82000
NPROCS="unlimited"
RELOAD_VCL=1
VARNISH_VCL_CONF=/etc/varnish/default.vcl
VARNISH_LISTEN_PORT=6081
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
VARNISH_SECRET_FILE=/etc/varnish/secret
VARNISH_MIN_THREADS=10
VARNISH_MAX_THREADS=50
VARNISH_THREAD_TIMEOUT=120
VARNISH_STORAGE_SIZE=128M
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"
VARNISH_TTL=120
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
             -f ${VARNISH_VCL_CONF} \
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
             -t ${VARNISH_TTL} \
             -p esi_syntax=0x2 \
             -p cli_buffer=16384 \
             -p http_resp_hdr_len=131072 \
             -p thread_pools=4 \
             -p thread_pool_add_delay=2 \
             -p thread_pool_min=15 \
             -p thread_pool_max=50 \
             -p thread_pool_timeout=3600 \
             -u varnish -g varnish \
             -S ${VARNISH_SECRET_FILE} \
             -s ${VARNISH_STORAGE}"

[/code]

Ezek a beállítások a Varnish háttérfolyamatára vonatkoznak, a cache-elés folyamatát és a kérések kezelését a VARNISH_VCL_CONF-ban meghatározott .vcl fájl írja le. A cache kezelést egy C-szerű nyelven, a VCL-en írhatjuk meg; ez C-re fordítható és bináris kóddá áll össze; akkor aktiválódik, amikor a kérések beérkeznek. Ennek köszönhetően a Varnish nem csupán cache-elési szempontból tekinthető egy erős HTTP processzornak, használhatjuk még terheléskiegyenlítésre, vagy akár egyszerű tűzfalnak is. A következőkben ezt részletesebben átvesszük.

 

Nézzük meg közelebbről!

 

Vegyük át részletesebben, hogyan működik a kérés feldolgozása a Varnish v4-ben.

Legelőször vessünk egy pillantást a Varnish Finite State Machine ábrájára, amely szemlélteti a folyamatokat:

 

varnish folyamatok

VCL_RECV

Ez a folyamat legeleje, mely közvetlenül a kérés fogadása és elemzése után kerül meghívásra. Meghatározza a további lépéseket a bejövő kérésekkel kapcsolatban: megváltoznak-e, cache-elve lesznek-e vagy sem, lesz-e valami továbbítva a backend-nek feldolgozásra vagy csak egy választ küldünk a gyorsítótárból, stb.?

 

VCL_HASH

A vcl_recv után hívódik meg. A kéréshez egy hash értéket hoz létre, ami a gyórsítótárban tárolt Varnish objektum azonosító kulcsa (lesz); majd a vcl_recv eredményétől függően más függvények felé továbbítja a kérést.

 

VCL_HIT

Akkor kerül meghívásra, ha a gyorsítótárban van a vcl_hash-ben generált azonosítónak megfelelő tartalom. Eredménye meghatározza, hogyan kezeljük a kérés további részét.

 

VCL_MISS

Akkor kerül meghívásra, ha a gyorsítótárban nincs megfelelő tatalom vagy ha a vcl_hit visszautasította/küldte a betöltést.

 

VCL_PASS

A pass mode-ba való belépéskor kerül meghívásra. Ebben a módban a kérés a backend felé továbbítódik, és a backend válasza a klienshez érkezik, de nem kerül bele a cache-be.

 

VCL_PIPE

A pipe mode-ba való belépéskor kerül meghívásra. Ebben a módban a kérés a backendhez kerül, és minden további adat, akár a klienstől, akár a backendtől származik, változatlanul továbbításra kerül, amíg a kapcsolat egyik vége be nem zárul.

 

 

Backend szerverek

A fenti leírásokban számos alkalommal esett szó a backend-ről. A Varnish szaknyelvében a „backend” bármilyen szervert jelenthet, amely a Varnish számára cache-elhető tartalmat nyújt és amelyet a Varnish felgyorsít.

Egy backend kiszolálgó elérését a .vcl fájlban deifniálhatjuk:

 

[code]

backend default {
        .host = "127.0.0.1";
        .port = "8080";
}

[/code]

 

A való életben találkozhatunk szerverösszeomlásokkal és egyéb backend problémákkal. A folyamatos működés biztosításához, meghatározhatunk egy paramétercsoportot (probe néven), amely a backend állapotát ellenőrzi.

[code]

backend default{
        .host = "127.0.0.1";
        .port = "8000";
        .probe = {
                .url = "/alive/";
                .timeout = 2s;
                .interval = 3s;
                .window = 10;
                .threshold = 9;
        }
}

[/code]

 

Ha ezt a paramétercsoportot beállítjuk, akkor a Varnish egy egyszerű GET kérést fog küldeni minden 3. másodpercben az „/alive/” url-nek, 2 másodperces időtúllépési limittel. Mivel az „ablakot” 10-re, a „küszöböt” pedig 9-re állítjuk, a backend egészségesnek minősül, amennyiben az utolsó 10 kérésből legalább 9 sikeresnek bizonyult. A Varnish nem küld adatokat olyan hosztoknak, amelyek nem megfelelő állapotúak.

Így amikor a Varnish-nak tartalomra van szüksége – az alap backend kapcsolatnak köszönhetően – tudja majd, hol találja. De mi a helyzet akkor, ha több backend szerverrel rendelkezünk vagy külön módszerünk van bizonyos kérések kezelésére? Új backendet-et határozhatunk meg (magic néven) és új szabályt adhatunk meg a kérések feldolgozásához:

 

[code]

backend magic {
        .host = "127.0.0.1";
        .port = "8000";
}
...
sub vcl_recv {
        if (req.url ~ "^/magic/") {
                set req.backend_hint = magic;
        } else {
                set req.backend_hint = default;
        }
}

[/code]

 

Szabadon megválasztható, hogy milyen módszerrel határozzuk meg egy kéréshez a backendet – szabályok mentén, paraméterek mentén vagy véletlenszerűen. Ezenkívül több backend szerver is csoportosítható egy „director”-ban. Ehhez be kell tölteni egy VMOD-ot (egy Varnish modult), majd meghívni bizonyos műveleteket a vcl_init-ben.

 

[code]

import directors;    # load the directors
 
backend default {
        .host = "127.0.0.1";
        .port = "8080";
}
backend magic {
        .host = "127.0.0.1";
        .port = "8000";
}
 
sub vcl_init {
        new foobar = directors. round_robin();
        foobar.add_backend(default);
        foobar.add_backend(magic);
}
 
sub vcl_recv {
        set req.backend_hint = foobar.backend();
}

[/code]

Ez a módszer segít, hogy a Varnish-t terhelés-optimalizálásra használhassuk. Itt egy „round-robin director”-t használunk, de létezik egy „random director”, amely véletlenszerűen osztja el a kéréseket.

 

Edge Side Includes (ESI)

Olykor szükség van rá, hogy egyedi információt jelenítsünk meg minden egyes felhasználónak, pl. felhasználónév, kosár tartalma, korábban rendelt termékek listája stb. Ezeknek az adatoknak a cache-elése komoly problémát okozhat, ezért a Varnish-ban alkalmazott ESI blokkok különösen hasznosak.

Az ESI használatával az oldalunkat kisebb részekre oszthatjuk és eldönthetjük, ezekből melyik legyen cache-elve és melyik ne, majd ezekből állíthatjuk össze a választ. Ezeknek a részeknek külön cache beállításai lehetnek. Például, ha van egy listád a webáruházadban lévő 5 legnépszerűbb termékkel, ezt a listát valószínűleg elég egyszer cache-elni és így szerepeltetni más oldalakon, míg más részek esetleg soha nem kerülnek cache-elésre és mindig dinamikusan kell betölteni azokat.

 

varnish esi diagram

 

Ezzel a stratégiával növelheted a találati arányodat és csökkentheted a szerverek terhelését.

Az ESI csupán egy kis részét használja a Varnish teljes funkcionalitásának, ám ez is elegendő. Három ESI utasítást (statements) használhatunk:

  1. esi:include
  2. esi:remove
  3. <!–esi …–>

A Varnish nem dolgozza fel az ESI instrukciókat HTML kommentekben (comments).

Lássunk néhány példát.

 

ESI:include

Az alábbiakban egy egyszerű példát írunk le, ez a user.php fájl:

<?php
…
// Including some libraries
..
$user = $this->getUser();
echo $user->getName();
?>

 

 

Most nézzünk egy HTML fájlt, mely egy ESI include statement-tel rendelkezik. Ez a test.html:

<HTML>
    <BODY>
        Hello <esi:include src="user.php"/>!
    </BODY>
</HTML>

 

Az utolsó lépés az ESI élesítésére az ESI feldolgozás aktiválása VCL-ben.

[code]

sub vcl_backend_response {
        if (bereq.url == "/test.html") {
               set beresp.do_esi = true;
               set beresp.ttl = 24 h;   
        } elseif (bereq.url == "/user.php") {
               set beresp.ttl = 1m;
        }
}

[/code]

 

 

ESI:remove and <!–esi … –>

 

Mit csináljunk, ha az ESI nem áll rendelkezésre, mert nincs mondjuk engedélyezve? Erre az esetre ott vannak az <esi:remove> és <!–esi … –> konstrukciós műveletek. Ezeket bármikor lehet használni tartalmak megjelenítésére, akár él az ESI, akár nem. Például megadhatsz konkrét tartalmat akkor, ha az ESI rendelkezésre áll, és linkelhetsz rá, ha nem.

A “<!–esi” és az ending “-→” tag-eket az ESI feldolgozók eltávolítják az oldal feldolgozásakor, de a köztük levő tartalmat nem. A szintaxis miatt a feldolgozatlan esi tag-ek HTML/XML kommentként működnek.Az <esi:remove> tag-eket az ESI processzorok eltávolítják minden köztük lévő lévő tartalommal együtt.

Például:

<esi:remove>
  <a href="http://www.example.com/LICENSE">The license</a>
</esi:remove>
<!--esi
<p>The full text of the license:</p>
<esi:include src="http://example.com/LICENSE" />
-->

 

Ahogy a péládból is látszik, ezekkel a tagekkel megoldható, hogy dinamikus blokk tartalma jelenjen meg amikor van ESI feldolgozás és egy egyszerű link amikor az ki van kapcsolva.

 

Kik használják a Varnish cache -t?

 

A Wikipédia szerint a világ 10 ezer leglátogatottabb oldalának mintegy 10%-a használja a Varnish-t – hírportálok, közösségi oldalak, médiaoldalak stb. Néhány fontosabb ezek közül: Wikipédia, Facebook, Twitter, Vimeo, The New York Times, The Guardian, The Hindu, Tumblr.

 

A Varnish használata a Magento-nál

 

A Magento a világ legnépszerűbb e-kereskedelmi platformja. Híres rugalmasságáról, de a gyorsaságáról már kevésbé. Ha a Varnish-t Magento 1-hez szeretnéd használni, keress egy külső modult, vagy, ha időd engedi: csináld magad. Ez esetben meg kell tanulnod a Magento használatát, értened kell a HTTP Headerekhez, valamint a fordított proxy cache-eléshez és a Varnish Cache-hez is.

"Csupán két nehéz dolog van a számítástechnikában: a cache érvénytelenítés és az elnevezés."Phil Karlton

A Magento 2 esetében könnyebb a helyzet. A Magento 2 hivatalosan is támogatja a Varnish 3.0.5 és frissebb verzióit és bármely 4.x verziót. Elég, ha követed az útmutató dokumentáció lépéseit, de itt most össze is foglaljuk neked a főbb pontokat:

  • Telepítsd a Varnish-t és teszteld egy tetszőleges Magento oldal megnyitásával, hogy lásd, kapsz-e a válasszal egy HTTP header-t, amely jelzi, hogy a Varnish működik.
  • Telepítsd a Magento szoftvert és a Magento adminisztrációs felületén hozz létre egy Varnish konfigurációs fájlt.
  • Cseréld le a már létező Varnish konfigurációs fájlt az adminban létrehozott fájlra.
  • Tesztelj ismét mindent, és ha semmit sem látsz a /var/page_cache könyvtárban, sikeresen konfiguráltad a Varnish-t a Magento-ban!

Végül érdemes megjegyezni, hogy a saját (vagy ügyfeleidé, ha másoknak fejlesztesz) webáruháza legyen az utolsó hely, ahol az új VCL/PHP kódokat teszteled!

 

 

3 válaszok

Trackbacks & Pingbacks

  1. […] A Varnish szoftver működésébe ebben a cikkben nem mélyednénk bele, azonban itt bővebben is olvashatsz róla. […]

  2. […] Varnish egy frontend cache szolgáltatás, mellyel hatékonyan lehet gyorsítani weboldalaink betöltési […]

  3. […] gyorsítótár (cache) megoldás a dinamikus tartalmak kiszolgálására, amiről már egy korábbi cikkünkben részletesen […]

Hagyjon egy választ

Want to join the discussion?
Feel free to contribute!

Vélemény, hozzászólás?

Az email címet nem tesszük közzé.