Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Responsieve webapplicatie met onvoorspelbare requests

Pagina: 1
Acties:

  • -DarkShadow-
  • Registratie: December 2001
  • Niet online
Eén van de factoren die een grote invloed heeft op de user experience van webapplicaties is de snelheid waarmee pagina's tevoorschijn komen.

Stel dat je een accountancy applicatie aan het ontwikkelen bent met daarin zaken als bestellingen, facturen en klanten. De hoeveelheid data in de applicatie is groot (1 milj. bestellingen bijv.). Het is de bedoeling dat pagina's met gegevens over klanten vliegensvlug worden geserveerd aan de gebruiker.

Ik vraag me af hoe je bij een onvoorspelbare aanvraag van de gebruiker, de benodigde data zo snel als mogelijk uit de cache/ database krijgt. Er belt bijvoorbeeld een klant die vraagt of dat hij nog garantie heeft op zijn videokaart. De telefoonniste (gebruiker) zoekt op de naam van de klant en vindt de juiste klant. Nu moeten alle bestellingen van de klant z.s.m. beschikbaar komen voor de telefoonniste. De telefoonniste ziet de bestelling en wil weten wanneer deze is verzonden, dus heeft ze de zendingsgegevens snel nodig.

Hoe los je dit op?

Veel grote webapplicaties als Facebook lossen het op d.m.v. vele TB's memcache in te zetten, maar bij een applicatie met veel onvoorspelbare requests levert dat veel cache misses op.

Je zou kunnen inleveren op normalisatie, maar dat maakt het ontwikkelen van de applicatie moeilijker en de database minder flexibel.

Zou pre-cachen een optie zijn? Op het moment dat de gebruiker de klantgegevens opvraagt zou een achtergrondproces alle gegevens (bestellingen, zendingen, retouren) van de klant alvast in memcache kunnen laden. Nadelen hiervan zijn: erg veel extra server belasting, erg moeilijk te implementeren in bijvoorbeeld PHP, voelt aan als een hack.

Om de gebruiker een idee van snelheid te geven wordt er natuurlijk al veel gebruik gemaakt van Ajax.

Specialist in:
Soldeerstations
Oscilloscoop


Verwijderd

Stop. Eerst maken.

Een miljoen bestellingen is met een goed genormaliseerde database met de juiste indexes geen enkel probleem.

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
En daarna. Meten is weten. Simpel. De enige reden dat het onvoorspelbaar is, is omdat je nog veel te vroeg in de ontwikkel cyclus zit.

[ Voor 23% gewijzigd door PrisonerOfPain op 04-04-2011 22:47 ]


  • ameesters
  • Registratie: Juni 2008
  • Laatst online: 05-01-2022
Verwijderd schreef op maandag 04 april 2011 @ 22:15:
Stop. Eerst maken.

Een miljoen bestellingen is met een goed genormaliseerde database met de juiste indexes geen enkel probleem.
Dat over een miljoen bestellingen ben ik met je eens over een database, maar om hem het eerst laten maken is nooit de weg, met zorgvuldig plannen kan hij in zijn applicatie een eventuele bottleneck al voorspellen, en encapsuleren zodat het in de toekomst makkelijk aangepast kan worden.

De tips die ik je kan geven is:

1) Kijk naar de basis functionaliteiten en key selling points van de applicatie, ontwikkel die als eerst. Probeer eerst de basis goed neer te zetten, als dat online is, evalueren, als je encapsulatie goed is, kan je dingen altijd nog via een cache laten lopen en optimaliseren.

2) zorg dat de functionaliteiten meetbaar zijn zodat er geevalueerd kan worden of deze ook echt gebruikt wordt, het is zonde om een hoop tijd en energie in iets te steken wat toch niet gebruikt wordt!

3) Don't over engineer - zoals ik in punt 1 al zei, zorg dat je basis goed staat, en ga daar vanuit verder ontwikkelen, het is voor de eindgebruiker ook leuk om nieuwe features te zien, en geeft ook altijd een boost bij de aanmeldingen...

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13:05

Janoz

Moderator Devschuur®

!litemod

Grote webapplicaties zoals Facebook hebben niet een dikke cache nodig vanwege de vele data die ze hebben, maar vanwege de enorme hoeveelheden bezoekers. Ik neem niet aan dat je je software aan het ontwikkelen bent voor een callcenter met een paar miljoen simultane agents.

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


  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 21:19

The Eagle

