[PHP] Persistent vars

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Voor het cachen van bepaalde query results was ik op zoek naar persistent variables die nadat een script run is afgelopen gewoon blijven bestaan en in de volgende script run automatisch weer beschikbaar zijn.
Zo te zien kan dit met PHP niet, maar weet iemand waarom niet?
Het lijkt me erg handig voor bijvoorbeeld caching.

Shared memory of zelfs gewone files zijn ook mogelijk, maar dan moet toch elke keer alles weer gelezen, geparsed, geparsed en gescheven worden.

Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
Voor caching van SQL resultaten? Lijkt me een nachtmerrie. Eén cache per pagina is genoeg, denk aan alle ellende met update statements en dergelijke. Je zult een goede garbage collection moeten inbouwen wil je zoiets kunnen maken.

Globale variabelen die je overal nodig hebt definieer je als een constante in een file,
variabelen die wel wilt wijzigen bewaar je meestal toch per sessie.

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Skaah schreef op 25 juni 2004 @ 00:34:
Voor caching van SQL resultaten? Lijkt me een nachtmerrie. Eén cache per pagina is genoeg, denk aan alle ellende met update statements en dergelijke. Je zult een goede garbage collection moeten inbouwen wil je zoiets kunnen maken.
Denk bijvoorbeeld aan een 'shoutbox' of de online list.
Of de Reacties en GoT Tech Forums lijstjes op de frontpage.

Wat bedoel je met een cache per page?

Acties:
  • 0 Henk 'm!

  • Morax
  • Registratie: Mei 2002
  • Laatst online: 20-09 00:30
OlafvdSpek schreef op 25 juni 2004 @ 01:44:
[...]

Denk bijvoorbeeld aan een 'shoutbox' of de online list.
Of de Reacties en GoT Tech Forums lijstjes op de frontpage.

Wat bedoel je met een cache per page?
Wat je bijvoorbeeld met een shoutbox kan doen, is de laatste zoveel shouts in een text bestand zetten en ze van daaruit uitlezen.

Bij de functie die een edit of nieuwe shout invoert, voer je dan ook gelijk een functie in die het tekstbestandje dan weer update.

Of is dit niet helemaal wat je bedoelt?

What do you mean I have no life? I am a gamer, I got millions!


Acties:
  • 0 Henk 'm!

Verwijderd

Skaah schreef op 25 juni 2004 @ 00:34:
Globale variabelen die je overal nodig hebt definieer je als een constante in een file,
variabelen die wel wilt wijzigen bewaar je meestal toch per sessie.
Die zijn natuurlijk wel enkel beschikbaar tijdens de uitvoer van het script, de TS wil de variabele ook na de uitvoer van het script kunnen aanspreken.

Gewoon in een tekstfile zetten, simpel als iets en doet toch ook perfect wat je wilt ...?

Acties:
  • 0 Henk 'm!

  • mjax
  • Registratie: September 2000
  • Laatst online: 10:03
OlafvdSpek schreef op 25 juni 2004 @ 00:30:
Shared memory of zelfs gewone files zijn ook mogelijk, maar dan moet toch elke keer alles weer gelezen, geparsed, geparsed en gescheven worden.
Het opslaan en weer inlezen van files is niet zo ingewikkeld. Voorbeeldje:

Opslaan:
PHP:
1
2
3
$fp = fopen($filename, 'w');
fputs($fp, serialize($variabele));
fclose($fp);


Inlezen:
PHP:
1
$variabele = unserialize(implode('', file($filename)));


Hier zou eigenlijk nog wat file locking statements bijmoeten, maar die heb ik voor het overzicht weggelaten. Ik gebruik dit mechanisme ook voor het cache van bepaalde queries, maar zoals Skaah al zei kan het cachen van query resultaten op een nachtmerrie uitdraaien, omdat je een mechanisme zult moeten verzinnen die de juiste caches updated/verwijderd als een tabel wijzigt qua inhoud. Zeker bij queries die ingewikkelde joins maken is dat niet gemakkelijk generiek op te lossen.

Acties:
  • 0 Henk 'm!

Verwijderd

Waarom gebruik je geen sessies?

Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
OlafvdSpek schreef op 25 juni 2004 @ 01:44:
[...]

Denk bijvoorbeeld aan een 'shoutbox' of de online list.
Of de Reacties en GoT Tech Forums lijstjes op de frontpage.

Wat bedoel je met een cache per page?
Als je een cache van queries en resulsets bijhoudt, moet je die op het eind van elke pagina wissen. Anders krijg je, zoals al opgemerkt werd, een nachtmerrie.
Verwijderd schreef op 25 juni 2004 @ 04:12:
Die zijn natuurlijk wel enkel beschikbaar tijdens de uitvoer van het script, de TS wil de variabele ook na de uitvoer van het script kunnen aanspreken.
Ná de uitvoer van een script? Wat moet er dan precies bij die variabelen kunnen? Een ander script, dat uitgevoerd wordt?

