Skocz do zawartości

[php] Cache a serwer


Mar

Rekomendowane odpowiedzi

Witam,

Postanowiłem trochę zoptymalizować swoje skrypty, i między innym wprowadzić cache,

a dokładniej, zrobiłem tak, że to co jest pobierany z bazy sql, zapisuję do pliku tymczasowego,

i jeśli plik jest starszy niż jeden miesiąc aktualizuję plik.

Testując to na localhost zauważyłem, że czas wykonywania skryptu przy czytaniu z danych z pliku

jest o 0.0018s mniejszy niż przy pobieraniu danych poprzez połączenie z bazą.

Ale chciałbym zapytać jak to się ma do obciążenia serwera? I czy to jest dobre rozwiązanie przy odwiedzinach powyżej 10k/u?

Czy może jest jeszcze jakiś inny sposób, może cache całych stron?

Pozdrawiam,

Mar.

Polecam katalog SeoPark.pl, katalog AK47 (5 lata w sieci) ...oraz Wirtualne-miasta.eu
"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów" - Stanisław Lem

Odnośnik do komentarza
Udostępnij na innych stronach

Smarty ma bardzo ciekawy system cache. Zapisuje dane elementy strony lub cały kod strony.

Przy tworzeniu własnego cache pamiętaj o rozdzieleniu plików na podkatalogi jezeli ma być ich więcej niż 5000.

Odnośnik do komentarza
Udostępnij na innych stronach

testuj programem ab z apache , będziesz mógł bardziej obciążyć swoją maszynę na localhost

Co do Twojej metody to ciekawi mię format w jakim przechowujesz wyniki z bazy ? Bo przy wyświetlaniu strony musisz je wczytać i obrobić więc też wykonać pewną pracę. Ogolnie im mniej trzeba wykonywać czynności aby wyświetlic cache tym lepiej.

Mi sie podobało rozwiązanie w którym kompletne strony www były zapisywane na dysku

W momencie gdy user chciał pobrać stronę sprawdzane było czy w cache jest plik, gdy był to pobierany był plik z cache

Gdy nie było pliku żądanie przechodziło przez CMS-a który generował na podstawie bazy danych stronę i zapisywał do cache.

Odnośnik do komentarza
Udostępnij na innych stronach

Zrobiłem w uproszczeniu tak:

<?
define("CACHE_DIR", "_cache");
define("CACHE_TIME", 5000);


$file = sprintf('%s/'.$_GET['id'], CACHE_DIR, md5($target));

if (file_exists($file) && (filesize($file) > 0) && (time() - filemtime($file)) < CACHE_TIME)
	{ 
		$u = explode("|", str_replace("\r", "", @join("", @file($file))));
		//........

} else {
	if ($handle = fopen($file, "w"))
		{
			if (is_resource($handle) && flock($handle, LOCK_EX))
			{					
				//.....
				fwrite($handle, $Result, strlen($Result));
				flock($handle, LOCK_UN);
			}
			fclose($handle);				
		} 
}
?>

Przy tworzeniu własnego cache pamiętaj o rozdzieleniu plików na podkatalogi jezeli ma być ich więcej niż 5000.
Możesz rozwinąć myśl, tak plików będzie więcej niż 5k.

Maximus Marius, załączony przykład jest odpowiedzią na Twoje pytanie.

Mar.

Polecam katalog SeoPark.pl, katalog AK47 (5 lata w sieci) ...oraz Wirtualne-miasta.eu
"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów" - Stanisław Lem

Odnośnik do komentarza
Udostępnij na innych stronach

Ja cache'uje czasem całe strony albo rozdzielam je na fragmenty i pobieram przez readfile().

W jednym z katalogów mam po kilkadziesiąt tys. plików i działa dobrze, ale to zależy od serwera. Jak dyski są słabe, to może przycinać odczyt/zapis albo tworzyć mnóstwo pustych plików.

Polecam linki stałe w Seomatik.pl oraz dopalacz stron Gotlink.pl.

obrazek.jpg

Odnośnik do komentarza
Udostępnij na innych stronach

Im wiecej plików w jednym katalogu tym dłuższy czas na ich wyszukiwanie, dlatego nie powinno sie przesadzać z ilością plikow w jednym katalogu. A zawsze jakoś można je podzielić np według kategorii itp.

Ja jak cachuje to zapisuje prawie gotowe strony html, aby już potem jak naj mniej zużywać mocy procka na serwerze, kosztem nawet tego, jeśli sama operacja cachownia jest o wiele bardziej zasobożerna niż nrmalne generowanie strony bez cachowania.

.

Odnośnik do komentarza
Udostępnij na innych stronach

EDDY wszystko zależy od systemu plików.

Dobra metoda na rozdzielenie plików cache to suma md5. Pozwala dowolnie tworzyc podkatalogi do wymaganej rozmiarami bazy głębokości (np: a/b/3/dalszyciagmd5.cache). Ta metoda sprawdza sie u mnie bez problemu dla cache wielkości kilku GB.

Odnośnik do komentarza
Udostępnij na innych stronach

A co do mojego skryptu? Nie ma w nim jakiś rażących nie optymalnych błędów?

Mar.

Polecam katalog SeoPark.pl, katalog AK47 (5 lata w sieci) ...oraz Wirtualne-miasta.eu
"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów" - Stanisław Lem

Odnośnik do komentarza
Udostępnij na innych stronach

  • 2 tygodnie później...

