PHP i memcached, zaawansowane przypadki użycia

Post on 25-Apr-2015

8.184 views 2 download

description

Autor: Mariusz Gil Memcached to podstawowy element architektury aplikacji webowych o znacznym wolumenie ruchu. Choć typowe wdrożenie tego silnika ogranicza się wykorzystania podstawowych funkcjonalności (np. set/get w obrębie jednej instancji memcached), to tematyka łączenia aplikacji PHP z memcached jest o wiele bardziej rozległa. Strategie cache'owania danych w memcached, komunikacja z klastrem jego instancji i metody zmniejszania obciążenia warstwy sieciowej, przeciwdziałanie dog-pile effect, slab klasy i chunki i ich wpływ na optymalizację wykorzystywanej pamięci operacyjnej, różnice i wynikające z nich możliwości pomiędzy modułami klienckimi w PHP, rozwiązania alternatywne dla memcached – to tylko część zagadnień jaki zostaną przedstawione w prezentacji.

Transcript of PHP i memcached, zaawansowane przypadki użycia

PHP I MEMCACHEDZAAWANSOWANE PRZYPADKI UŻYCIA

Mariusz Gilmariusz.gil@scalability.pl

PHPCon 2010 Poland, Góry Świętokrzyskie, maj 2010

środa, 26 maja 2010

CO TO JEST MEMCACHED?

•Memcached to wysoce wydajny i skalowalny system pamięci podręcznej, oparty wyłącznie o pamięć RAM

•Ogólnego przeznaczenia, choć głównie stosowany podczas optymalizacji i skalowaniu aplikacji internetowych

środa, 26 maja 2010

ODROBINA HISTORII

• Autorem memcached jest Danga Interactive

• Projekt powstał w 2003 roku na potrzeby serwisu LiveJournal

•Od tamtej chwili stanowi podstawowy element architektury nowoczesnych aplikacji, a opracowany protokół stał się standardem

środa, 26 maja 2010

IDEA DZIAŁANIA

cache 1GB cache 1GB

rozdzielne cache nakażdym serwerze

memcached 2GB

wspólny cache dla wszystkichserwerów, implementowany jako

rozproszona tablica hashująca

środa, 26 maja 2010

IDEA DZIAŁANIA

// Pobranie danych bez cache’owaniafunction get_foo(int userid) { result = db_select("SELECT * FROM users WHERE userid = ?", userid); return result;}

// Pobranie danych z cache’owanie,function get_foo(int userid) { /* Najpierw sprawdzamy, czy dane są w cache */ data = memcached_fetch("userrow:" + userid); if (!data) { /* Nie znaleziono: odpytujemy bazę danych */ data = db_select("SELECT * FROM users WHERE userid = ?", userid); /* Następnie umieszczamy w cache dla następnych odwołań */ memcached_add("userrow:" + userid, data); } return data;}

przykład pochodzi ze strony http://en.wikipedia.org/wiki/Memcached

środa, 26 maja 2010

PRZYKŁADOWE ZASTOSOWANIA

• Cache zapytań SQL

• Cache stron, widoków, partiali

• Handler sesyjny

• Storage dla locków i liczników

środa, 26 maja 2010

OGRANICZENIA MEMCACHED

• Klucze o długości 250 znaków

•Wartość o maksymalnym rozmiarze 1MB

• Brak trwałości danych - to tylko cache, nie storage

• Brak bezpiecznego dostępu do serwera

środa, 26 maja 2010

ROZPOCZYNANIE PRACY

• Instalacja oprogramowania

wget http://memcached.org/latesttar -zxvf memcached-1.x.x.tar.gzcd memcached-1.x.x./configuremake && make testsudo make install

• Uruchomienie

memcached -m 1024 -u root -l 127.0.0.1 -p 11211 -vv

środa, 26 maja 2010

PODSTAWY PROTOKOŁU

• Protokół memcached to zaledwie kilka podstawowych poleceń:

• Komendy składujące: SET, ADD, REPLACE, APPEND, PREPEND, CAS, INCR/DECR, DELETE, FLUSH_ALL

