[PHP] persistent storage van multi-dim array tussen requests

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
Wat zou volgens jullie de beste manier zijn om een grote multi-dimensionale array (zeg 1MB) op te slaan tussen requestst? Persistent storage dus.

Ik kan verschillende mogelijkheden voorstellen, waarvan sommige volgens mij niet wenselijk zijn.

1. opslaan van de array in session variables. Volgens mij niet wenselijk omdat dit oneigenlijk gebruik is van de session variables.

2. het opslaan van de data in een MySQL Memory table. Aardig, heeft een aantal voordelen (bijv. data kan worden gequeried zodat niet telkens alle data opgehaald hoeft te worden), maar ook nadelen (je komt uit bij meerdere relationele tabellen) en dus weer "platte" data.

3. opslaan van een serialized variant van de array op disk, welke bij een volgende request wordt ingelezen en deserialized. Dit is voor zover ik kan zien de beste variant, maar hij doet me in ieder geval op papier nog wat log aan (denk aan snelle requests uit AJAX calls, telkens die 1MB openen).

Zijn er nog meer ideeen/mogelijkheden? Roept u maar!

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Misschien een stomme vraag, maar waarom heb je 1MB aan persistent tussen requests voor nodig :?

Acties:
  • 0 Henk 'm!

  • 0fbe
  • Registratie: Januari 2004
  • Laatst online: 20-09 07:25
Wat betreft twee: Hoezo kom je uit bij meerdere relationele tabellen? Je kan toch ook gewoon een key-value-store maken in MySQL? Of zelfs een tabel met één text kolom?

Anders is misschien memcached nog een leuke key-value-store om naar te kijken.

Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
Nog even wat verduidelijking. Het gaat om matrices. Denk aan waarnemingen van persoon A over persoon B, C en D, van persoon B over A, C en D, enz. en dat in bijvoorbeeld meerdere groepen. En dat dan ook nog eens met waarnemingen over verschillende aspecten van een persoon (dus meerdere data velden voor A over B).

Dat leidt dus al snel tot een heel grote meer-dimensionele array. Ik wil daarmee kunnen rekenen, onderdelen uit tonen, etc.

Vandaar de grootte.

Kan dus inderdaad ook wel in 1 tabel misschien. Iets als

[groepID][persoonID][overPersoonID][Data1][Data2][etc]

Acties:
  • 0 Henk 'm!

  • ameesters
  • Registratie: Juni 2008
  • Laatst online: 05-01-2022
ligt eraan wat er nodig is, je zou voor een temp table kunnen gaan in mysql, deze blijft in het snellere werkgeheugen waardoor je enorm veel snelheid over houd, dit is alleen niet de makkelijkste methode,

voor gemak kan je inderdaad de sessies gebruiken, moet je alleen even controleren of de array niet tegroot is voor een cookie, anders kan dat weer problemen geven.

Bij veel ajax calls zou ik het niet op de disk op slaan in ieder geval, voor de rest hangt het van de situatie af.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
leipepo schreef op dinsdag 02 november 2010 @ 20:58:
voor gemak kan je inderdaad de sessies gebruiken, moet je alleen even controleren of de array niet tegroot is voor een cookie, anders kan dat weer problemen geven.
Euh? Wat heeft de array-grootte in een sessie te maken met een cookie :?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
Cookie of niet (volgens mij niet :) ), volgens mij is het gebruik van sessie variablen eigenlijk hetzelfde als serialized arrays op disk opslaan, maar dan met overhead. Dus die optie valt wat mij betreft sowieso af.

Ik ga toch eens kijken naar die memory tables in mysql. Het kunnen query'en van bijvoorbeeld 1 of 2 groepen levert volgens mij aardige performance winst t.o.v. het moeten inladen van de volledige serialized array.

Wat is het trouwens een treurnis als het gaat om matrix rekenen en functies in PHP zeg...

Acties:
  • 0 Henk 'm!

  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-08 20:35