I wear my sunglasses at night

Zorgen dat je aan deferred processing doet :)
Lang niet alle gegevens zullen direct opgevraagd moeten worden als men een zoekveld invult. Voor iedere directe process is een roundtrip naar de server nodig. Als je aan deferred processing doet, bijvoorbeeld voor je invoerschermen van stamgegevens, is 1 roundtrip naar de server al voldoende om alle gegevens te valideren. Gebeurt bij het saven ;)
En voor de gegevens die je wel direct opvraagbaar wilt hebben, zorgen dat je simpele, snelle views gebruikt :)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Wat je omschrijft in de use case kan prima zonder caching. Al doe zoekacties kunnen op basis van indexen.

De klant zal bijvoorbeeld zijn naam geven. Als je voor en achternaam gescheiden in de account database opslaat kun je zoiets doen:
code:
1
SELECT id, [etc...] FROM customer WHERE surname = 'Beer';

Vervolgens kun je al zijn bestellingen opvragen:
code:
1
SELECT id FROM order WHERE customer_id = 1;


Het wordt pas lastig wanneer "klinkt als" of "bevat" doet, maar een telefooniste kan gewoon vragen om de naam te spellen. Zeker als de response tijd van de backoffice snel is. Bij lastige namen zou je ook het eerste deel van de achternaam kunnen accepteren:
code:
1
SELECT id, [etc...] FROM customer WHERE surname LIKE 'Beer%';

Maar ga vooral niet in het "midden" zoeken een index in mysql kan dit niet snel afhandelen bij grote hoeveelheden:
code:
1
SELECT id, [etc...] FROM customer WHERE surname LIKE '%beer%';


Als je wilt dat de telefooniste echt zonder spellen kan, dan zul je met soundexes of iets dergelijks moeten werken en die bij de klant opslaan en indexen.
code:
1
SELECT id, [etc...] FROM customer WHERE soundex = 'B6';

Let op: De soundex verschilt per taal. De php soundex is gemaakt voor het engels.

Je kunt ook een complexer algoritme als soundex gebruiken. Hier heeft creator1988 een mooi tweakblog over geschreven.

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Zorg ervoor dat je in de tussenstappen enkel key-requests doet.
Dus een klantenlijst kan best voor- en achternamen bevatten als hiervoor een key bestaat. Produceer dus geen hele lijsten met naw-gegevens, maar bijv enkel klant-nr en naam (simpel voorbeeld) en dan een venstertje ernaast met de naw-gegevens van 1 klant.

Additionele gegevens van 1 klant zijn zo gevonden als je ze benaderd via een key.

Lijsten samenstellen met gegevens die niet uit keys komen is zwaar.
En probeer ook goed in te schatten wat de maximaal gebruikte resultaten zullen worden en wanneer je moet gaan zoeken.
Een autocomplete wat gelijk reageert als je 1 letter intoetst is leuk, maar als het 3000 resultaten teruggeeft is het zinloos, dan kan je het beter beperken op bijv pas reageren na 3 letters plus 0.1 sec inactiviteit, zelfde met het aantal resultaten, als je ziet dat iedereen enkel vanaf het 1e scherm werkt (en als het daar niet opstaat gewoon de zoekopdracht uitbreidt) limiteer dan de initiele resultaten tot het 1e en 2e scherm, de rest wordt toch nooit geraadpleegd en zorgt enkel maar voor cache misses.

Waar je bijv de fout mee ingaat is het volgende stukje :
De telefoonniste (gebruiker) zoekt op de naam van de klant en vindt de juiste klant. Nu moeten alle bestellingen van de klant z.s.m. beschikbaar komen voor de telefoonniste. De telefoonniste ziet de bestelling en wil weten wanneer deze is verzonden, dus heeft ze de zendingsgegevens snel nodig.
De telefoniste hoeft niet te beschikken over alle bestellingen van de klant. Zeer waarschijnlijk hoeft ze enkel maar snel te beschikken over de bestellingskoppen van de laatste 2 maanden, de rest moet via een knopje meer oid wel beschikbaar zijn, maar minder snel.
Zendingsgegevens moet bijv al geen probleem meer zijn, dat is gewoon op een key 1 record ophalen.