TS, je zou eventueel een automagisch script kunnen bouwen dat variabelen in de database opslaat aan het eind van elke pagina, en ze weer beschikbaar maakt aan het begin van elke pagina. MySQL heeft een tabeltype dat alleen in het geheugen wordt opgeslagen, dat is hier zeer geschikt voor, denk ik. Het werkt dan een beetje als het Application-object in ASP. (Als ik me niet vergis).

Pas een beetje op met cachen, als je zoveel extra performance nodig hebt, kun je beter je server opwaarderen, of je pagina's efficienter schrijven. Waarom wil je dit eigenlijk?

[ Voor 53% gewijzigd door Skaah op 25-06-2004 09:12 ]


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Verwijderd schreef op 25 juni 2004 @ 08:59:
Waarom gebruik je geen sessies?
Omdat bij 5000 simultane gebruikers die continu de topiclist van je forum opvragen je dan alsnog 5000 caches aan het bijhouden bent, terwijl je ook 1 cache kunt bijhouden die je invalidate zodra er 1 iemand een nieuw topic maakt.

ASP.NET heeft hier wel ondersteuning voor, daar kun je in Page.Session (System.Web.SessionState.HttpSessionState) de sessie-lokale data kwijt en in Page.Cache (System.Web.Caching.Cache) de globale data.

Ik zal chem eens vragen hier te komen kijken, React doet namelijk uitgebreide caching afaik :)

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Morax schreef op 25 juni 2004 @ 03:01:
Wat je bijvoorbeeld met een shoutbox kan doen, is de laatste zoveel shouts in een text bestand zetten en ze van daaruit uitlezen.

Bij de functie die een edit of nieuwe shout invoert, voer je dan ook gelijk een functie in die het tekstbestandje dan weer update.

Of is dit niet helemaal wat je bedoelt?
maar dan moet toch elke keer alles weer gelezen, geparsed, geparsed en gescheven worden.
Vooral voor wat complexere caches lijkt me dat niet handig.

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Skaah schreef op 25 juni 2004 @ 09:08:
Pas een beetje op met cachen, als je zoveel extra performance nodig hebt, kun je beter je server opwaarderen, of je pagina's efficienter schrijven. Waarom wil je dit eigenlijk?
Als proof-of-concept dat het kan. En voor later als ik het mogelijk echt nodig heb.

Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
curry684 schreef op 25 juni 2004 @ 09:16:
[...]

Omdat bij 5000 simultane gebruikers die continu de topiclist van je forum opvragen je dan alsnog 5000 caches aan het bijhouden bent, terwijl je ook 1 cache kunt bijhouden die je invalidate zodra er 1 iemand een nieuw topic maakt.
Dat hoort je databeest te cachen, en dat doet MySQL dan ook. Ik heb hier een keer mee geëxperimenteerd, 3000 queries, waarvan 600 dubbele, op de database afgevuurt mét en zonder caching van PHP (gewoon, in één pagina, dus in het geheugen). Het scheelde ongeveer 10% in het voordeel van PHP cachen (Athlon XP 2600+ / 1024MB DDR400, Windows XP / Apache 1.3 / MySQL 3.x / PHP 4.3.3). Die winst raak je gemakkelijk kwijt door de overhead van het inlezen van een bestand en kijken of je query al een keer gecached is.

Cachen in files lijkt me een stuk langzamer dan een database, en een stuk complexer. En om nou het hele shared-mem vol te stoppen met caches, voelt IMHO ook niet helemaal fijn.
Ik zal chem eens vragen hier te komen kijken, React doet namelijk uitgebreide caching afaik :)
Chem is liev :+

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 19-09 22:18

chem

Reist de wereld rond

Eigenlijk haalt React alles opnieuw op, maar wordt er veel data gedenormaliseerd opgeslagen (zoals counters).

Er zit wel support in voor, bijvoorbeeld, mmCache. Hiermee kunnen we idd resultsets opslaan van algemene queries zoals de forumdropdown onderaan en de gebruikersrechten.

SHM zou ik je sterk afraden, aangezien het nogal wat ellende kan opleveren (PHP was er nooit zo heel sterk in iig). Je kan wel een serialized value in een HEAP table van MySQL (of een andere db-server) zetten. (un)serializen is echt heel snel in PHP, en een HEAP table is ook erg snel :+
Zit je trouwens wel weer in/met de database...

Maar veel winst maak je er niet mee, de meeste db-servers kunnen best aardig cachen, en sommige kunnen zelfs queries cachen (mits alle gerelateerde tables untouched zijn).