leipepo schreef op dinsdag 02 november 2010 @ 20:58:
ligt eraan wat er nodig is, je zou voor een temp table kunnen gaan in mysql, deze blijft in het snellere werkgeheugen waardoor je enorm veel snelheid over houd, dit is alleen niet de makkelijkste methode,
De temp tabel bestaat ook alleen zolang de verbinding duurt. De kans is erg groot dat je in de volgende request een andere verbinding opzet danwel gebruikt naar de mysql server waardoor je geen toegang hebt tot dezelfde temp table.
voor gemak kan je inderdaad de sessies gebruiken, moet je alleen even controleren of de array niet tegroot is voor een cookie, anders kan dat weer problemen geven.
De hoeveelheid informatie die je in een sessie op kan slaan is echt niet gelimiteerd door de hoeveelheid data die je in een cookie op kan slaan. Zie voor enige uitleg: How sessions work in PHP.


Het lijkt mij een goed idee om ze gewoon in de sessie op te slaan of iets als memcached of APC te gebruiken voor de opslag van de data zoals ook al eerder is aangegeven. Het opslaan van de data in een MySql memory table is volgens mij ook een prima optie. PHP zal er weinig moeite mee hebben (kwa processing) om dit naar de gewenste structuur om te zetten zeker als het "maar" om 1 MB aan gegevens gaat.

Je zou het een en ander zelf uit kunnen proberen en kunnen benchmarken om te kijken wat de beste oplossing is in jouw situatie.

If I can't fix it, it ain't broken.


Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 16:37
Hoe vluchtig zijn die gegevens? Als iemand de MySQL database herstart ben je de gegevens kwijt. Is het niet beter om voor gewone tabellen te kiezen?

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
leipepo schreef op dinsdag 02 november 2010 @ 20:58:
Bij veel ajax calls zou ik het niet op de disk op slaan in ieder geval, voor de rest hangt het van de situatie af.
Ik heb een tijdje terug eens lopen benchmarken wat op mijn development server sneller is: een image file van ~ 50Kb inladen vanaf filesystem, memcache of MySQL. Filesystem won dat verbazingwekkend genoeg. Veel andere storage providers moeten eerst een connectie met de service opzetten of initializeren, tegen de tijd dat PHP "hoi" gezegd heeft tegen een memcachedaemon is je filesystem al halverwege met laden bij wijze van spreken. Daar komt bij dat zowel je OS, HD zelf als controller aan caching doen wat het geheel nog aardig versnelt.

Ik gok dat memcache / serialized filestorage je hier de beste performance gaat geven, of als je wat meer moeite wilt doen APC wellicht - ik heb helaas zelf geen ervaring met die laatste :)

Overigens is 1Mb aan data wel erg veel. Dan heb je het al snel over duizenden waardes. Als je die niet allemaal nodig hebt is het een stuk handiger eens goed na te denken over hoe je de data opslaat. Als je bijvoorbeeld veel tekst hebt (waardoor je data groot wordt) zou je ook alleen de ID's kunnen bewaren van elke koppeling: iets als "[persoon A][persoon B] = 24" en vervolgens uit je database de content van record 24 opvragen, of uit een serie records als je er meerdere per pagina nodig hebt.

Hou er ook rekening mee dat je eigenlijk hoe dan ook je data ergens netjes zal moeten opslaan, en dat een goed uitgewerkte database met correcte indici etc qua performance vaak nauwelijks onderdoet voor persistente data arrays - dat is doorgaans een laatste redmiddel als je DB echt heel zwaar belast wordt en traag is.
Borizz schreef op dinsdag 02 november 2010 @ 21:10:
De temp tabel bestaat ook alleen zolang de verbinding duurt. De kans is erg groot dat je in de volgende request een andere verbinding opzet danwel gebruikt naar de mysql server waardoor je geen toegang hebt tot dezelfde temp table.
Dat kun je afaik afvangen met persistente databaseconnecties. Mooi is anders though.
Je zou het een en ander zelf uit kunnen proberen en kunnen benchmarken om te kijken wat de beste oplossing is in jouw situatie.
Eensch. Zijn nogal wat factoren die direct van invloed zijn op hoe goed een bepaalde storage methode performed, ze schalen allemaal anders onder belasting en sommige zijn betrouwbaarder of meer werk om te implementeren dan anderen. Meten is weten :)