Overweeg ook rustig om een veld omgekeerd op te slaan voor je zoekindexen. Een like '%beer' vind menig dbase niet leuk. Maar als je dit omschrijft naar like 'reeb%' dan vind je dbase dit geen probleem zolang je de naam maar omgekeerd hebt opgeslagen...

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 11:39
Gomez12 schreef op maandag 04 april 2011 @ 23:28:
Overweeg ook rustig om een veld omgekeerd op te slaan voor je zoekindexen. Een like '%beer' vind menig dbase niet leuk. Maar als je dit omschrijft naar like 'reeb%' dan vind je dbase dit geen probleem zolang je de naam maar omgekeerd hebt opgeslagen...
Of je zet er een fulltext index op. Zijn die dingen voor tenslotte B)

Volgens mij kun je met een beetje bayesian probability model best aardig voorspellen welke data opgehaald moet worden. Heb er wel eens een case study van gezien (pre-fetchen van bepaalde pagina's op een grote website), leek best te werken. Zodra een pagina geladen wordt ga je kijken welke pagina's daarna wellicht ook geladen moeten worden, de meest waarschijnlijke pagina's pre-fetch je dan alvast zodat ze direct beschikbaar zijn als de gebruiker op een link klikt. Schijnt dat mensen gewoontedieren zijn en dat je erg goed kan voorspellen waar ze gaan klikken. Mik de complete HTML output in een fast-expiring cache (1 minuut ofzo is ruim voldoende) en je kan zo met relatief weinig geheugen een behoorlijke lading gebruikers aan.

Mind you, dat soort relatief exotische cachingsmechanismen heb je pas nodig als je site echt traag is en je data dit aankan. Met een normaal gebruikersaantal zou me dat zeer verbazen, ga daarvoor eerst maar eens bottlenecks vinden en proberen die op te lossen. In mijn ervaring is caching zeer zelden echt nodig maar wordt het te pas en te onpas maar gebruikt "want dan is het sneller". Ik sluit me dan ook volledig aan bij Cheatah: eerst maken, dan kijken of en hoe je moet cachen :)

[ Voor 3% gewijzigd door FragFrog op 04-04-2011 23:57 ]

[ Site ] [ twitch ] [ jijbuis ]


  • -DarkShadow-
  • Registratie: December 2001
  • Niet online
Ok. Wat ik al vermoedde is bevestigd. Een degelijke database opzetten met de juiste indices. Zoeken is nog een verhaal apart. Er moet nog een keuze gemaakt worden tussen één zoekveld voor zowel klantnamen, adressen, bedrijfsnamen, telefoonnummers, factuurnummers, bestelnummers, etc.. of meerdere velden. Maar dat is een verhaal voor een ander topic.

Specialist in:
Soldeerstations
Oscilloscoop


  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 26-11 23:14

GrimaceODespair

eens een tettenman, altijd ...

Als je met Java of .NET werkt en voor een full-text index gaat, kan je eventueel ook zelf een index bijhouden met Lucene of Lucene.NET. Da's redelijk eenvoudig en bij juist gebruik zo snel dat zelf cachen vaak trager is.

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 19:16
-DarkShadow- schreef op dinsdag 05 april 2011 @ 00:02:
Ok. Wat ik al vermoedde is bevestigd. Een degelijke database opzetten met de juiste indices. Zoeken is nog een verhaal apart. Er moet nog een keuze gemaakt worden tussen één zoekveld voor zowel klantnamen, adressen, bedrijfsnamen, telefoonnummers, factuurnummers, bestelnummers, etc.. of meerdere velden. Maar dat is een verhaal voor een ander topic.
Wellicht, als je de performance echt zo serieus neemt, is het een idee om een concept te maken. Daarmee bedoel ik simpelweg: Maak de tabel aan met data, schrijf een script wat onzin data plaatst. Vervolgens maar je een plat script wat die zoekactie uitvoert. Als dat voldoende performance heeft dan is het technisch mogelijk. Anders weet je al meteen dat je een probleem tegen gaat komen.