Zelf vind ik mmCache (of Zend Cache) 1 van de weinige oplossingen, aangezien de techniek bewezen is en er nagenoeg geen overhead is.

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Skaah schreef op 25 juni 2004 @ 09:52:
[...]

Dat hoort je databeest te cachen, en dat doet MySQL dan ook. Ik heb hier een keer mee geëxperimenteerd, 3000 queries, waarvan 600 dubbele, op de database afgevuurt mét en zonder caching van PHP (gewoon, in één pagina, dus in het geheugen). Het scheelde ongeveer 10% in het voordeel van PHP cachen (Athlon XP 2600+ / 1024MB DDR400, Windows XP / Apache 1.3 / MySQL 3.x / PHP 4.3.3). Die winst raak je gemakkelijk kwijt door de overhead van het inlezen van een bestand en kijken of je query al een keer gecached is.
Dan is dat baggerslechte caching in PHP of je hebt heel foute benchmarks gedaan. Goede in-memory caching is vanzelfsprekend tig keer sneller dan opnieuw de hele query compileren, de data induiken en alles opnieuw verzamelen. Zelfs al is de hele resultset gecached sla je nog de lookup stap van de database en een rits IPC over als je de hele dataset kant en klaar preformatted in je DAL hebt hangen. Dat is ook 1 van de grote voordelen van een DAL: als je updates en selects door dezelfde abstractielaag trekt kun je aannames maken over wanneer je cache al of niet dirty is, wat je een stuk intelligenter kunt doen dan de database zelf.

Met complexe queries, en tig joins en views is er in de extreemste gevallen tegen SQL Server vanuit een middle tier meer dan 50% winst realiseerbaar kan ik uit ervaring melden: en SQL Server cached slimmer dan MySQL, geloof me.
Cachen in files lijkt me een stuk langzamer dan een database, en een stuk complexer. En om nou het hele shared-mem vol te stoppen met caches, voelt IMHO ook niet helemaal fijn.
Waarvoor stop je dan al dat geheugen in zo'n server? :? Indien de DAL en DB op dezelfde server draaien is er nog iets te zeggen, maar zelfs dan nog is het twijfelachtig in hoeverre je puur en alleen de DB aan het cachen wil hebben, omdat je als applicatie simpelweg veel betere aannames kunt maken en voorspellingen kunt doen over de 'houdbaarheid' en 'use frequency' van de te selecteren data.

Chem's voorbeeld van de forumlist-dropdown's is een perfect voorbeeld: rarely to never updated, required every page. Wat denk je dat de snelste code is (ik pak even C#/ASP.NET):
C#:
1
2
3
4
5
6
7
8
if((int)Cache["ForumListSequenceNr"] != (int)Session["ForumListSequenceNr"])
  {
  // Synchronize sequence first to avoid having to lock
  Session["ForumListSequenceNr") = Cache["ForumListSequenceNr"];
  Session["ForumList") = AssembleUserSpecificForumList();
  }
foreach(DictionaryEntry entry in (StringDictionary)Session["ForumList"])
  Response.Write("<option id=\"" + entry.Key + "\">" + entry.Value + "</option>";

Denk je echt dat deze code langzamer wordt als je iedere keer de AssembleUserSpecificForumList functie aanroept die een select met bijbehorende locking en query compilation of execution plan lookup moet doen over een IPC pijpje naar de database?

[ Voor 18% gewijzigd door curry684 op 25-06-2004 10:30 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
chem schreef op 25 juni 2004 @ 10:08:
SHM zou ik je sterk afraden, aangezien het nogal wat ellende kan opleveren (PHP was er nooit zo heel sterk in iig). Je kan wel een serialized value in een HEAP table van MySQL (of een andere db-server) zetten. (un)serializen is echt heel snel in PHP, en een HEAP table is ook erg snel :+
Zit je trouwens wel weer in/met de database...
Maar tot hoeveel kb/mb is (un)serializen echt heel snel?
Als de cache groot is en er per keer maar een klein deel van geselect of geupdate wordt, dan wordt de seralize overhead ineens toch te groot.

Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Ik gebruik zelf XSLT's in PHP5-dingen die ik aan het maken ben. Stel nou dat ik bijvoorbeeld de ingeladen DOMDocument van de XSLT in een globale var zou kunnen gooien, dan zou ik niet voor ieder request die XSLT weer moeten parsen :)

Acties:
  • 0 Henk 'm!

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 16-09 10:29

Apache

amateur software devver

K'ben al aan het experimenteren geweest met SQLite om aan caching te doen, minder overhead dan een heap table in mysql.

Kan je ook niet alleen caching in doen maar ook applicatievar achtige zaken.

En er is zelfs een OO interface voor voorzien vanaf php5+.

De database zelf moet je niet enorm veel van verwachten, is zelf ook loose typed maar sluit daarom wel goed aan bij php.

If it ain't broken it doesn't have enough features

Pagina: 1