Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [art] php i Memcached
Forum PHP.pl > Inne > Oceny
Riklaunim
Napisałem artykuł opisujący możliwości zastosowania memcached z poziomu php smile.gif
Link: php i Memcached

Testów wydajnościowych jeszcze nie robiłem ale mam w planach smile.gif
nrm
najs, to porównaj to wtedy do wykorzystania PDO z keszem do pliku (serializacja). Mam wrażenie, że ten drugi sposób jest równie wydajny a przyjemniejszy w użyciu (jeżeli chodzi o cache zapytań). chętnie obejrzałbym wyniki takich testów.
Riklaunim
RAM jest szybszy od I/O na dysku i dodatkowo serializacją/deserializacją winksmiley.jpg ale trochę testów będzie.
nrm
teoretycznie tak winksmiley.jpg praktycznie to różnie bywa. jak pisałem wyżej: daj znać jak będziesz robił testy, pewnie będą bardzo ciekawe.
Bastion
Po pierwsze - po co to kiedy jest shmop http://pl.php.net/manual/pl/ref.shmop.php

Po drugie - większe prawdopodobieństwo, że firma hostingowa zgodzi się zainstalować
oryginale rozszerzenie, które jest razem z php poprzez --enable-shmop, niż zajmie się
instalacją rozszerzeń "trzecich", w dodatku wymagających dziwnych, mało znanych zależności
typu :

- konieczność posiadania libevent
- konieczność posiadania serwera cache memcached
- wymagana opbsługa epol w jądrze - z małym ale jądra 2.4 tego nie mają - trzeba więc je patchować

Po trzecie - serwer memcached musi byc uruchomiony w tle ( uruchomiona przez użytkownika )
więc wypada mieć shella - wyjątek stanowi, praca jako użytkownik nobody , uruchomiona przez admina.

Po czwarte, brak możliwości hashowania nazwy klucza pod jakim ma być zapisany nasz cachowany obiekt,
skutkuje to tym, że każdy będzie mogł odczytać zawartość cache, znając tekstowy klucz. Dodatkowo więc
wypadałoby napisać aggregato, który będzie zamieniał nam nasze klucze tworząc unikatowy hash.

Po piąte, łączenie się z serwerem cache, nawet po localhoscie jest wolniejsze niż odczyt z dysku metodą
unserialize(file_get_contents(....));

Po szóste, cache obiektów, zapytań SQL - w ogóle nie ma sensu z zasadniczych powodów

- obsługa FS w php i tak jest cacheowana (duża więc wydajność sama w sobie odczytu danych z dysku)
- podbnie zapytania SQL w bazach MySQL i podobnych równie jest cachowana

Po siódme, wyniki mówią same za siebie :

Testowi poddałem 32kB plik tekstowy zawierający tekst Lorem Ipsum (48 linii), plik należało pobrać do tablicy
i poddać procesowi cachowania.

Na ogień poszły 3 metody

1) Na dysku twardym poprzez unserialize(file_get_contents())
2) Używając rozszerzenia SHMOP z wykorzystaniem klasy Class5.Mnemonic
3) Używając rozszerzenia MemCache

Test 2 i 3 wykonano dwoma sposobami - 1 sposób to jednokrotna inicjacja obiektu, 2 sposób wielokrotna inicjacja obiektu

Jak przechowano dane :

  1. <?php
  2.  
  3. require_once('../libs/class5.mnemonic.php');
  4.  
  5. $lorem_ipsum = file('lorem.txt');
  6.  
  7. // Cache Mnemonic
  8. $cache = new Mnemonic();
  9. $cache -> store('lorem', $lorem_ipsum);
  10.  
  11. $memcache = new MemCache();
  12. $memcache -> connect('localhost', 11211);
  13. $memcache -> set('lorem', $lorem_ipsum, false);
  14.  
  15. // Cache Traditional
  16. file_put_contents('cache/lorem.cache', serialize($lorem_ipsum));
  17.  
  18. ?>


