Skocz do zawartości

System cache z synchronizacją procesów


INOMan
 Udostępnij

Rekomendowane odpowiedzi

Dzień dobry,

 

temat raczej dla zaawansowanych użytkowników PHP.

 

Jakiś czas temu zrobiłem projekt na githubie (https://github.com/tztztztz/php-no-slam-cache) systemu cache który synchronizuje procesy/wątki HTTP podczas pobierania zasobu (READ LOCK) / jego tworzenia (WRITE LOCK), w modelu "many readers, one writer at once"

Instalacja przez composera:
 

php composer.phar require inopx/noslamcache

 

Tradycyjny system cache działa tak:

 

1. Sprawdzenie czy zasob jest w cache. Jeżeli jest - pobranie, koniec.

2. Jeżeli nie ma zasobu w cache lub jest przeterminowany - jego stworzenie i wstawienie do cache.

 

Wydaje się, że wszystko jest w porzątku, ale nie jest.

W przypadku kiedy mamy duzy ruch na stronie, a samo tworzenie zasobu zajmuje trochę czasu - np. kilka sekund, bez synchronizacji zaczyna się problem podobny do "thread race": to znaczy wiele wątków / procesów na raz w tym samym momencie tworzy zasob i wstawia go do cache. To zjawisko nosi nazwę cache slamming / cache stampede.

 

Jest niewiele systemów cache które rozwiązują ten problem, a jeżeli rozwiązują to w skomplikowany sposób.

 

System który stworzyłem działa na takiej zasadzie:

 

1. Tworzymy przepis na stworzenie zasobu w formie funkcji callback, np.:

 

$create = function() use($jakasZmienna, $innaZmienna) {

 

return $jakasZmienna + $innaZmienna;

 

}

 

2. Wywołujemy system cache TYLKO RAZ, bez żadnego sprawdzania czy zasób istnieje czy nie. Jeżeli nie będzie istniał, wtedy system cache wywoła callback tworzac zasób i wstawiając do cache, i zrobi to synchronizując inne procesy które w tym samym czasie chciałyby czytać lub tworzyć zasób. Tylko jeden wątek / proces będzie tworzył zasob a reszta będzie czekać nie obciążając serwera, aż zasob zostanie stworzony.

Synchronizacja jest na dany zasób / klucz, więc może być kilka zasobów dla cache w tym samym momencie tworzonych, ale o innych identyfikatorach.

 

Szczegółowy opis w moim kalecznym języku angielskim znajduje się na stronie projektu, tzn:

 

https://github.com/tztztztz/php-no-slam-cache

 

W projekcie znajdziemy też dokumentację API, oraz skrypt testowy do szybkiego testowania cache w trybie CLI.

 

UWAGA - aby synchronizacja działała, wymagane jest zainstalowanie dodatku do PHP, bilbioteki SYNC którą można znaleźć pod adresem: https://pecl.php.net/package/sync

 

Bez tej biblioteki system będzie działał, ale bez synchronizacji, zobacz też dokumentację w PHP tej biblioteki: https://php.net/manual/en/book.sync.php

 

Zaletą SYNC jest to, że działa bez problemów zarówno na Windowsie jak i Linuxie, w dodatku jest o wiele prostsza w uzyciu niż zabawa np. z Semaforami do synchronizacji.

 

Pozdrawiam

Edytowane przez INOMan
Odnośnik do komentarza
Udostępnij na innych stronach

Cytat

 


$cache = new CacheMethod();

$cache->get($group, $key, $lifetimeInSeconds, $createCallback)

/// NIE!!!! można sie bedzie zajechać :)
====================================


namespace et/qwe

use NoSlamCache;
class ABC {

$private $cacheKey;

public function qwe() {

$data = NoSlamCache::get($cacheKey,$b,$c, $etc);
if(!$data) { 
 //blabla jakiś kod
 $data = $cośtam;
 NoSlamCache::set($cacheKey,$data,$c, $etc)
}
return $data;
}
//etc

//// TAK plus plik config gdzie ustawiasz parametry typu jaki driver, default expires etc.

}

 

używasz composera a dajesz classloader.php zrób przyzwoicie composera z PSR4 i niech to idze w vendor

Edytowane przez kayman
Odnośnik do komentarza
Udostępnij na innych stronach

Get nie może być metodą statyczną, bo każdy sposób keszowania to inny obiekt.

 

Classloader jest opcjonalny, nie trzeba robić classloadera w komposerze, bo nazwy klas ich pozycje sa kompatybilne ze standardem PSR-4.

 

Jeżeli uważasz, że coś powinno być inaczej, zawsze możesz zrobić forka i sobie to przerobić.

Edytowane przez INOMan
Odnośnik do komentarza
Udostępnij na innych stronach

4 minuty temu, INOMan napisał:

Get nie może być metodą statyczną

e tam

 

masz kolekcje obiektów :) https://laravel.com/docs/5.6/eloquent-collections