Zastanawia mnie kilka rzeczy przy cachowaniu:

1. Jak sprawdzacie czy zmienily sie dane w bazie? Wysylacie zapytanie show table status (chociaz wedlug mnie mija sie to z celem) czy macie jakis plik, ktory informuje, ktora tabela kiedy sie zmienila. Przy tym rozwiazaniu przy select sprawdzacie ten plik, a przy zmianie danych dopisujecie do pliku, ze sie zmienily dane w bazie.

2. Jak pzrechowywujacie dane cache z zapytania? Z lenistwa uzywam serialize i unserialize, ale wyczytalem, ze to dosc powolne. Warto stworzyc wlasna funkcje?

Odnośnik do komentarza
Udostępnij na innych stronach

Testując to na localhost zauważyłem, że czas wykonywania skryptu przy czytaniu z danych z pliku

jest o 0.0018s mniejszy niż przy pobieraniu danych poprzez połączenie z bazą.

To raczej o niczym nie świadczy. Potestuj w "prawdziwym" środowisku. Najlepiej napisz skrypt do obliczania średniego czasu ładowania strony. fopen("w") może powodować błędy. Co do samego cache, to ja bym to zrobił na bazie. Pliki średnio się do tego moim zdaniem nadają.

Jeśli koniecznie ma być na plikach to zainteresuj się funkcją ignore_user_abort() i connection_aborted(). Jest jeden atak na taki cache. Polega on na tym, że użytkownik wysyła wiele rządań do skryptu i rozłącza połączenie. Jak zawartość cache wolno się generuje, to może taki plik uciąć np. w połowie. ignore_user_abort() przed tym chroni ;)

Co do kodu: to pierwsze trzeba wygenerować zawartość do wpisania do cache a dopiero potem plik otwierać. Jeśli będzie dużo wejść to pomiędzy otwarciem pliku (tryb "w" czyści plik, tak że ma 0 bajtów) a wygenerowaniem nowej zawartości rządania będą wpadać w else i cache się będzie odświerzał nie jeden ale kilka razy. Z tym, że jeśli rządań będzie dużo. Jeśli masz mało wyswietleń nie ma się czym przejmować.

2. Jak pzrechowywujacie dane cache z zapytania? Z lenistwa uzywam serialize i unserialize, ale wyczytalem, ze to dosc powolne. Warto stworzyc wlasna funkcje?

PHP jest napisane w szybkim C, to samo się tyczy serialize. Jeśli napiszesz taką samą funkcję (serialize) w PHP będzie ona o wiele wolniejsza. Sam mam cache do bazy, na bazie z wykorzystaniem serialize. Działa szybko i niezawodnie. Nie ma NIC GORSZEGO niż pisanie konów funkcji które już są zaimplementowane w PHP. Bo nie dość, że będą dużo wolniejsze to jeszcze mogą zawierać błędy.

Odnośnik do komentarza
Udostępnij na innych stronach

To działa tak jak byś pod windows'em w jednym folderze zrobił sobie kilka tysięcy plików. a w innym tylko kilka. Spróbuj otworzyć oba katalogi i zobacz czy ci to szybko pokaże. Innym sposobem na sprawdzenie czy szybko ci sie wszystko wyświetli jak bys przez serwer FTP spróbował odczytać drzewo katalogowe w jakimś katalogu gdzie było by tych elementów kilka tysięcy. Nieco to wolno będzie działać...

Wracając do tematu. Mój sposób na cache jest taki.

Tworze zapytanie do mysql'a, dajmy na to jakiś:

$query = "SELECT count(0) FROM tabela";

to wrzucam w "filtr" który usuwa zbędne spacje, entery itp., po czym przenosze to do md5, dzięki czemu mam unikatowy identyfikator dla danego zapytania...

ten identyfikator to jest mój plik + rozszerzenie xml.

Dane zapisuje wiadome do XML bo dobrze sie z tym pracuje, a szybkość też w miare odpowiednia ;)

Zanim jednak całość zapisze do XML, sprawdzam czy taki plik z identyfikatorem już istnieje. Jeśli tak to sprawdzam czy jest starszy od określonej ilości minut, godzin, sekund czy jak tam chce :)

Po czym wiadomo, albo odczytuje dane z bazy i zapisuje do pliku, po drodze robie odpowiednio wyglądającą tablice array i wciepuje do smartów...

narazie mam to tak rozwiązane, wynik jest zadowalający, tym bardziej że to dość płynnie działa....

Gdy obiektowo dopisze cachowanie samego wyniku czyli gotowego pliku html i tak by mi to też działało jak ja bym chciał to sie pochwale :(

..:: Strony WWW ::....:: Nowe technologie ::....:: Hurtownie ::....:: Reszte znajdziesz w google.pl ::..

Odnośnik do komentarza
Udostępnij na innych stronach

To działa tak jak byś pod windows'em w jednym folderze zrobił sobie kilka tysięcy plików. a w innym tylko kilka. Spróbuj otworzyć oba katalogi i zobacz czy ci to szybko pokaże. Innym sposobem na sprawdzenie czy szybko ci sie wszystko wyświetli jak bys przez serwer FTP spróbował odczytać drzewo katalogowe w jakimś katalogu gdzie było by tych elementów kilka tysięcy. Nieco to wolno będzie działać...

Czy aby napewno?

Mi nie chodziło o wyświetlanie folderów tylko o dostęp (szybkość) do plików w tych folderach.

Odnośnik do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

  • 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