Jak testowano :

  1. <?php
  2.  
  3. require_once('../libs/class5.mnemonic.php');
  4.  
  5. $passes = 3;
  6. $iteration = 1000;
  7.  
  8. $s = microtime(true);
  9. $cache = new Mnemonic();
  10. for ($j = 0; $j < $passes; $j++)
  11. {
  12. for ($i = 0; $i < $iteration; $i++)
  13. {
  14. $wynik = $cache -> get('lorem');
  15. }
  16. }
  17. echo 'Class5.Mnemonic (SHMOP Extension) #1 : '.((microtime(true)-$s)/$passes).'<br />';
  18.  
  19. $s = microtime(true);
  20. for ($j = 0; $j < $passes; $j++)
  21. {
  22. for ($i = 0; $i < $iteration; $i++)
  23. {
  24. $cache = new Mnemonic();
  25. $wynik = $cache -> get('lorem');
  26. }
  27. }
  28. echo 'Class5.Mnemonic (SHMOP Extension) #2 : '.((microtime(true)-$s)/$passes).'<br />';
  29.  
  30. $s = microtime(true);
  31. $memcache = new Memcache();
  32. $memcache -> connect('localhost', 11211);
  33. for ($j = 0; $j < $passes; $j++)
  34. {
  35. for ($i = 0; $i < $iteration; $i++)
  36. {
  37. $wynik = $memcache -> get('lorem');
  38. }
  39. }
  40. $memcache -> close();
  41. echo 'Memcache #1 : '.((microtime(true)-$s)/$passes).'<br />';
  42.  
  43. $s = microtime(true);
  44. for ($j = 0; $j < $passes; $j++)
  45. {
  46. for ($i = 0; $i < $iteration; $i++)
  47. {
  48. $memcache = new Memcache();
  49. $memcache -> connect('localhost', 11211);
  50. $wynik = $memcache -> get('lorem');
  51. $memcache -> close();
  52. }
  53. }
  54. echo 'Memcache #2 : '.((microtime(true)-$s)/$passes).'<br />';
  55.  
  56. $s = microtime(true);
  57. for ($j = 0; $j < $passes; $j++)
  58. {
  59. for ($i = 0; $i < $iteration; $i++)
  60. {
  61. $wynik = unserialize(file_get_contents('cache/lorem.cache'));
  62. }
  63. }
  64. echo 'file_get_contents Unserialize : '.((microtime(true)-$s)/$passes).'<br />';
  65.  
  66.  
  67. ?>


Wyniki :

Cytat
Class5.Mnemonic (SHMOP Extension) #1 : 0.15039666493734
Class5.Mnemonic (SHMOP Extension) #2 : 0.12634968757629
Memcache #1 : 0.22323632240295
Memcache #2 : 0.55660033226013
file_get_contents Unserialize : 0.090231021245321


Jak widać Memcache wypadł najgorzej... można powiedzieć okropnie.

Jednak jest sens wykorzystania pamięci , ale nie w takim obrazie jak przedstawiono,
sens jest , gdy jednocześnie cacheujemy znaczne ilości danych, ale nie jakby się mogło
wydawać rozmiarowo ( kilka plików po kilkaset kB ), a setki/tysiące plików po kilkaset bajtów
lub parę kilobajtów. Jak wiadomo przewagą jest tu czas dostępu I/O ( czyli mam na myśli
tworzenie, kasowanie, odczytywanie, modyfikacja ). Dlatego sensem jest cachowanie
np. systemów szablonów, warstw danych, lub umieszczanie w pamięci shared memory
(memcached tego nie umożliwia), źródeł skryptów php.

Wtedy wyniki prezentują sie nieco odmiennie

Cytat
IO test on 5000 files
IO Result of Regular Directory : 1.1335179805756 seconds
IO Result of Class5.Mnemonic : 0.37275409698486 seconds

IO test on 10000 files
IO Result of Regular Directory : 2.5350189208984 seconds
IO Result of Shared Memory Directory : 0.91874718666077 seconds