Edytowane przez kayman
Odnośnik do komentarza
Udostępnij na innych stronach

Nie używam i nie znam Laravela. To ma być mała użyteczna biblioteka a nie jakaś krowa wymagająca komponentów z Laravela.

 

---

 

Edit - to może jeszcze wyjaśnienie.

 

Mała biblioteka niezależna od innych komponentów (poza PECL SYNC) ma tą zaletę, że możesz używać w wielu roznych frameworkach i dostosować ją sobie jak chcesz.

Robienie krowy która korzysta z jakichś komponentów innych frameworków to zły pomysł - bo ja np. robię wszystko na frameworku Phalcon, i po co mi cokolwiek z Laravela, to tylko zaśmiecanie projektu plikami. Laravel jest najpopularniejszy, ale to nie jest jedyny framework.

Poza tym nie każdemu pasuje styl jaki Tobie się podoba - czyli korzystanie ze statycznych metod. Jeżeli w ten sposób chcesz z tej biblioteki korzystać (o ile w ogóle) to piszesz sobie małego wrappera który spowoduje, że będziesz miał dostęp przez statyczne metody.
 

 

Edytowane przez INOMan
Odnośnik do komentarza
Udostępnij na innych stronach

ona przecież może być zamknięta, niezależna od czegokolwiek

tylko jak mam pisać 1000 razy 

$cache = new CacheMethod();

$cache->get($group, $key, $lifetimeInSeconds, $createCallback)

to narobię burdelu w kodzie o duplikacji nie wspomnę , to Twoja klasa powinna robić wszystko co potrzeba by była użyteczna a za tym idzie czytelna w kodzie, ona ma cachować więc niech cachuje, dostaje config +  paramenty w metodzie i koniec robi co trzeba

 

pomysł masz fajny ale na moje wykonanie trzeba poprawić chociażby dla tego że jest duża frajda jak ktoś z tego korzysta 

 

btw. używam tego ORM do slim3 -> i właśnie o to chodzi że można z niego skorzystać niezależnie od frameworka, a jak ktoś tego nie chce zawsze może sobie napisać modele/sql'e z łapy :)

Odnośnik do komentarza
Udostępnij na innych stronach

Nie rozumiem po kiego grzyba za każdym razem tworzyć nową metodę keszowania.

 

Robisz tylko raz

$cache = new CacheMethod();

 

i możesz korzystać z tego obiektu wiele razy.

Możesz sobie zrobić gdzieś metodę statyczną, singletona który za każdym razem zwróci Ci jednorazowo utworzony obiekt, jeżeli nie umiesz żyć bez metod statycznych.

 

Przy okazji Laravel m.in. dlatego jest syfem, bo uczy wielu złych praktyk programowania - takich jak nadużywanie metod statycznych tam gdzie do tego się nie nadają.

 

---edit:

 

I szczerze mówiąc to ja właśnie tak robie u siebie - mam jedną metodę statyczną - z Dependency Injectora - która zwraca mi obiekt cache.

 

I teraz dzieki temu że każda metoda cache implementuje ten sam interfejs, jest to przeźroczyste - czyli mogę w tej metodzie statycznej / Dependency Injectorze zmienić sposób keszowania z plików na memcached, albo ustawic "dummy cache", i dla reszty projektu / systemu nie będzie różnicy.

Edytowane przez INOMan
Odnośnik do komentarza
Udostępnij na innych stronach

phalcon powiadasz

6 godzin temu, INOMan napisał:

robię wszystko na frameworku Phalcon

 

no chyba oprócz modeli :) 

use Store\Toys\Robots;

// Find record with id = 3
$robot = Robots::findFirst(3);

// Prints 'Terminator'
echo $robot->name;

https://docs.phalconphp.com/en/3.3/db-models

Odnośnik do komentarza
Udostępnij na innych stronach

Poprawiłem trochę composera - dodałem autoloading (dzięki za sugestię), oraz usunąłem wymóg biblioteki SYNC ponieważ nie jest to pakiet od komposera i instalacja rodzi problemy.

 

Co do ORM Phalcona - on jest trudny do nauki i upierdliwy, ale jak go opanujesz to jest bardzo dobry, i bardzo szybki.

Pomogłem już wielu ludziom z tym ORMem na forum, oraz w sumie jestem jednym z tworców tego frameworka (malutkim), bo jedna z moim poprawek została zaakceptowana: https://github.com/phalcon/cphalcon/issues/12842

Edytowane przez INOMan
Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
 Udostępnij

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę. Warunki użytkowania Polityka prywatności