• Komendy pobierające: GET, GETS

• Komendy statystyk: STATS, STATS ITEMS, STATS SLABS, STATS SIZES

środa, 26 maja 2010

PODSTAWY PROTOKOŁU (CLI)

MacBook-Pro:~ mariusz$ telnet 127.0.0.1 11211Trying 127.0.0.1...Connected to 127.0.0.1.Escape character is '^]'.set test 1 0 4abcdSTOREDget testVALUE test 1 4abcdENDset counter 1 0 11STOREDincr counter 12decr counter 11quit

środa, 26 maja 2010

PODSTAWY PROTOKOŁU (PHP)

<?php/** * Przykład: prosta komunikacja z serwerem. */$memcached = new Memcached();

$memcached->addServer('127.0.0.1', 11211);

$memcached->set('test3', 'test3', 3600);$memcached->get('test3');$memcached->add('test4', 'test4', 3600);

?>

środa, 26 maja 2010

ARCHITEKTURA W PRAKTYCE

...

Moduły klienckie

Ruch sieciowy

Rodzaj protokołu

Wykorzystanie pamięci

Ruch sieciowy

Klastrowanie serwerów

Monitoring działania

Strategie cache’owania

LRU, evictions

Podsłuchiwanie komunikacji

Wysoka dostępność

środa, 26 maja 2010

MODUŁY KLIENCKIE DLA PHP

pecl/memcache pecl/memcached

Data pierwszego wydania 2004-06-08 2009-01-29Zależności zewnętrzne libmemcached

Polecenia APPEND/PREPEND ✓

Automatyczna serializacja ✓ ✓

Protokół binarny opcjonalniePolecenie CAS ✓

Kompresja ✓ ✓

Constistent hashing ✓ ✓

Opóźnione pobieranie danych ✓

Polecenie multi-GET ✓ ✓

Support sesji ✓ ✓

Polecenia SET/GET na wskazanym serwerze ✓

Przechowywanie danych liczbowych konwersja ✓

Automatyczne naprawianie kluczy ✓ ✓

Zarządzanie timeout-ami tylko połączenie ✓

środa, 26 maja 2010

STRATEGIE CACHE’OWANIA

• Rozpatrzmy następujące zapytanie

SELECT * FROM table_1 AS t1 JOIN table_2 AS t2 ON (t2.related_id = t1.id)WHERE t1.id BETWEEN 100 AND 200

• Jak aktualizować cache dla tak wykonanego zapytania?

• Czasem taka strategia się jednak sprawdza...

•Osobne klucze vs. tagowanie

środa, 26 maja 2010

STRATEGIE CACHE’OWANIA

• Przykładowe rozwiązanie problemu:

SELECT * FROM table_1 AS t1 WHERE t1.id BETWEEN 100 AND 200// Zapisz pod kluczami t_1_ID wartości poszczególnych rekordów// Zapisz pod innym kluczem listę samych ID

SELECT * FROM table_2 WHERE related_id IN (X1...Xn)// Zapisz pod kluczami t_2_ID wartości poszczególnych rekordów

•W przypadku aktualizacji jakiejkolwiek danej, modyfikowany jest tylko jeden klucz w memcached

środa, 26 maja 2010

PODSŁUCHIWANIE KOMUNIKACJI

• Czasem zachodzi potrzeba analizowania komunikacji pomiędzy procesami PHP a serwerem memcached

• memcached -m 1024 -u root -l 127.0.0.1 -p 11211 -vv

• ngrep -d lo0 port 11211

• wrapper na obiekt klasy Memcache(d)

środa, 26 maja 2010

PODSŁUCHIWANIE KOMUNIKACJI

•Memcached nie udostępnia opcji listowania wszystkich kluczy, ale można skorzystać z narzędzia peep:

