Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: obciążenia php
Forum PHP.pl > Forum > PHP
maksik
Witam

Otrzymałem od admina serwera informację o zbyt nadmiernych obciążeniach procesami php i prośbę o optymalizację kodu php (nie korzystam z żadnego cms tylko autorskiego skryptu)

Chciałbym zapytać czy spotkaliście się już takim problemem lub znacie przykłady błędne napisanych kodów które mogły by powodować nadmierne obciążenia, zapętlenia skryptu?
Sephirus
Po kolei:

Cytat
czy spotkaliście się już takim problemem


W moim przypadku tak i to nie raz. Nie ma co się oszukiwać - czasem ruch na stronie bądź sama aplikacja jest częściowo niedopasowana wydajnościowo. Nieraz też występuję jakieś wąskie gardło. Wszystko jednak próbuję robić tak by kolokwialnie mówiąc "serwer to pociągnął".

Cytat
znacie przykłady błędne napisanych kodów które mogły by powodować nadmierne obciążenia, zapętlenia skryptu?


Tego to jest cała masa. Opcje ogólnie masz dwie:

- albo coś faktycznie źle zaprojektowałeś bądź zaimplementowałeś i serwer nie daję rady,
- albo masz za duży ruch i potrzebujesz mocniejszego sprzetu.

Powinieneś przetestować aplikację pod kątem wydajności, dać jakiegoś debuga (xdebug np), posprawdzać czasy, obłożenie pamięci i procka itd. Polecam też profilowanie (cachegrind itp.)

maksik
sądze, że to raczej błędne zaprojektowanie.

A co myślisz o tym jeżeli po wejściu z adresu domeny strona wolniej się ładuje niż po wejściu w nią poprzez link hostingu? Jak mógłaby wyglądać tego przyczyna? problem z dnsami nie występuje ponieważ obsługa serera zapewnia że spowodowane to jest jakimś błędnym kodem w skrypcie
Sephirus
Hmm ciekawe, ale szczerze mówiąc to nie powinno mieć znaczenia jeśli chodzi o obciażenie - jeśli nawet na domenie coś szwankuje to nie powinno to na hostingu nic obciążać bo jak? smile.gif

Osobiście bym szukał gdzie indziej przyczyny...

EDIT: podaj linki na priv to zerknę
thek
Cytat
zbyt nadmiernych obciążeniach procesami php i prośbę o optymalizację kodu php
Powiem tak... Z tego co widzę, komunikat mailowy sugeruje mi home.pl, który to wysyła takowy mail niemal każdemu, niezależnie od faktycznego obciążenia. Niedługo powinieneś dostać (lub już dostałeś) maila o możliwości przejścia na ich dedyka biggrin.gif Ja poprosiłem w informacji zwrotnej o slow logi, error logi itp. Powiem tylko, że przeglądając je był śmiech na sali. Czemu? Ponieważ w slow logu mysql potrafiło się znaleźć kwiatki w stylu: zapytanie z selectem do tabeli, która miała jakoś 20 wierszy o 3 krótkich kolumnach (jedna int i dwie varchar 30). I takie zapytanie wykonywało się, proszę się nie śmiać, około 8 sekund smile.gif Niestety ale to wiele mówi o hostingu, a raczej podejściu do klienta na maszynach typu shared (masowy overselling i nie tylko). Potem mają kwiatki, że serwery padają czy są nieludzko obciążone, nawet przy znikomym obciążeniu faktycznym przez danego klienta. Twój kod może być ok, ale inny klient tak zajeżdża zasoby maszyny, że innym się serwisy wykładają nawet na teoretycznie zoptymalizowanych skryptach. Dostają oni więc z automatu maile, choć nie powinni, gdyż inny klient tak masakruje maszynę, iż inni stojąc w kolejce do zasobów, przekraczają limity hostingu.

Tak więc najlepsze rozwiązanie to: poproś hosting o logi i przejrzyj je (lub poproś kogoś kto to rozumie) oraz zinterpretuj by wyszukać "winowajcę".
maksik
akurat az.pl... ale masz rację poproszę o logi i zobaczymy wink.gif