Op die manier blijft je project stabiel, een mogelijk risicopunt heb je uitgesloten, en daarnaast zou je tevens wat simpele user testing kunnen doen. Wat werkt het beste, 1 zoekveld of een veld per veld in de database. Je kan dan ook bijvoorbeeld gaan voorzien dat mensen die zoeken op telefoonnummer soms met en soms zonder streepje doen etc.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Ik denk dat je wat betreft hoe een webapplicatie 'voelt' al een hoop winst kunt halen door AJAX te gebruiken. Gebruikers vinden bijvoorbeeld autocompletion erg fijn, zoals google zoekwoorden suggereert.
djluc schreef op dinsdag 05 april 2011 @ 08:54:
[...]
Wellicht, als je de performance echt zo serieus neemt, is het een idee om een concept te maken. Daarmee bedoel ik simpelweg: Maak de tabel aan met data, schrijf een script wat onzin data plaatst.
Pas op met onzin data.. Je kunt voor een proof of concept beter 'echte' data gebruiken. Twee voornaamste redenen: ten eerste is het salestechnisch leuk om al vast een demo te kunnen geven. Daarnaast, vooral belangirjk als je je zorgen maakt over de performance, zijn er situaties te bedenken waar een volledig willekeurige verdeling van data andere performancemetrics oplevert dan eentje die wel natuurgetrouw is. Kijk maar naar hoeveel meer tijd het jezelf kost een naam met een M in je telefoon te vinden dan een naam met een X.

https://niels.nu


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 19:16
Uiteraard moet de data logisch zijn en willekeurig zodat je geen mini indexes e.d. krijgt. Of je echte data kan en mag gebruiken hangt vooral van de situatie af.

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 21:19

The Eagle

I wear my sunglasses at night

Vwb dat telefoonnummer met een streepje: ik mag aannemen dat als je een systeem bouwt, je het fieldformat wel afvangt bij de invoer. Desnoods met een check constraint op DB niveau, maar dat soort dingen wil je dus echt afvangen. Sidenote: een telefoonnummer is standaard een string veld, geen number. Anders verlies je de eerste 0 van het kengetal ;)

T.a.v. een flink zoekscherm: eerst bouwen. In je app zelf afvangen dat er gecheckt wordt op al dan niet gevuld zijn van een veld. Vervolgens een dynamische where clause aanmaken. Kost je even wat werk - maar dan heb je uiteindleijk ook wat :)
Voorbeeldje van zo'n dynamische where-clause in pseudo code:
code:
1
2
3
4
5
6
7
8
9
10
$whclause = "where ";
If all ($naam) then 
  $whclause = $whclause | "and name=" | $naam;
end-if;
if all If all ($telnbr) then 
  $whclause = $whclause | "and phone=" | $telnbr;
end-if;
...
sqlexec(" "select * from klant" | $whclause ");
etc etc.

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
The Eagle schreef op dinsdag 05 april 2011 @ 19:42:
je het fieldformat wel afvangt bij de invoer. Desnoods met een check constraint op DB niveau, maar dat soort dingen wil je dus echt afvangen.
Echt foute invoer wil je afvangen, maar gebruik van streepjes en spaties moet je vooral lekker toestaan en zelf normaliseren. Aka verveel mij (als eindgebruiker) aub niet met hoe ik een telefoonnummer moet formatteren.

Maar goed, het genoemde aantal van 1M rows betekent dat ts gewoon aan de slag kan en niet per se maanden over een compleet serverpark en architectuur hoeft na te denken. Zorg maar eerst dat je je populariteit met Facebook mag vergelijken, want dat is een luxeprobleem.

Met 1M rows heb je alleen wel een kans dat mysql fulltext niet meer voldoet; bij die omvang kan het 'opeens' een trage, amper te tunen black-box zijn. Maar dan gooi je er Sphinx (of lucene etc.) tegenaan en kan je weer door tot heel Europa in je db zit. :+

{signature}


  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 26-11 21:19
The Eagle schreef op dinsdag 05 april 2011 @ 19:42:
Vwb dat telefoonnummer met een streepje: ik mag aannemen dat als je een systeem bouwt, je het fieldformat wel afvangt bij de invoer. Desnoods met een check constraint op DB niveau, maar dat soort dingen wil je dus echt afvangen. Sidenote: een telefoonnummer is standaard een string veld, geen number. Anders verlies je de eerste 0 van het kengetal ;)

T.a.v. een flink zoekscherm: eerst bouwen. In je app zelf afvangen dat er gecheckt wordt op al dan niet gevuld zijn van een veld. Vervolgens een dynamische where clause aanmaken. Kost je even wat werk - maar dan heb je uiteindleijk ook wat :)
Voorbeeldje van zo'n dynamische where-clause in pseudo code:
code:
1
2
3
4
5
6
7
8
9
10
$whclause = "where ";
If all ($naam) then 
  $whclause = $whclause | "and name=" | $naam;
end-if;
if all If all ($telnbr) then 
  $whclause = $whclause | "and phone=" | $telnbr;