$ sudo peep --pretty 2479time | exptime | nbytes | clsid | key | exprd | flushd8658 | 613458 | 272 | 5 | "c3RhdH:171:5" | false | false8658 | 0 | 6 | 1 | "current_c3RhdH:3" | false | false8658 | 613458 | 281 | 5 | "c3RhdH:171:26" | false | false8678 | 95078 | 6 | 1 | "User:1:auth:m4Uq" | false | false8658 | 0 | 8 | 2 | "user_dGltZWxp:4" | false | false8686 | 613486 | 1278 | 9 | "User:1:6" | false | false8658 | 613458 | 1286 | 9 | "User:1:4" | false | false...8658 | 613458 | 283 | 5 | "c3RhdH:171:28" | false | false8658 | 613458 | 277 | 5 | "c3RhdH:171:30" | false | false

dane pochodzą ze strony http://blog.evanweaver.com/articles/2009/04/20/peeping-into-memcached/

środa, 26 maja 2010

MONITORING DZIAŁANIA

STAT pid 83010STAT uptime 29STAT time 1274341051STAT version 1.4.5STAT pointer_size 64STAT rusage_user 0.001817STAT rusage_system 0.004779STAT curr_connections 5STAT total_connections 6STAT connection_structures 6STAT cmd_get 2STAT cmd_set 2STAT cmd_flush 0STAT get_hits 0STAT get_misses 2STAT delete_misses 0STAT delete_hits 0STAT incr_misses 0STAT incr_hits 3

STAT decr_misses 0STAT decr_hits 0STAT cas_misses 0STAT cas_hits 0STAT cas_badval 0STAT auth_cmds 0STAT auth_errors 0STAT bytes_read 133STAT bytes_written 163STAT limit_maxbytes 1073741824STAT accepting_conns 1STAT listen_disabled_num 0STAT threads 4STAT conn_yields 0STAT bytes 72STAT curr_items 1STAT total_items 3STAT evictions 0STAT reclaimed 0

•Monitorowanie serwera za pomocą poleceń STATS

środa, 26 maja 2010

MONITORING DZIAŁANIA

• Integracja z systemami monitorowania środowiska

•Wykresy systemowe pozwalają określić skuteczność cache

środa, 26 maja 2010

ZARZĄDZANIE PAMIĘCIĄ

•Memcached korzysta z algorytmu LRU w obrębie slab klasy

• Expire

• Klucz może zostać usunięty przed wygaśnięciem

• Evictions

•Niebezpiecznie w przypadku wykorzystania memcached jako handlera sesyjnego

środa, 26 maja 2010

PRZECHOWYWANIE WARTOŚCI

• Rozmiar wartości ma znaczenie (klucza także)<?php/** * Przykład: rozmiar wartości. */$data = array( 'key_1' => array( 'value_1_1', 'value_1_2', 'value_1_3' ), 'key_2' => array( 'value_2_1', 'value_2_2', 'value_2_3' ),);

var_dump(serialize($data));var_dump(json_encode($data));

?>

string(162) "a:2:{s:5:"key_1";a:3:{i:0;s:9:"value_1_1";i:1;s:9:"value_1_2";i:2;s:9:"value_1_3";}s:5:"key_2";a:3:{i:0;s:9:"value_2_1";i:1;s:9:"value_2_2";i:2;s:9:"value_2_3";}}"

string(93) "{"key_1":["value_1_1","value_1_2","value_1_3"],"key_2":["value_2_1","value_2_2","value_2_3"]}"

środa, 26 maja 2010

CHECK AND SET

• Równoległe operacje na kluczach, race-conditions

serwer php

serwer php

serwer php

serwer memcached

środa, 26 maja 2010

FLAGI

•Memcached pozwala na przechowywanie wraz z parą klucz-wartość dodatkowych informacji

• Flagi są zapisywanie przez serwer atomowo, wraz z parą

• Implementacja obsługi flag zależy od wersji biblioteki klienckiej

środa, 26 maja 2010

SKALOWANIE

• Rozłożenie kluczy pomiędzy wiele serwerów

• Algorytmy rozpraszania kluczy: modulo, consistent hashing

klucz 11

klucz 27klucz 89

klucz 44

klucz 5klucz 90

serwer memcached 2

klucz 31

klucz 9klucz 13

klucz 51

klucz 99klucz 72

serwer memcached 3

