Nette, Doctrine a další pomalost – několik otázek
- Jiří Nápravník
- Člen | 710
Zdravím,
prosím o radu, jak nejlépe vyladit rychlost Nette.
Mimo samotné Nette používám Kdyby\Doctrine, Kdyby\Events a Kdyby\Autowired, Webloader. Ostatní addony nepředpokládám, že způsobovalo něco extra, je jich pár a jsou spíše jednorázové.
Stránka na lokále jede něco přes 2sekundy, tam to není až tak překvapivé, mám pomalejší PC, ale i tak mi ostatní frameworky jedou cca 1sec. Když hodím na web, tak většinou mám zpracováno 0,8sek v průměru. Přičemž sejná aplikace běžící na Zendu 1 (bez Doctrine).
A teď k otázkám:
- Zkusil jsem profilovat. A 100ms zabere jenom načtení containeru z cache (při generování samozřejmě ještě více). Mám v kontejneru celkem asi tak 40 služeb a přibližně stejný počet generovaných továrniček. Koukal jsem dále a při načítání kontejneru se kontrolují všechny soubory co jsou v něm uložené. Nejen extensions a neon soubory, ale třbea v případě genereované továrnicčky to kontroluje i soubor s interfacem i souborem, co má generovat. Nejde nějak na produkci přepnout, aby se prostě container nekontroloval v cachi, a musel ho smazat z cache aby se přegeneroval a nedělalo se to automaticky?
- Mám asi dvacet rout. Chci se zeptat, je nějaký výkonový rozdíl, pokud napíšu jednotlivé routy nadefinované jako běžně. Nebo pokud si udělám jeden jediný router, kde si budu dělat řízení sám?
- Je obecně něco na co dát pozor? Vyčetl jsem, že je pomalejší generování odkazů, tak jsem využil tam kde je hodně podobných odkazů ten trik s replacem.
- Když profiluji, tka koukám, že Webloader zabírá taky celke mdost času, mám tam dvě komponenty pro javascript a css. Neexistuje u webloaderu nějaká možnost, že bych vždy předgeneroval ty js/css a na produkci už to posílal rovnou zkompilované, aby to zase nemuselo všechno kontrolovat apod?
- Jak se chová výkonnost Nette, pokud mám povolený debugger jen pro svoji IP. Já totiž když ho takto povolím, tak u mě je to až +200ms, je to tak i u ostatních lidí, kteří mají jinou IP? Jak to tam funguje, prostě projde to celým tím rpocesem jen to debug bar nevyhodí, nebo je to jako když je enableDebugger(FALSE)?
- Kdyby\Autowired, nemůže být nějak pomalejší, oproti klasickému injectu přímo v nette, podle mě ne. Spíše naopak, když je to lazy. Ale raději se ptám.
Problém je hlavně také v tom, že to běži v clusteru, což je network filesystem a tak jsou pomalé IO operace, proto pravděpodobně pomalé načtení containeru apod.
Budu rád za jakékoli rady, protože jsem přecházel na Nette také hlavně kvůli rychlosti. Všde jsem četl, jak to mají i s doctirnou pod 50ms apod:)
Nutno taky podotknout, že to není napsáno nijak extra prasácky, jenom stránka s formulářem a jednou komponentou. Celkem s 0 SQL dotázy se mi načítá na serveru 0,4 sekundy…
- David Matějka
- Moderator | 6445
1.
A 100ms zabere jenom načtení containeru z cache
zapni opcode cache a bude to mene :)
Nejen extensions a neon soubory, ale třbea v případě genereované továrnicčky to kontroluje i soubor s interfacem i souborem, co má generovat
pouze pri debug modu, na produkci jsou tam jen neon soubory
2. samozrejme kazda nova routa muze prinest zpomaleni. Co bude pro vykon lepsi si musis vyzkouset sam.
- Tomáš Votruba
- Moderator | 1114
Ad Doctrine, doporučuji přečíst Doctrine 2 není pomalá od Ondry Mirtese.
- Filip Procházka
- Moderator | 4668
FYI Kdyby/Doctrine by měla řešit produkční mód a nastavit všechno pro maximální výkon. Jediný co, tak by sis měl nainstalovat například apcu a nastavit do něj cache metadat.
annotations:
cache: apc
doctrine:
metadataCache: apc
queryCache: apc
1. Zkusil jsem profilovat. A 100ms zabere jenom načtení containeru z cache (při generování samozřejmě ještě více). Mám v kontejneru celkem asi tak 40 služeb a přibližně stejný počet generovaných továrniček.
Mám v aplikaci 613 služeb a 95 generovaných továrniček.
Upgraduj na PHP 5.5 a zapni opcode cache, tohle je moje konfigurakce
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=128
opcache.interned_strings_buffer=12
opcache.max_accelerated_files=4000
opcache.validate_timestamps=0
opcache.fast_shutdown=1
opcache.save_comments=1
opcache.load_comments=1
opcache.verbosity_level=2
Koukal jsem dále a při načítání kontejneru se kontrolují všechny soubory co jsou v něm uložené.
To se děje jenom v development módu, bys nemusel mazat cache když upravíš konstruktor nějaké třídy.
2. Mám asi dvacet rout. Chci se zeptat, je nějaký výkonový rozdíl, pokud napíšu jednotlivé routy nadefinované jako běžně. Nebo pokud si udělám jeden jediný router, kde si budu dělat řízení sám?
Méně rout = lepší výkon.
Routery jsme extra nijak neměřili, zase tolik to není. Reguláry jsou rychlé :)
4. Když profiluji, tka koukám, že Webloader zabírá taky celke mdost času, mám tam dvě komponenty pro javascript a css. Neexistuje u webloaderu nějaká možnost, že bych vždy předgeneroval ty js/css a na produkci už to posílal rovnou zkompilované, aby to zase nemuselo všechno kontrolovat apod?
Nad tímhle jsem tuhle taky přemýšlel, že bych chtěl command co to předgeneruje, ale ještě jsem se k tomu nedostal. Nechceš poslat pullrequest s konfigurační volbou, která by tu kontrolu vypla? :)
5. Jak se chová výkonnost Nette, pokud mám povolený debugger jen pro svoji IP.
To se týká jenom tebe pro tvoje requesty.
6. Kdyby\Autowired, nemůže být nějak pomalejší, oproti klasickému injectu přímo v nette, podle mě ne. Spíše naopak, když je to lazy. Ale raději se ptám.
Pomalejší to je, ale neznatelně. Závislosti se zkontrolují a nacachují.
Nejrychlejší je použít public @inject
a mít presentery v DI
Containeru tak aby to závislosti našlo jednou a vygenerovalo kód který je
vkládá.
- Jiří Nápravník
- Člen | 710
matej21 napsal(a):
1. zapni opcode cache a bude to mene :)
opcode cache je zapnuta – APC. V PHP 5.5 je opcode cache inbuilt, ale to to zatím nemáme, vím, že je možnost zkompilovat i pro php 5.4, ale to asi nebude možné jen tak v blízké odbě. Ale APC by mělo snad taky pomoci ne?
2. samozrejme kazda nova routa muze prinest zpomaleni. Co bude pro vykon lepsi si musis vyzkouset sam.
mě šlo spíše o to, jestli je lepší výkonově mít více rout vypsaných přímo v RouteListu, nebo udělat jednu vlastní routu, která si bude matchovaní a sestavování url, řešit sama. Na základě zkušeností,m zda to má smysl vůbec zkoušet…
@Casper: na to jsem koukal, sql dotazy jsou rychlé, dibi nepoužívám, minified verzi jsem nezkoušel, ale prý když se jede přes nějakou opcode cache, tak je lepší používat full-verzi
- David Matějka
- Moderator | 6445
Jiří Nápravník napsal(a):
Ale APC by mělo snad taky pomoci ne?
Jedu na 5.4 a APC a vykonostne ok..
Jen nastav
apc.stat = 0
to zajisti, ze se nebude pri kazdem requestu kontrolovat, zda nebyl php soubor upraven. problem je, ze pri deploy musis smazat cache – bud treba php-fpm reload nebo je pro to i nejaka php fce (ale nestaci ji spustit v cli)
dalsi optimalizace muze byt
composer dump-autoload -o
to ti vytvori class map vendor slozky
- Jiří Nápravník
- Člen | 710
Filip Procházka napsal(a):
FYI Kdyby/Doctrine by měla řešit produkční mód a nastavit všechno pro maximální výkon. Jediný co, tak by sis měl nainstalovat například apcu a nastavit do něj cache metadat.
APC mám nainstalovaný ale cache těhle věcí jde do filesystemu. Což není dobré vím, měl jsem storage na memcache, ale jak to je v clusteru tak jsem to musel vyhodit, protože jsem mohl vždy mazat cache pouze z jednoho místa (nak terý node mě zrovna hodil). Předpokládám, že to bude v případě APC stejné, ne?
A celkově jak se to pak chová, když někdo restartne server, to se paměť vyčistí a musí se vše nacachovat znovu ne? když teď cachuji do filesystemu, nebo jsem zkoušel i do sqlite, tak než se nacachují metadata a anotace, tak to zabere bez problémů více než minutu…
Mám v aplikaci 613 služeb a 95 generovaných továrniček.
a za jak dlouho máš v tomhle případě s opcode cachí načteno?
Nad tímhle jsem tuhle taky přemýšlel, že bych chtěl command co to předgeneruje, ale ještě jsem se k tomu nedostal. Nechceš poslat pullrequest s konfigurační volbou, která by tu kontrolu vypla? :)
to je zatím bohužel mimo mé schopnosti:-)
matej21: apc.stat = 0 není příliš reálný vyvíjí se celkem dost na tom serveru, a tak bych pořád musel řešit promazávání cache. Composer mám optimizovaný autoloader. Používám jej i místo robotloaderu v app
- Filip Procházka
- Moderator | 4668
APC mám nainstalovaný ale cache těhle věcí jde do filesystemu. Což není dobré vím, měl jsem storage na memcache, ale jak to je v clusteru tak jsem to musel vyhodit, protože jsem mohl vždy mazat cache pouze z jednoho místa (nak terý node mě zrovna hodil). Předpokládám, že to bude v případě APC stejné, ne?
Jenže je to nesrovnatelně pomalejší, daleko menší problém je to nacachovat jednou dvakrát navíc.
- Jiří Nápravník
- Člen | 710
JJ, to já chápu. Jenže zrovna v tom případě, když jsem tam měl memcache. Tak jsem pak šel do konzoly, protože jsem upravil entitu a že smažu cache, aby si to načetlo nový data z entity. Jenže ono to smazalo jenom na tom jednom serveru, a ne na tech ostatnich, protoze jsem bezel ja na tom jednom nodu, a uzivatele na tech starych mely stary metadata, proto jim to nefungovalo. Jedine by to musel resit admin. Já s ním řeším, jeslti to nějak půjde, protože vím, že paměť je rychlejší než filesystem, byl tam na serveru rozdíl až 200ms. Ale třeba u mě na lokale jsem odzkoušel, že funguje nejlépe sqllite storage, dokonce lépe než filesystem nebo memcache.
Jinak můžeš mi pls říct, jak řešíš u těhle memory cachí, když se restartne server, resp. za jak dlouho se to obnoví? u mě to trvá opravdu dlouho, u memory je to sice rychlejší, když jsem ji zkoušel, ale i tak. když to vím ,tak vystavím maintenance.php a počkám až se to přegeneruje. Nebo je tohle vystavení zbytečné a nějak to řeší samo Kdyby\Doctrine nebo Nette podle tohohle?
- Jiří Nápravník
- Člen | 710
@Chipso: Tj hodně zjednodušený pohled. S určitou režií pro potřeby ORM samozřejmě počítám. Ale pokud mají lidi s ORM aplikace rychlejší třeba desetkrát než já, tak se ptám co vylepšít.
Nemluvě o tom, že tady to není jen o ORM, protože jak jsem psal, tak i jenom strának, kde je jeden form a na doctrinu není nijak sáhnuto (snad jedině inicializace entitymanageru), má load 500ms… Samotný action/render metody, které volají model a tím pádem i Doctrine, jsou tak pětina času celého času.
- David Matějka
- Moderator | 6445
U tebe tam fakt budou problem ty I/O operace. Urcite musis vyresit tu opcode cache, aby porad nekontrolovala soubory – proste udelat nejakej script, kterej pri deploy invaliduje apc cache na vsech serverech.
Pak nette cache na ruznych mistech kontroluje zmenu v souborech, namatkou template, cache makro nebo jiz zmineny generovany container. Toho by bylo vhodny se taky zbavit..
U webloaderu by melo stacit vypnout kontrolu last modified
Editoval matej21 (23. 4. 2014 0:11)