end-if;
...
sqlexec(" "select * from klant" | $whclause ");
etc etc.
Of niet helemaal uitgeprogrammeerd, maar gewoon gegenereerd (.NET alert, dat dan weer wel :) ), Coding Glamour: Zoekscherm dat dynamisch queries maakt met Expression Trees en MVC

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 21:19

The Eagle

I wear my sunglasses at night

Voutloos schreef op dinsdag 05 april 2011 @ 20:50:
[...]
Echt foute invoer wil je afvangen, maar gebruik van streepjes en spaties moet je vooral lekker toestaan en zelf normaliseren. Aka verveel mij (als eindgebruiker) aub niet met hoe ik een telefoonnummer moet formatteren.

Maar goed, het genoemde aantal van 1M rows betekent dat ts gewoon aan de slag kan en niet per se maanden over een compleet serverpark en architectuur hoeft na te denken. Zorg maar eerst dat je je populariteit met Facebook mag vergelijken, want dat is een luxeprobleem.

Met 1M rows heb je alleen wel een kans dat mysql fulltext niet meer voldoet; bij die omvang kan het 'opeens' een trage, amper te tunen black-box zijn. Maar dan gooi je er Sphinx (of lucene etc.) tegenaan en kan je weer door tot heel Europa in je db zit. :+
Als jij alles accepteert wat er qua streepjes, slashes etc in een systeem wordt ingevoerd bij telefoonnummers wens ik je veel succes bij het zoeken, en nog veel meer bij een evt sortering op kengetal / telnummer voor een afdeling marketing ofzo ;)
Ik zeg overigens ook niet dat je de gebruiker met een foutmelding om zijn oren moet slaan - d'r zijn prima functies te vinden die er alle niet-cijfers uitfilteren en waar de gebruiker niks van merkt :)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Als je die prima functies gebruikt normaliseer je. ;)

{signature}


  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 21:19

The Eagle

I wear my sunglasses at night

Voutloos schreef op woensdag 06 april 2011 @ 10:09:
Als je die prima functies gebruikt normaliseer je. ;)
Leest en huivert: Wikipedia: Databasenormalisatie
Heeft dus niks met normaliseren te maken ;)
Tenzij je er een (kandidaat) sleutel van wilt maken, maar dat wil je niet. Telefoonnummers zijn namelijk van nature al uniek. Hooguit wil je er een (zoek) index op zetten. Persoonlijk zou ik klantid oid daarvoor als sluetel pakken, dan type telefoonnummer en dan pas het nummer zelf. Maar we dwalen wat af geloof ik ;)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


  • HMS
  • Registratie: Januari 2004
  • Laatst online: 17-11 00:33

HMS

The Eagle schreef op donderdag 07 april 2011 @ 01:11:
[...]

Leest en huivert: Wikipedia: Databasenormalisatie
Heeft dus niks met normaliseren te maken ;)
Tenzij je er een (kandidaat) sleutel van wilt maken, maar dat wil je niet. Telefoonnummers zijn namelijk van nature al uniek. Hooguit wil je er een (zoek) index op zetten. Persoonlijk zou ik klantid oid daarvoor als sluetel pakken, dan type telefoonnummer en dan pas het nummer zelf. Maar we dwalen wat af geloof ik ;)
offtopic:
In principe maakt het niet uit hoe de gebruiker het als formaat invoert. Gewoon strippen die string en opslaan zoals je zelf wilt.

  • NetForce1
  • Registratie: November 2001
  • Laatst online: 19:09

NetForce1

(inspiratie == 0) -> true

The Eagle schreef op donderdag 07 april 2011 @ 01:11:
[...]

Leest en huivert: Wikipedia: Databasenormalisatie
Heeft dus niks met normaliseren te maken ;)
Je verward normalisatie met databasenormalisatie, leest en huivert: Wikipedia: Normaliseren ;)

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 21:19

The Eagle

I wear my sunglasses at night

Mja, de eerste regel van die link zegt het dus al: spraakverwarring :)

Ontopic dan maar weer. Heeft de TS genoeg info nu? :)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


  • -DarkShadow-
  • Registratie: December 2001
  • Niet online
The Eagle schreef op donderdag 07 april 2011 @ 15:17:
Ontopic dan maar weer. Heeft de TS genoeg info nu? :)
Voorlopig wel :)

Specialist in:
Soldeerstations
Oscilloscoop

Pagina: 1