[ Voor 18% gewijzigd door FragFrog op 02-11-2010 21:32 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
hmm...database tabellen mogen dan wel snel zijn. "Probleem" is dat de opgevraagde data als nog naar een matrix omgezet moet worden. Dus:

Persoon,OverPersoon,Value
1,2,4
1,3,5
1,4,5
2,1,3
2,3,5
2,4,6
enz

moet naar

array(
[0] => array(null, 4, 4, 5)
[1] => array(3, null, 5, 6)
[enz]

om er de dingen mee te kunnen doen die ik wil.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

nika schreef op dinsdag 02 november 2010 @ 21:09:
Cookie of niet (volgens mij niet :) ), volgens mij is het gebruik van sessie variablen eigenlijk hetzelfde als serialized arrays op disk opslaan, maar dan met overhead. Dus die optie valt wat mij betreft sowieso af.
Welke overhead? Het beheren van de sessie? Die operaties die je nu met het handje na gaat bouwen omdat je toch op 1 of andere manier moet bepalen welke 1MB bij welke gebruiker hoort? Dat je vervolgens ook nog zelf een cronjob of wat dan ook in elkaar moet draaien om die geserialiseerde data ook weer eens weg te flikkeren wanneer een gebruiker al lang vertrokken is?


Daarnaast heb ik nog wel een paar andere vragen:
-Is de data per gebruiker (die 1MB) of gebruikt iedereen dezelfde data.
-Waarom moet het uberhaupt allemaal in het geheugen staan?
-Kun je de bewerkingen niet gewoon met de database zelf doen ipv in het geheugen?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
Wait up!

De data komt niet uit een database. En er is maar 1 gebruiker eigenlijk. Waar het om gaat is dat de gebruiker een CSV bestand upload waarin zogenaamde dyadische data staat (persoon A zegt iets over persoon B en dat doet iedereen over elkaar in een groep, dus een volledige matrix van N x N, waarbij N het aantal personen in de groep is).

Vervolgens wil ik die data onder andere per groep kunnen doorlopen en bepaalde bewerkingen op kunnen uitvoeren. Dus binnen groepen maar ook over groepen.

Het kan dus gaan om grote bestanden. Data hoeft niet langer te bestaan dan de duur van de sessie.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
nika schreef op dinsdag 02 november 2010 @ 21:35:
hmm...database tabellen mogen dan wel snel zijn. "Probleem" is dat de opgevraagde data als nog naar een matrix omgezet moet worden. Dus:
...
om er de dingen mee te kunnen doen die ik wil.
Dan zou ik eerst eens gaan kijken naar je methodes/opslagmethodiek om te doen wat je wilt.

Momenteel sla je iets op op een manier blijkbaar niet handig voor jou is, en daardoor krijg je een shitload aan persistent data die je opeens ergens kwijt moet.

Als je dus 1000 "bijna" concurrent users krijgt, dan heb je ergens 1 Gb aan persistent zooi staan en dit is compleet naast je dbase...

Scratch that :)

Maar waarom stouw je het dan niet in 1 php-request? Of gewoon in meerdere achter elkaar gechained met een logische manier van tussendoor data opslaan.
Met deze opzet zou ik gewoon kiezen voor serialized opslaan en de kosten gewoon op de koop toe nemen.

