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.
1. PHP I MEMCACHED
ZAAWANSOWANE PRZYPADKI UŻYCIA
Mariusz Gil
mariusz.gil@scalability.pl
PHPCon 2010 Poland, Góry Świętokrzyskie, maj 2010
środa, 26 maja 2010
2. 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
3. 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
4. IDEA DZIAŁANIA
cache 1GB cache 1GB memcached 2GB
rozdzielne cache na wspólny cache dla wszystkich
każdym serwerze serwerów, implementowany jako
rozproszona tablica hashująca
środa, 26 maja 2010
5. IDEA DZIAŁANIA
// Pobranie danych bez cache’owania
function 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
6. PRZYKŁADOWE ZASTOSOWANIA
• Cache zapytań SQL
• Cache stron, widoków, partiali
• Handler sesyjny
• Storage dla locków i liczników
środa, 26 maja 2010
7. 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
8. ROZPOCZYNANIE PRACY
• Instalacja oprogramowania
wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure
make && make test
sudo make install
• Uruchomienie
memcached -m 1024 -u root -l 127.0.0.1 -p 11211 -vv
środa, 26 maja 2010
9. 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
10. PODSTAWY PROTOKOŁU (CLI)
MacBook-Pro:~ mariusz$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set test 1 0 4
abcd
STORED
get test
VALUE test 1 4
abcd
END
set counter 1 0 1
1
STORED
incr counter 1
2
decr counter 1
1
quit
środa, 26 maja 2010
12. ARCHITEKTURA W PRAKTYCE
Moduły klienckie
Wysoka dostępność
Ruch sieciowy
Monitoring działania
Podsłuchiwanie komunikacji
Rodzaj protokołu
Strategie cache’owania
...
Wykorzystanie pamięci
LRU, evictions
Klastrowanie serwerów
środa, 26 maja 2010
13. MODUŁY KLIENCKIE DLA PHP
pecl/memcache pecl/memcached
Data pierwszego wydania 2004-06-08 2009-01-29
Zależności zewnętrzne libmemcached
Polecenia APPEND/PREPEND ✓
Automatyczna serializacja ✓ ✓
Protokół binarny opcjonalnie
Polecenie 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
14. 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
15. 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
16. 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
18. MONITORING DZIAŁANIA
• Monitorowanie serwera za pomocą poleceń STATS
STAT pid 83010 STAT decr_misses 0
STAT uptime 29 STAT decr_hits 0
STAT time 1274341051 STAT cas_misses 0
STAT version 1.4.5 STAT cas_hits 0
STAT pointer_size 64 STAT cas_badval 0
STAT rusage_user 0.001817 STAT auth_cmds 0
STAT rusage_system 0.004779 STAT auth_errors 0
STAT curr_connections 5 STAT bytes_read 133
STAT total_connections 6 STAT bytes_written 163
STAT connection_structures 6 STAT limit_maxbytes 1073741824
STAT cmd_get 2 STAT accepting_conns 1
STAT cmd_set 2 STAT listen_disabled_num 0
STAT cmd_flush 0 STAT threads 4
STAT get_hits 0 STAT conn_yields 0
STAT get_misses 2 STAT bytes 72
STAT delete_misses 0 STAT curr_items 1
STAT delete_hits 0 STAT total_items 3
STAT incr_misses 0 STAT evictions 0
STAT incr_hits 3 STAT reclaimed 0
środa, 26 maja 2010
19. MONITORING DZIAŁANIA
• Integracja z systemami monitorowania środowiska
• Wykresy systemowe pozwalają określić skuteczność cache
środa, 26 maja 2010
20. 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
21. PRZECHOWYWANIE WARTOŚCI
• Rozmiar wartości ma znaczenie (klucza także)
<?php 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:
* Przykład: rozmiar wartości. {i:0;s:9:"value_2_1";i:1;s:9:"value_2_2";i:2;s:9:
*/ "value_2_3";}}"
$data = array(
'key_1' => array( string(93) "{"key_1":["value_1_1","value_1_2","value_1_3"],
'value_1_1', "key_2":["value_2_1","value_2_2","value_2_3"]}"
'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));
?>
środa, 26 maja 2010
22. CHECK AND SET
• Równoległe operacje na kluczach, race-conditions
serwer php
serwer php
serwer php
serwer memcached
środa, 26 maja 2010
23. 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
25. 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
26. WYSOKA DOSTĘPNOŚĆ
• Projekt Repcached dla memcached 1.2.x, memcached z zasady
jest ulotny!
klucz 1 klucz 1
klucz 4 klucz 4
klucz 3
replikacja klucz 3
master-master klucz 2
klucz 2
klucz 5 klucz 5
klucz 6 klucz 6
get, set, incr, decr get, set, incr, decr
klient
środa, 26 maja 2010
27. OPTYMALIZACJA KOMUNIKACJI
• Memcached jest bardzo szybki, ale czasem barierę wyznacza
warstwa sieciowa i ilość zapytań
• Minimalizacja round-tripów, czyli multiGET oraz multiSET
<?php <?php
/** /**
* Przykład: 100 x GET * Przykład: 1 x multiGET
*/ */
$memcached = new Memcached(); $memcached = new Memcached();
$memcached->addServer('127.0.0.1', 11211); $memcached->addServer('127.0.0.1', 11211);
for ($i = 1; $i <= 100; $i++) { for ($i = 1; $i <= 100; $i++) {
$values[] = $memcached->get('test_' . $i); $keys[] = 'test_' . $i;
} }
?> $values = $memcached->getMulti($keys);
?>
środa, 26 maja 2010
28. 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
29. 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
30. 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
• Przydatnenp. przy wykorzystaniu memcached jako
handlera sesyjnego
środa, 26 maja 2010
31. DOGPILE EFFECT
• Czym jest dogpile effect? Kiedy może wystąpić? Jak się bronić?
serwer php
serwer php
serwer php
serwer memcached
x
środa, 26 maja 2010
32. ROZWIĄZANIA ALTERNATYWNE
• MemcacheDB
• Trwały silnik KV oparty o bazę danych BerkeleyDB
• Redis
• Bardzo wydajny, trwały silnik KV implementujący protokół
memcached
Posiada wsparcie dla złożonych struktur danych
środa, 26 maja 2010