Skontaktowałem się z działem technicznym i ztwierdzili że powodem może być duża ilość zapytań do bazy danych. W skrypcie jest dosyć dużo funkcji "$query = mysql_query('SELECT..." ale każda pobiera inne dane z danej tabeli, to może być problemem? ale jak z tym sobie poradzić?
mstraczkowski
Uwielbiam takie "wojny" między programistami a serwerowcami smile.gif

Skoro sugerują ci zapytania do bazy danych.
Poproś o slow loga w nim powinieneś znaleźć odpowiedź
maksik
dostałem właśnie logi, ale nie wiem już sam jak sobie z nimi poradzić
są to rzekomo "wiszące procesy"

| Query | 3 | Locked | UPDATE `Ads` SET `HitsAd`=`HitsAd` + '2' WHERE `Id_ad`='24197' |
| Query | 4 | Sending data | SELECT Ads.Id_ad, Source, ImgFB FROM Ads WHERE NOT EXISTS (Select Id_ad FROM AdsClick WHERE Ads.Id_a |
| Query | 3 | Locked | SELECT * FROM Ads WHERE Login='kamil.jesk' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 3 | Locked | SELECT * FROM Ads WHERE Login='kamil.jesk' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 3 | Locked | SELECT * FROM Ads WHERE Login='cyber3606' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 2 | Locked | SELECT * FROM Ads WHERE Login='dorota180' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 1 | Locked | SELECT * FROM Ads WHERE Login='SENATOR76' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 0 | Locked | SELECT * FROM Ads WHERE Login='Florcia' ORDER BY Id_ad DESC LIMIT 0,20


gdyby ktoś z was wiedział jak sobie poradzić z taką sprawą w miare szybko dałby radę się z tym uporać i mógłbym to mu zlecić, proszę na priv dać znać
mstraczkowski
Niestety, ale analiza i wyszukanie wąskich gardeł aplikacji nie jest do "do szybkiego uporania się".
Ten proces może być naprawdę czasochłonny i kosztowny.

To że w slow logu znajdują się zapytania oznacza że albo baza/tabele są źle zaprojektowane, albo zapytania są wykonywane zbyt często np. pętla w pętli.
Albo zapytania są zaprojektowane mało wydajnie

Jest też możliwość, że hosting próbuje namówić do kupna czegoś lepszego

PS: Nie podoba mi się zapytanie z WHERE NOT EXISTS

W slow logu powinieneś mieć także czasy wykonania danych zapytań, przeanalizuj wpisy o największym czasie wykonania i postaraj się zoptymalizować te zapytania jeżeli jest taka możliwość wg ciebie
daniel1302
Dokładnie jak wyżej +

Cytat
sądze, że to raczej błędne zaprojektowanie.

A co myślisz o tym jeżeli po wejściu z adresu domeny strona wolniej się ładuje niż po wejściu w nią poprzez link hostingu? Jak mógłaby wyglądać tego przyczyna? problem z dnsami nie występuje ponieważ obsługa serera zapewnia że spowodowane to jest jakimś błędnym kodem w skrypcie


Być może używasz złych serwerów DNS, provider domeny, albo sam ustawiałeś w domenie.
Wykonaj w konsoli polecenie:
Linux:
Kod
traceroute TWOJA_STRONA

Windows:
Kod
tracert TWOJA_STRONA

wykonaj je 2 razy dla adresu domeny oraz serwera

Powodem może być to, że twoja tabela zawiera zbyt wiele rekordów(kilkadziesiąt/kilkaset tysiecy) , ale bardziej prawdopodobne jest to, że używasz zapytania pętla w pętli. Dodaj licznik zapytań, jeśli używasz PDO to rozszerz funkcje (np przez dziedziczenie) a jeśli innego sterownika to napewno jest zaimplementowany (nie mówię o funkcjach typu mysql_*)
maksik
Cytat(daniel1302 @ 12.02.2013, 19:32:38 ) *
ale bardziej prawdopodobne jest to, że używasz zapytania pętla w pętli. Dodaj licznik zapytań, jeśli używasz PDO to rozszerz funkcje (np przez dziedziczenie) a jeśli innego sterownika to napewno jest zaimplementowany (nie mówię o funkcjach typu mysql_*)



Mógłbyś powiedzieć coś więcej o tym zapytaniu "pętla w pętli"? do tabeli z którą jest problem dochodzi codziennie ok. 5tyś rekordów także masz racje z tym że moze zawierać zbyt wiele rekordów, ale one muszą być...

Co do zmiany na wyższy plan hostingu, sam to zasugerowałem lecz usługodawca zasugerował, abym najpierw wykonał optymalizację bo to może nie pomóc. Póki co jest ok bo przeczyściłem troche tabele, ale co dalej?
daniel1302
no np takie coś
tabela uzytkownicy, avatary(avatary userow), rozdzielone dla prezentacji
  1. $query = mysql_query('SELECT id, imie FROM uzytkownicy');
  2.  
  3. while($osoba = mysql_fetch_assoc($query))
  4. {
  5. $avatar = mysql_fetch_assoc(mysql_query("SELECT * FROM avatary WHERE wlasciciel=$osoba['id']"));
  6.  
  7. }


Można to zapisać bardziej optymalnie:
  1. $query = mysql_query("SELECT u.id, u.imie, a.id as avatar_id, a.file, a.wlasciciel FROM uzytkownicy u LEFT JOIN avatary a ON a.wlasciciel=u.id");
  2. while($osoba = mysql_fetch_assoc($query))
  3. {
  4. //Wykonujemy 2 razy mniej azapytań
  5. }
mstraczkowski
@up Bardzo dobry przykład.

Zgadzam się z twoim usługodawca, (chyba że serwer jest na prawdę beznadziejny) to jego zmiana pomogła by na krótką metę, doszło by kolejne kilkadziesiąt tyś. rekordów i problem wystąpi ponownie.
daniel1302
Mysql ostatnio się bardzo poprawiło, odkąd Oracle je przejęło, rozwija się bardzo dynamicznnie, znam przykłady baz danych pracujących na MYSQL, które zajmują powyżej 20GB. Serwer to 2x1.6GHz i 2 GB ramu gwarantowane a czasem 3. I nie mają żadnych problemów
mstraczkowski
Wiadomo, że software też odgrywa znaczącą rolę, ale bardzo dużo zależy od tego na jakim sprzęcie stoi baza danych oraz jak jest skonfigurowana (prawidłowo skonfigurowana baza danych to sztuka).

Osobiście się cieszę, że MySQL zmierza w dobrym kierunku aczkolwiek na razie do dużych baz danych polecałbym używanie Postgresa/Oracle.
Ew. MSSQL na nim też widziałem ogromne bazy.

maksik
daniel1302 - dziekuje za przykład, ale właśnie w ten bardziej optymalny sposób mam zapisany kod. Może winy trzeba szukać w indexach w bazie danych? mogą być one np źle napisane i przez to jest problem?
mstraczkowski
Owszem, indeksy mogą być nieprawidłowe.

Zacznijmy od tego, że indeksy są użyteczne przy dużej ilości rekordów (w przypadku małych tabel mogą działać wręcz odwrotnie)

Indeksy powinny być nakładane na tabele, które są często przeszukiwane (SELECT), a rzadko zmieniane (UPDATE, INSERT).
Każdy indeks spowalnia zapytania INSERT oraz UPDATE, natomiast przyśpiesza SELECT.

Dlatego nie warto nakładać indeksów na tabelę, do której dziennie wpada np. kilka tysięcy rekordów, a wyszukiwanie w niej odbywa się rzadko.

Indeksy powinny być nakładane na pola po których wyszukujemy, bardzo ważne jest to, aby nakładać indeksy w takiej kolejności w jakiej występują one w warunku WHERE (jeżeli wyszukujemy za pomocą kilku kryteriów)
maksik
w moim przypadku są powiedzmy dwie tabele. X i Y,

X posiada ok. 2 tys rekordów i wyświetla pojedyńczo użytkownikowi wyselekcjonowane wyniki, gdy użytkownik zatwierdzi dane, zapisują się wtedy o tej akcji informacje do tabeli Y (która posiada ok. 20 tys. rekordów) które mają na celu zapamiętanie danych które zatwierdził.

więc każde wyświetlenie pojedyńczego wyniku z tabeli X najpierw sprawdza tabele Y czy już wynik nie był wyświetalny wcześniej, aby się nie powtarzał.
daniel1302
Poza szczególnymi przypadkami do 10 zapytań na stronie raczej przechodzi bezproblemowo, powyżej tej liczby zaczynają się problemy.

Staraj się wewnątrz pętli nie wykonywać zapytania.
20 tyś rekordów to nie jest tak dużo. Aczkolwiek daj ofertę jaką wykupiłeś i hosting jeśli info nie jest tajne
maksik
Nie robie nikomu antyreklamy, bo to pewnie głównie problem skryptu, ale oferta to personal hosting w A zet ;p
daniel1302
Hmm, az.pl nigdy nie kupowałem, ale niech wyślą ci dane dotyczące obciazenia logi przez twoje konto. W jakiejś formiektóra umożliwi łatwą analize i ew generowanie wykresów
maksik


Cytat(maksik @ 12.02.2013, 10:15:35 ) *
| Query | 3 | Locked | UPDATE `Ads` SET `HitsAd`=`HitsAd` + '2' WHERE `Id_ad`='24197' |
| Query | 4 | Sending data | SELECT Ads.Id_ad, Source, ImgFB FROM Ads WHERE NOT EXISTS (Select Id_ad FROM AdsClick WHERE Ads.Id_a |
| Query | 3 | Locked | SELECT * FROM Ads WHERE Login='kamil.jesk' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 3 | Locked | SELECT * FROM Ads WHERE Login='kamil.jesk' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 3 | Locked | SELECT * FROM Ads WHERE Login='cyber3606' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 2 | Locked | SELECT * FROM Ads WHERE Login='dorota180' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 1 | Locked | SELECT * FROM Ads WHERE Login='SENATOR76' ORDER BY Id_ad DESC LIMIT 0,20 |
| Query | 0 | Locked | SELECT * FROM Ads WHERE Login='Florcia' ORDER BY Id_ad DESC LIMIT 0,20

mstraczkowski
A tak mi się jeszcze przypomniało, byłem świadkiem sytuacji jak pewien hosting (dosyć poważny gracz na polskim rynku, nazwy nie będę jednak oficjalnie podawać)

Informował o bardzo dużym obciążeniu pamięci RAM (ponoć baza danych zabierała całą pamięć).
Potem gdy RAM się skończył grzebała po dysku (tymczasowe tabele itd)

Nałożony został więc co 5 - 10 minutowy cron, zapisujący wynik użycia pamięci do pliku (linuxowy top)

Po kilku dniach, doszło do analizy, w logach nic nie zjadało pamięci (tak jak było wciskane), a serwis padł poprzedniego dnia.
Po poinformowaniu o tej sytuacji hostingu dowiedzieliśmy się, że codziennie wykonywany jest backup (akurat w tym czasie co serwis padał)
I to przez ich backup + ruch dochodziło do padnięcia serwera

Później użycie top, nie było już możliwe (zostało zablokowane), można trochę wniosków powyciągać.

Pozdrawiam
thek
A najlepsze są infolinie. Człowiek po rozmowach tam kończy głupszy niż był przed zadzwonieniem wink.gif Pół biedy gdy trafi na osobę kumatą, ale jesli to będzie marketingowiec, który ma wrażenie że wie lepiej od osoby, która ma wykształcenie techniczne i siedzi w branzy lata, to robi się tragedia. Nieraz miałem takie przeboje gdy jakis hosting padał. Ja od razu z mostu prosiłem o osobę z działu technicznego lub zaczynałem sypać takimi terminami, że sami po niego wołali biggrin.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.