Przykładem może być jak już wspomniałem umieszczenie w pamięci podręcznej
nie tyle co tylko szablonów TPL i kompilatów, ale także samych klas.

Cytat
Testing Chameleon 2.1.4 + Mnemonic => 359.57 requests/s
Testing OPT 1.1.0 => 160.29 requests/s
Testing Smarty 2.6.16 => 96.01 requests/s


i tradycynie z dyku ::

Cytat
Testing Chameleon 2.1.4 => 192.57 requests/s
Testing OPT 1.1.0 => 85.54 requests/s
Testing Smarty 2.6.16 => 56.01 requests/s


smile.gif

Na zakończenie parę uwag odnośnie artykułu :

1) extension=memcache.so a nie extension=memcached.so
2) nie napisałeś nic o instalacji serwera memcached oraz libevent
3) brak informacji o wymaganiu jadra 2.6 lub 2.4 z odpowiednia lata

To tyle smile.gif

Pozdro.
nrm
Bastion brawo winksmiley.jpg Na ciebie zawsze można liczyć winksmiley.jpg
Żenua ale pierwszy raz słyszę o Shmop ?!? Coś ze mną nie tak, czy to jest tak mało znane/popularne?

Niezgodze się tylko z jednym:
Cytat
Po szóste, cache obiektów, zapytań SQL - w ogóle nie ma sensu z zasadniczych powodów
to tzw. bullshit winksmiley.jpg czyli chrzanienie winksmiley.jpg Ma sens i to ogromny!!! Pokeszuj sobie różne głupie pytania (tzn. takie których nie trzeba wyciagać za każdym razem np. lista kategorii) na serwisie, który ma tysiące uników na godzinę smile.gif Ja tak zrobiłem i nagle obciążenie dedyka spadło _bardzo mocno_ a praca dysków nie wykazała zauważalnych zmian.
Bastion
smile.gif Nie przeglądamy manuala dla relaksu co ? tongue.gif http://pl.php.net/manual/pl/ref.shmop.php

co do SQL *teraz* nie przeczę - uwaga była wysunięta na podstawie mojego doświadczenia, opartego
widać na mniejszych serwisach smile.gif wybacz ! ;]
nrm
ta, linka widziałem wyżej, już przejrzałem choć niewiele tam tego. Poogoglam sobie później w tym temacie. A manuala dla relaksu zdecydowanie nie przeglądam winksmiley.jpg

Co do cache sql: należy też pamiętać o tym, że na ogół to (my)sql najbardziej obciąża serwer* przy sporym ruchu, zamiana tysięcy pytań do sqla na tysiące wczytań zserializowanej do pliku tablicy przy dyskach scsi w raidzie okazuje się zbawienna dla całego serwera.


* szczególnie teraz w dobie web2.0, serwisów społecznościowych, OGROMU informacji które ciągnie się z bazy, kilka razy więcej sqli na stronę :/ eh, masakra. Najgorsze jest to, że większości z nich skeszować się nie da :/
Riklaunim
tutaj jest prezentacja (PDF) dotycząca rails i memcached smile.gif Autor opisuje po co, kiedy i do czego powinno używać się memcached.

Odnośnie sensu keszowania - memcached nie jest dla małych i średnich stron. Memcached jest dla slashdotów, wikipedii czy diggów, gdzie można sobie postawić nawet kilka serwerów memcached. Odnośnie keszowania wyników zapytań to nie keszuje się prostych a jedynie te skomplikowane łączące table z różnymi warunkami i zwracające wiele danych. Na mniejszą skalę można sobie keszować do plików w katalogu [z podmontowanym tmpfs] winksmiley.jpg
Bastion
<joke>Tylko co ma rails do php smile.gif</joke>

A na poważnie, zgadzam się z sensem stosowania cache w dużych projektach, cacheująć spore, powiązane ze sobą zapytania.
Nie mniej jednak już na samych różnicach I/O widać że SHMOP jest szybszy i bardziej dostępny niż MemCached. Powiedzmy,
że zmylił mnie artykuł, wyglądający jak coś do małych rzeczy.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.