Portál AbcLinuxu, 10. května 2025 22:10
Řešení dotazu:
Tím je psát někomu, že nemá hledat problém v Apache, když tam pravděpodobně nějaký je.Jaký je problém v Apache, když se stránka generuje 1.5 sekundy a Apache mu i s tím generováním zvládá obsluhovat 1 požadavek na jádro za sekundu?
<php sleep(1); echo "Bye." ?>
. Pokud i tohle bude zasekávat Apache, tak máš problém v Apachi. Pokud se server nezaseká a prostě to postupně odbavuje požadavky N za sekundu, kde N je počet procesů v Apachi/PHP, tak Apache je v pohodě, ale server nestíhá řešit ten skript a asi mu nestačí paměť (nejen v PHP, ale třeba v databázi), takže se uswapuje.
Tak či onak, pokud to je možné, tak ten komplikovaný výpočet vyhoď z generování stránky a předpočítej si to asynchroně vedle. Nebo si předpočítej aspoň něco, aby to pak bylo výrazně rychlejší.
Ale i tak, ty tvoje hodnoty jsou divné. Že by prefork byl výrazně výkonější než worker se mi nezdá – prefork je v podstatě worker s poolem na procesy, aby klient nečekal na fork.Divne jsou tvoje informace. Worker je narozdil od preforku multithreadovy. Z toho plynou diskuze o pravech, kdyz se z nej ma poustet PHP po ruznymi uzivateli, nutnost thread safe knihovnen a podobne.
HTTP/1.1 200 1.82 secs: 12964 bytes ==> GET /homepage
Nasledne, testy po dobu 120s:
siege -c 50 -t120S -d 0 --no-parse https://.../homepage Response time: 3.92 secs Transaction rate: 12.61 trans/sec Throughput: 0.16 MB/sec Concurrency: 49.48 CPU Load 53
-c 100 Response time: 8.12 secs Transaction rate: 11.95 trans/sec Throughput: 0.15 MB/sec Concurrency: 97.03 CPU Load 63
ab -c 50 -t 120 -n 100000000 -l https://.../homepage Concurrency Level: 50 Requests per second: 12.60 [#/sec] (mean) Time per request: 3968.430 [ms] (mean) Time per request: 79.369 [ms] (mean, across all concurrent requests) Connection Times (ms) min mean[+/-sd] median max Connect: 6 146 536.8 7 3394 Processing: 849 3766 644.9 3870 5028 Waiting: 828 3666 629.5 3763 4975 Total: 1060 3912 534.7 3915 6376 Percentage of the requests served within a certain time (ms) 50% 3915 66% 4085 75% 4191 80% 4241 90% 4454 95% 4676 98% 5060 99% 5517 100% 6376 (longest request) CPU Load 50Kdyz se k tomu prida pozadavek sefa, ze ta homepage se ma zobrazit XXXx za vterinu (resp, zrychleni infra o Xnasobek) bez ohledu na optimalizace ze strany vyvojaru (idealne by nemeli delat zadne zmeny na zaklade mych zasahu), tak se to komplikuje, kdyz neni znam cas generovani te homepage na jinem HW/technologii a treba nasazeni Varnish cache pro php taky neni trivialni. Proto ten dotaz na rozdil mezi prefork a worker, to je jedine v kratkodobem horizontu mozne zmenit.
Nginx je ted taktez pase, aplikace dost vyuziva htaccess.To se nevylučuje. Tu trochu konfigurace lze snadno přepsat.
Pripominam, na te same VM bezi i db.A co žere víc? CPU? IO? Pusť si htop, přidej sloupeček na diskové IO a sleduj.
Jo a php skript, zobrazujici cestu, kde se nachazi, se pro 50 klientu vygeneruje pri 750tps, aniz by to bylo na loadu vyrazne znat.Nahoď XDebug, spusť profiler a nech si nahrát, kde to vázne. Jedno načtení stránky ti dá klidně pár desítek MB velký soubor, tak opatrně s tím. KCacheGrind ti pak záznam v souboru přechroupe a poví, co tam vlastně trvá dlouho. Ale tohle je práce pro vývojáře, ne pro admina. I když ti zas nebudou mít data z produkčního serveru, takže jim to asi budeš muset nahrát
Masivne zlepsit HW je problemHlavně to už moc nejde, jestli už teď tam máš 20 přiměřeně současných jader.
nepredpokladam, ze by to Debian7 zvladnul z hlediska ovladacu apod.Stejně to budeš muset za chvíli upgradovat, v květnu končí podpora.
Na tom problemovem virtualu mame tps (1,2,3,4 atd klienti): 1] 100,175,275,350 ...atd (zde zrejme vliv preforku na strop) 2] 27,50,72,118 ...atdJinými slovy škáluje to lineárně, přesně tak, jak by člověk čekal. Hele, už nám napiš, co jako očekáváš, že se stane. Prostě generování stránky ti trvá 1.5 sekundy (pro většinu stránek mi to přijde strašně moc, ale tvoji aplikaci neznám) a žádný webserver, CGI ani databáze s tím nic neudělá. Musíš prostě zrychlit to generování - bez znalosti aplikace se těžko radí, je potřeba zvážit, jestli se nepoužívají neefektivní algoritmy, jestli by to nešlo cachovat, jestli by to PHP nešlo zakompilovat do bytecode, a jestli by to nešlo napsat v nějakém rychlejším jazyce než je PHP.
Tak zacit muzes jiste tim ze se konecne podivas jestli ten procesor drti PHP nebo Postgres, skoro me to zacina zajimat. Zkus se na ten top podivat poradne a nestyd se nam to tajemstvi vyjevit.
Kdyz uz mas povolene ty statistiky, tak se pojdme podivat, jestli nekde nemuzeme pojmout podezreni, ze chybi index. To udelame tak, ze so podivame nad jakymi tabulkami se dela vic sekvencnich scanu, nez kolikrat se pouziva index scan:
SELECT relname, seq_scan-idx_scan AS too_much_seq, CASE WHEN seq_scan-idx_scan>0 THEN 'Missing Index?' ELSE 'OK' END, seq_scan, idx_scan FROM pg_stat_all_tables WHERE schemaname='public' ORDER BY too_much_seq DESC;
Ma to samozrejme vady - 1) ne vzdycky je sekvencni scan spatne - Kdyz si to uplne zjednodusime, cim mensi tabulka, tim min vadi, az je rychlejsi nez index a 2) ze tady vypada tabulka "dobre", neznamena, ze se s ni vsude pracuje velmi a spravne, jen dotazy z homepage potrebuji ten sekvencni scan a trvaji dlouho. Poucka: U tech tabulek co vypadnou jako podezrele se podivej na velikost, kdyz velke, (mozna) spatne.
Nezapomen, ze ten dotaz, tak jak je napsan, se diva jen na tabulky z public schema, pokud pouzivate pro tu databazi co nezname jine, musis ho nalezite upravit.
Taky nezapomen, ze ta aplikace bezi, v tech statistikach zdaleka nemas jen data od dotazu generovanych strankou, ktera te zajima.
Kdyz uz v tom budes, muzes se jiste cvicne podivat, jestli ti taky nejake indexy neprebyvaji, coz muze zpomalovat zapis (Pokud te chapu, je to nejaka homepage, takze toho asi moc nezapisuje a tohle je nam jedno, ale co uz, aspon uvidime, jak moc to vyvojari resi)
SELECT indexrelid::regclass as index, relid::regclass as table, 'DROP INDEX ' || indexrelid::regclass || ';' as drop_statement FROM pg_stat_user_indexes JOIN pg_index USING (indexrelid) WHERE idx_scan = 0 AND indisunique is false;
A sice jsem to povazoval za samozrejmost, ale zminit se to musi - ma ten Postgres zapnute autovacuum nebo je implementovano neco co dela neco periodicky vacuum? Pokud "nevim", zjistit, pokud ne, implementovat. Pokud se ty data meni, bez vacuum se ta databaze s casem zpomaluje az do uplne nepouzitenosti.
Az se probereme timhle, a budes mit pripravene k pouziti pg_stats_statements podle prislusne jedne stranky dokumentace, kterou si jiste prectes az do konce a uz me nebudes potrebovat, postoupime k pouziti, to pak bude teprve u vyvojaru zabava.
To ze jsi systemak a ne "db expert" je jedno, garantuju ze nic expertniho nedelame a delat ani nebudeme.
echo time();
$connection = @pg_connect("host=localhost port=5432 dbname=template1 user=USERNAME password=PASSWORD");
if($connection !== false)
{
$rows = pg_query($connection, "SELECT version();");
echo $rows !== false ? 1 : 0;
}
else
{
echo 'Spojeni se nezdarilo';
}
pustit treba pres siege/ab na 10s pro c=1.
Diky
Aplikaci resi vyvojari, ja nemam sanci poznat, zda nekde neco chybi.Můžeš ale např. logovat pomalé sql dotazy a pak je ukázat šéfovi a vývojářům s tím, že tohle je potřeba opravit. Na to dokonce není potřeba té databázi ani moc rozumět. Předem by ale bylo dobré si ověřit, že ta databáze netrpí nějakým problémem v nastavení (např. že má přiděleno málo paměti, že neprobíhá autovacuum apod.), na to ale už databázi rozumět potřeba je.
Connection Times (ms) min mean[+/-sd] median max Connect: 9 10 0.8 10 11 Processing: 809 826 28.1 834 858 Waiting: 790 810 29.3 820 844 Total: 820 836 27.8 844 868Ted je tam minimum navstevniku.
No vidis, prumerna delka query je pod 1 ms, to se bude profilovat primo lahudkove...
Body k vyzkumu:ab -c 10 -n10 url... ab -c 50 -n50 url... ab -c 100 -n100 url...Samozřejmě zvážit, zda to chcete nebo nechcete měřit na produkčním provozu (zatížíte ho).
Podobne se chova i jina VM. Ale, pokud pro otestovani pouzijeme novy navrh infrastruktury (odlisny hypervizor, debian, php atd, relativne stejny virtualizacni hw, ale vm disky jsou tentokrat na nfs serveru), ktery ma oddelene www a psql servery na samostatne VM, tak mame zhruba 2x tolik tps. Samozrejme, zmenily se doby provedeni ruznych db skriptu generujicich stranku (male dotazy zpomaleni, velke dotazy zrychleni).No a zkoušeli jste to spustit na čistém železe bez virtualizace? Nějaký současný hardware, rychlé SSD disky a dost paměti? Mohlo by to pomoct odfiltrovat případné problémy způsobené virtualizací, síťovým úložištěm.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.