klucz 1

klucz 22klucz 34

klucz 23

serwer memcached 1

klucz 58klucz 62

środa, 26 maja 2010

SKALOWANIE

• Skalowanie memcached od strony PHP

<?php/** * Przykład: Komunikacja z klastrem serwerów. */$memcached = new Memcached();

$memcached->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);$memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);

$memcached->addServer('127.0.0.1', 11211);$memcached->addServer('127.0.0.1', 11311);$memcached->addServer('127.0.0.1', 11411);$memcached->addServer('127.0.0.1', 11511);$memcached->addServer('127.0.0.2', 11211);$memcached->addServer('127.0.0.3', 11311);

?>

środa, 26 maja 2010

WYSOKA DOSTĘPNOŚĆ

• Projekt Repcached dla memcached 1.2.x, memcached z zasady jest ulotny!

klient

klucz 1

klucz 2klucz 3

klucz 4

klucz 5klucz 6

klucz 1

klucz 2klucz 3

klucz 4

klucz 5klucz 6

get, set, incr, decr

replikacjamaster-master

get, set, incr, decr

środa, 26 maja 2010

OPTYMALIZACJA KOMUNIKACJI

•Memcached jest bardzo szybki, ale czasem barierę wyznacza warstwa sieciowa i ilość zapytań

•Minimalizacja round-tripów, czyli multiGET oraz multiSET

<?php/** * Przykład: 100 x GET */$memcached = new Memcached();

$memcached->addServer('127.0.0.1', 11211);

for ($i = 1; $i <= 100; $i++) { $values[] = $memcached->get('test_' . $i);}

?>

<?php /** * Przykład: 1 x multiGET */$memcached = new Memcached();

$memcached->addServer('127.0.0.1', 11211);

for ($i = 1; $i <= 100; $i++) { $keys[] = 'test_' . $i;}

$values = $memcached->getMulti($keys);

?>

środa, 26 maja 2010

OPTYMALIZACJA KOMUNIKACJI

• Skuteczność operacji multiGET/multiSET zależy od sposobu rozrzucania kluczy pomiędzy serwery

• Jeśli dysponujemy 20 serwerami memcached i zapisujemy 20 kluczy, w najgorszym przypadku wykonujemy 20 pojedynczych SET-ów

• Analogicznie jest z pobieraniem danych

środa, 26 maja 2010

OPTYMALIZACJA KOMUNIKACJI

•Moduł pecl/memcached umożliwia przejście na protokół binarny

• Pozwala to zaoszczędzić cenne zasoby<?php/** * Przykład: Opcje połączenia. */$memcached = new Memcached();

// Przed połączeniem z serwerem!$memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);

$memcached->addServer('127.0.0.1', 11211);

var_dump($memcached->getOption(Memcached::OPT_BINARY_PROTOCOL));

?>

środa, 26 maja 2010

OPTYMALIZACJA KOMUNIKACJI

•Opóźnione pobieranie kluczy

<?php/** * Przykład: Opóźnione pobieranie kluczy. */$memcached = new Memcached();

$memcached->addServer('127.0.0.1', 11211);$memcached->get('int', 99);$memcached->get('string', 'a simple string');$memcached->get('array', array(11, 12));

var_dump($memcached->getDelayed(array('int', 'array'), true));?>

•Opóźnione zapisywanie wartości

• Przydatne np. przy wykorzystaniu memcached jako handlera sesyjnego

środa, 26 maja 2010

DOGPILE EFFECT

• Czym jest dogpile effect? Kiedy może wystąpić? Jak się bronić?

serwer php

serwer php

serwer php

serwer memcachedx

środa, 26 maja 2010

ROZWIĄZANIA ALTERNATYWNE

•MemcacheDB

• Trwały silnik KV oparty o bazę danych BerkeleyDB

• Redis

• Bardzo wydajny, trwały silnik KV implementujący protokół memcachedPosiada wsparcie dla złożonych struktur danych

środa, 26 maja 2010

DZIĘKUJĘ ZA UWAGĘ.PYTANIA?

środa, 26 maja 2010