[ Voor 16% gewijzigd door Gomez12 op 02-11-2010 21:50 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

nika schreef op dinsdag 02 november 2010 @ 21:45:
De data komt niet uit een database. En er is maar 1 gebruiker eigenlijk. Waar het om gaat is dat de gebruiker een CSV bestand upload waarin zogenaamde dyadische data staat (persoon A zegt iets over persoon B en dat doet iedereen over elkaar in een groep, dus een volledige matrix van N x N, waarbij N het aantal personen in de groep is).

Vervolgens wil ik die data onder andere per groep kunnen doorlopen en bepaalde bewerkingen op kunnen uitvoeren. Dus binnen groepen maar ook over groepen.

Het kan dus gaan om grote bestanden. Data hoeft niet langer te bestaan dan de duur van de sessie.
Blijft mijn eerste vraag staan. Op basis van welke overhead wijs je sessions af?

Daarnaast heb ik nog wel een nieuwe vraag. Waarom overweeg je niet om hier gewoon een clientside applicatie van te maken? Ik krijg een beetje het idee dat het eigenlijk een tooltje voor 1 iemand wordt voor het analiseren van dyadische data. Het hele request based gebeuren zit je dan toch wel behoorlijk in de weg.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
Blijft mijn eerste vraag staan. Op basis van welke overhead wijs je sessions af?
Opslaan in een session variable leidt tot ook alleen maar tot serialized opslaan op disk (even uitgaand van standaard session storage). Dus dan lijkt me een heel eenvoudige file_put_contents en file_get_contents minder overhead geven.

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
nika schreef op woensdag 03 november 2010 @ 08:36:
[...]


Opslaan in een session variable leidt tot ook alleen maar tot serialized opslaan op disk (even uitgaand van standaard session storage). Dus dan lijkt me een heel eenvoudige file_put_contents en file_get_contents minder overhead geven.
Het lijkt mij gewoon precies dezelfde overhead te geven.

Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
nika schreef op woensdag 03 november 2010 @ 08:36:
[...]


Opslaan in een session variable leidt tot ook alleen maar tot serialized opslaan op disk (even uitgaand van standaard session storage). Dus dan lijkt me een heel eenvoudige file_put_contents en file_get_contents minder overhead geven.
De session handler doet precies hetzelfde als wat jij omschrijft, waarom zou jou methode minder overhead geven? Je zal die array sowieso moeten serializen, anders krijg je allemaal bestandjes met de tekst "Array"

Acties:
  • 0 Henk 'm!

  • CrisT
  • Registratie: Maart 2003
  • Laatst online: 20-09 14:12
Waar hebben we het over? Er is blijkbaar 1 gebruiker, die een object alleen maar tijdens 1 sessie nodig heeft. Volgens mij zijn daar session-variables juist voor bedacht :). Af en toe niet te hard nadenken over optimalisaties :P.

Nederlandse Civilization community DutchCiv.nl


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
CrisT schreef op woensdag 03 november 2010 @ 09:12:
Waar hebben we het over? Er is blijkbaar 1 gebruiker, die een object alleen maar tijdens 1 sessie nodig heeft. Volgens mij zijn daar session-variables juist voor bedacht :). Af en toe niet te hard nadenken over optimalisaties :P.
Je hebt gelijk hoor. Ik kan mij af en toe verliezen in dit soort "optimalisatie" processen.

M.b.t. de overhead. Misschien is overhead niet het goede woord. Laat ik het anders zeggen, ik zie geen meerwaarde om het via sessie vars te doen i.p.v. "zelf" via file_put_content() en serialization. Bovendien bestaat bij het gebruik van sessie vars het "risico" dat de sessie vars niet op disk maar in de DB opgeslagen worden. Dat zal bij grote hoeveelheden dat de performance zeker niet ten goede komen.
Daarnaast heb ik nog wel een nieuwe vraag. Waarom overweeg je niet om hier gewoon een clientside applicatie van te maken? Ik krijg een beetje het idee dat het eigenlijk een tooltje voor 1 iemand wordt voor het analiseren van dyadische data. Het hele request based gebeuren zit je dan toch wel behoorlijk in de weg.
Twee redenen. Er kunnen meerdere gebruikers op meerdere lokaties zijn, niet gelijktijdig waarschijnlijk (zie het als een tool). Daarnaast kan ik via het web gebruikmaken van de gemakken van presenteren via html.

[ Voor 24% gewijzigd door nika op 03-11-2010 10:19 ]


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
nika schreef op woensdag 03 november 2010 @ 10:16:
[...]

