Memcached

Z Wikipedii, wolnej encyklopedii
Memcached
Autor Danga Interactive
Pierwsze wydanie 2003-05-22 22 maja 2003(dts)
Aktualna wersja stabilna 1.6.25
(19 marca 2024) [±]
Platforma sprzętowa wieloplatformowy
System operacyjny wieloplatformowy
Rodzaj System buforowania pamięci podręcznej
Licencja Licencja BSD[1]
Strona internetowa

Memcached – system buforowania pamięci podręcznej ogólnego przeznaczenia, stworzony przez Danga Interactive dla serwisu LiveJournal, lecz aktualnie używany przez wiele innych stron. Jest często używany do przyspieszenia dynamiki baz danych poprzez buforowanie danych i obiektów w pamięci RAM w celu zredukowania czasu odczytu zewnętrznego źródła danych (np. bazy danych lub API). Memcached działa na systemach uniksopodobnych, Windows i MacOS. Projekt jest udostępniany na licencji BSD.

API Memcached zapewnia ogromną tablicę mieszającą rozproszoną na wielu maszynach. Kiedy tablica jest pełna, następuje zastępowanie najmniej używanych rekordów nowymi danymi, zgodnie z algorytmem LRU (ang. least recently used). Aplikacje wykorzystują Memcached najczęściej w warstwie żądań przed bezpośrednim użyciem wolniejszych baz danych.

Schemat obsługi połączeń z aplikacją MediaWiki z uwzględnieniem Memcached.

Projekt jest używany przez kilka dużych, znanych serwisów, takich jak: Wikipedia[2], YouTube[3], Facebook[4][5], Twitter[6], Reddit[7], The New York Times[8], Nasza-Klasa[9][10], Grono.net[11][12].

Historia[edytuj | edytuj kod]

Memcached został opracowany przez Brada Fitzpatricka na potrzeby jego strony LiveJournal, 22 maja 2003 roku[13][14][15].

Architektura[edytuj | edytuj kod]

Memcached używa modelu klient-serwer. Serwer przechowuje klucze i wartości jako tablice asocjacyjną, natomiast klient przetwarza tablicę i odpowiada w przetworzonej formie. Klucze maja długość do 250 bajtów, a wartości do 1 MB.

Klient używa do kontaktu z serwerem własnych bibliotek, które standardowo udostępniają usługę na porcie 11211 TCP. Każdy klient zna wszystkie serwery; serwery nie komunikują się ze sobą. Jeśli klient chce ustawić lub odczytać wartość odpowiadającą danemu kluczowi, najpierw oblicza hash klucza do określenia serwera który będzie użyty. Następnie kontaktuje się ze serwerem, który oblicza drugi hash klucza do określenia miejsca przechowywania wartości. Jeśli wszystkie biblioteki klienta używają tego samego algorytmu mieszania w celu ustalenia serwerów, to klienci mogą czytać nawzajem swoje dane w pamięci podręcznej, co jest pożądane.

Serwer utrzymuje klucze w RAM jedynie gdy działa lub rekord jest na tyle często używany, że nie jest kasowany zgodnie z algorytmem LRU. Dlatego nie powinno się zakładać, że jak nadejdzie potrzeba odczytu lub zapisu to nadal będzie istnieć w Memcached. Istnieje projekt MemcacheDB będący kompatybilny z protokołem Memcached, który trwale przechowuje dane.

Typowe wdrożenia mają kilka serwerów i wielu klientów. Jednakże możliwe jest użycie Memcached na jednej maszynie, działając jednocześnie jako klient i serwer.

Bezpieczeństwo[edytuj | edytuj kod]

Wiele wdrożeń Memcached funkcjonuje w zaufanych sieciach, gdzie klienci mogą swobodnie łączyć się z dowolnym serwerem. Jednak jeśli Memcached został wdrożony w sieciach mniej zaufanych, gdzie administratorzy chcą sprawować kontrolę nad połączeniami klientów, wtedy można skompilować Memcached z opcją obsługi uwierzytelniania SASL, które wymaga użycia protokołu binarnego.

Przykładowy kod[edytuj | edytuj kod]

Wszystkie funkcje opisane na tej stronie są pseudokodem. Wywołanie funkcji Memcached i język programowania mogą się różnić w zależności od używanego API

Konwersja bazy danych lub zapytań tworzących obiekt do użycia Memcached jest łatwa. Zazwyczaj, gdy używamy prostych zapytań do bazy danych, przykładowym kodem może być:

 function pobierz_dane(int userid) 
 {
    result = db_select("SELECT * FROM users WHERE userid = ?", userid);
    return result;
 }

Po konwersji do użycia Memcached, ta sama funkcja wygląda:

 function pobierz_dane(int userid) 
 {
     /* Najpierw próba pobrania danych z cache */
     data = memcached_fetch("userrow:" + userid);
     if (!data) {
         /* Nie znaleziono wymaganych danych => pobranie danych z bazy danych, */
         data = db_select("SELECT * FROM users WHERE userid = ?", userid);
         /* następnie po pobraniu danych, przechowywanie ich w cache. */
         memcached_add("userrow:" + userid,  data);
     }
     return data;
 }

Funkcja najpierw sprawdzi czy na serwerze Memcached są zawarte wartości dla unikatowego klucza "userrow:userid", gdzie userid jest liczbą. Jeśli nie występują dane w Memcached, następuje pobranie danych z bazy danych (w taki sam sposób jak początkowo), następnie wprowadzenie wartości do pamięci podręcznej z przypisanym do nich unikatowym kluczem, w celu późniejszego odwołania się do nich.

Jednak, jeśli będą dane aktualizowane w bazie danych, to dane zawarte w pamięci podręcznej będą nieprawidłowe. Dlatego trzeba stworzyć funkcję która będzie aktualizowała bazę danych i pamięć podręczną jednocześnie.

 function aktualizuj_dane(int userid, string dbUpdateString) 
 {
     /* Najpierw aktualizacja bazy danych */
     result = db_execute(dbUpdateString);
     if (result) 
     {
         /* Aktualizacja bazy danych powiodła się => pobranie danych przechowywanych w bazie danych, */
         data = db_select("SELECT * FROM users WHERE userid = ?", userid);
         /* następnie wprowadzenie danych do pamięci podręcznej. */
         memcached_set("userrow:" + userid, data);

         /* ostatnia linia powinna wyglądać:
         //data = createDataFromDBString(dbUpdateString);   */
     }
 }

Funkcja zaktualizuje pamięć podręczną nowymi danymi, jeżeli aktualizacja bazy danych się powiedzie. Alternatywą może być, że po aktualizacji bazy danych usunie stare dane w pamięci podręcznej, a nowe dane zostaną wprowadzone za pomocą przykładowej funkcji pobierz_dane. Podobne działania muszą być podjęte, gdy rekord w bazie danych zostanie usunięty.

Zobacz też[edytuj | edytuj kod]

Przypisy[edytuj | edytuj kod]

Linki zewnętrzne[edytuj | edytuj kod]