giovedì 20 marzo 2014

Php cache: APC + Memcached + custom

De multe ori, un site dinamic are unele portiuni din pagina care sunt identice pentru toate paginile si se schimba destul de rar. De exemplu: topul celor mai vandute produse, ultimele anunturi sau cei mai activi useri. Aceste statistici se populeaza din baza de date, deci necesita cate cel putin un query mysql la fiecare incarcare de pagina. Daca ne gandim ca query-ul intoarce aceleasi rezultate de fiecare data, ne dam seama ca acest lucru duce la o incarcare nejustificata a serverului mysql, ceea ce poate duce inclusiv la blocarea tabelelor sau la timpi f. mari de acces pentru celelalte query-uri, deci la timpi mari de incarcare a paginilor. Putem scapa de acest overload, prin stocarea rezultatelor intr-un cache si citirea/folosirea lor direct din cache, fara a mai interoga DB-ul.

Solutiile cele mai des folosite pentru acest lucru sunt APC si memcache, insa niciunul dintre aceste module nu face parte din PHP standard, deci firmele de hosting pot alege daca sa il instaleze sau nu. Din motive istorice, eu folosesc mai multe hostinguri:
- Godaddy - ofera APC, insa cu o calitate forte slaba (missing rate de 30%, vezi mai jos)
- Arvixe - ofera APC ok
- TsoHost - ofera doar Memcache, deoarece APC nu poate fi instalat pe suPHP


Tinand cont de faptul ca uneori vreau sa mut un site de la un hosting la altul si nu vreau sa schimb toata logica caching-ului, am fost nevoit sa contruiesc un set de functii generice. Aceste functii verifica daca modulele sunt disponibile si folosesc cea mai potrivita solutie, in felul urmator:
1. verifica daca mod_apc este instalat. Daca este instalat si nu este cerut explicit sa nu fie folosit APC (pentru godaddy), atunci apeleaza functiile APC.
2. daca este setat un server de Memcache, atunci apeleaza functiile memcache*
3. altfel apeleaza functii custom, scrise de mine, care stocheaza totul intr-un fisier.

* Biblioteca Memcached a fost conceputa pentru un singur user, deci nu are nici un fel de protectie a datelor. Un user poate citi/actualiza/sterge accidental sau voit, toate datele celorlalti useri. Trebuie mentionat ca acest lucru nu este f. simplu (caci trebuie sa afli intai numele variabilelor), insa eu am reusit sa le aflu folosind o pagina de statistici memcache, similara cu cea de la APC. Pentru ca nu vrem ca oricine sa se joace cu datele noastre, inainte de a stoca datele cu memcache, le serializez si criptez (serialize() + mcrypt_encrypt), iar dupa recuperare le decriptez si le deserializez (mcrypt_decrypt() + unserialize()). In felul acesta:
- orice user poate sa le vada, dar nu ii folosesc la nimic, decat daca stie key+iv, deci sunt sigur ca nu imi poate fura informatiile.
- De asemenea, daca cineva vrea sa le rescrie, poate, insa neavand parola, nu poate sa le encripteze la un sir valid, deci atunci cand incerc sa le folosesc, imi va da eroare si pur si simplu voi ignora acele date, ca si cum nu ar fi fost prezente in cache.
- Daca vrea sa le stearga, le poate sterge, insa nu e nici o pierdere. Eu le voi regenera fara probleme.

Cum folosesc functiile?
1. pentru fiecare set de informatii pe care le pun in cache, am construit cate o functie, cu parametri relevanti (gen limba, categorie...)
2. creez numele variabilei de pus in cache, pe baza numelui functiei+parametri. In felul acesta, asigur unicitatea si evit suprascrierea din greseala
3. verifica daca variabila se gaseste in cache. Daca da, atunci o folosesc.
4. daca nu e in cache, atunci:
   - generez valoarea variabilei, eventual intr-un array
   - salvez variabila in cache
   - folosesc variabila
In felul acesta, variabila este generata si stocata in cache doar daca nu este gasita in cache. In general, tin variabilele in cache pentru o ora.
Unele variabile (gen ultimele anunturi) trebuie sa expire inainte de termen. In acest caz, atunci cand "este adaugat un nou anunt", pur si simplu sterg variabila din cache. In acest fel, atunci cand voi avea nevoie de acea variabila, negasind-o in cache, o voi regenera, folosind evident date actualizate.

Download
Fisierul cu functiile construite de mine poate fi descarcat de aici. Fisierul contine instructiuni sumare de utilizare. Sper ca nu trebuie sa mentionez ca ar fi bine sa modificati key-iv... din motive de securitate.

Nessun commento:

Posta un commento