Je hebt gelijk hoor. Ik kan mij af en toe verliezen in dit soort "optimalisatie" processen.

M.b.t. de overhead. Misschien is overhead niet het goede woord. Laat ik het anders zeggen, ik zie geen meerwaarde om het via sessie vars te doen i.p.v. "zelf" via file_put_content() en serialization. Bovendien bestaat bij het gebruik van sessie vars het "risico" dat de sessie vars niet op disk maar in de DB opgeslagen worden. Dat zal bij grote hoeveelheden dat de performance zeker niet ten goede komen.
De meerwaarde is dat de functionaliteit al bestaat en je het zo kunt gebruiken, zonder na te denken over implementatie-details. Verder zijn PHP sessies altijd file-based, tenzij je een eigen database-handler maakt en activeert middels session_set_save_hander().

Acties:
  • 0 Henk 'm!

  • iH8
  • Registratie: December 2001
  • Laatst online: 17-06-2024

iH8

nika schreef op woensdag 03 november 2010 @ 10:16:

M.b.t. de overhead. Misschien is overhead niet het goede woord. Laat ik het anders zeggen, ik zie geen meerwaarde om het via sessie vars te doen i.p.v. "zelf" via file_put_content() en serialization. Bovendien bestaat bij het gebruik van sessie vars het "risico" dat de sessie vars niet op disk maar in de DB opgeslagen worden. Dat zal bij grote hoeveelheden dat de performance zeker niet ten goede komen.
Je hebt toch uberhaubt al met sessies te maken om je clients te onderscheiden? Dan kun je toch net zo goed meteen je data daarin storen in plaats van nog eens extra een file, database, whatever, aan te spreken. Dat zou ik pass overhead noemen.

Aunt bunny is coming to get me!


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
Ik ben overtuigd. Ik ga het proberen via session vars. :)

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
nika schreef op woensdag 03 november 2010 @ 10:16:
[...]

Je hebt gelijk hoor. Ik kan mij af en toe verliezen in dit soort "optimalisatie" processen.
Begin niet met optimaliseren als je het niet nodig hebt :)

Klinkt heel bot, maar stop het gewoon in een sessie. Blijkt de applicatie langzaam te zijn, dan ga je benchmarken. Blijkt dat de sessie de bottleneck is, kan je eenvoudig overstappen op acp, of andere RAM based cache. Je kan pielen met zaken waarvan je denkt dat ze belangrijk zijn, maar zonder zeker te weten kom je niet verder. Meten = weten en daarvoor moet je eerst gaan bouwen (prototype of niet).

Ik gok namelijk zo dat de berekeningen die je wil loslaten op 1MB data veel meer impact hebben dan de methode van opslaan ;)

Acties:
  • 0 Henk 'm!

  • juggle
  • Registratie: December 2003
  • Laatst online: 10:38

juggle

Papa, ondernemer, gamer

Afgezien van het feit dat 1MB aan data wel erg veel is kun je hiervoor ook prima het registry pattern toepassen.
Het registry pattern is ook in andere talen een veel toegepast pattern.

Voor een uitleg van de werking en het implementeren van een registry verwijs ik naar phppatterns:
http://www.phppatterns.com/docs/design/the_registry

edit:

Toch iets te snel gereageerd, lees nu dat je het binnen requests wilt houden, het registry pattern is voornamelijk bedoeld om data te kunnen delen binnen objecten. Ik zou inderdaad hiervoor ook voor sessies gaan of het registry pattern toepassen en deze serializen naar de file storage.

[ Voor 31% gewijzigd door juggle op 03-11-2010 12:22 ]

Zoek je mede papa's om gezellig mee te gamen? kijk op: fathersoftweakers.nl


Acties:
  • 0 Henk 'm!

  • nika
  • Registratie: Oktober 2003
  • Niet online
Registry is toch alleen maar een (goed) alternatief voor een global variable? En dus alleen binnen 1 request persistent. Het gaat/ging mij om tussen request persistence.
Pagina: 1