Avatar billede CodingJoe Nybegynder
10. maj 2013 - 09:18 Der er 31 kommentarer og
2 løsninger

Design / arkitektur review af løsning

Jeg er i færd med at lave nogle optimeringer i min applikation. Disse optimeringer drejer sig primært om at sikre en god brugeroplevelse af mit site. Nu ved jeg at hardware har en del at sige, men hvis vi lægger det fra os for en kort stund, så består mit system af følgende:

------------------------------------------------
* UI lag - Jeg regner med at bruge noget JQuery til AJAX
------------------------------------------------
* Forretningslogik lag - Jeg regner med at bruge Tasks - Threading -TPL
------------------------------------------------
* Dataaccess lag - Jeg bruger allerede noget System.Runtime.Caching til data sammen med EF5.
------------------------------------------------
* MySQL database
------------------------------------------------

Omkring caching er jeg meget i tvivl om hvilken caching strategi, jeg skal bruge. Iøjeblikket cacher jeg fx. alle medlemmer fra en medlemstabel. Der kan være mellem 1000-4000 potentielle rækker inkl. data fra andre tabeller hvor medlemsID fremgår som fremmednøgler. Jeg har omkring 7-9 subtabeller, hvor data naturligvis også bliver hentet og cached.
Har jeg efterfølgende metoder, der fx. skal hente et enkelt medlem, så slår jeg op i min cache og returnerer det enkelte medlem. Skal jeg fx. hente alle medlemmer med et specifikt postnr, slår jeg igen op i min cache og returnerer en liste af medlemmer.
Det meste af tiden vil jeg operere med cachede data. Jeg kører med en AbsoluteExpiration og har sat den til 10 min. Sker der en opdatering af data, så er data cached i op til 10 min.
Er det i det hele taget en farbar vej, at jeg cacher så store datamængder, eller skal jeg forsøge at cache enkelte typiske småkald?

Jeg er meget åben for konstruktive ideer og kritik.
Avatar billede arne_v Ekspert
10. maj 2013 - 17:21 #1
Hvor meget fylder de data du cacher i KB/MB/GB?
Avatar billede Syska Mester
10. maj 2013 - 17:35 #2
Hvis du cacher, så skal du kunne flush det som er caches som en del af din Update logik. Det bør deres være muligt at cache alt forever ... indtil det ændre state. At cache i 10 mins virker som noget der kan giver mange mærkelige og uhåndterbare scenarier.

Been there, done that og har fortudt det.

Tænk over hvordan din data ændre sig og cache de ting som altid hænger sammen som et object og cache det.
Avatar billede CodingJoe Nybegynder
10. maj 2013 - 17:48 #3
Data i sig selv fylder nok ikke meget, men der er albums -> billeder knyttet til hver medlem. Billederne er ikke i højopløsning, og jeg håber at kunne lave nogle programmatiske begrænsninger af upload af billeder på max 150KB. Der er ikke tale om GB, men samlet er vi nok et sted mellem 25-50MB...måske en lille smule mere...

Mht. til caching af data, der kan ændrer sig, så har jeg allerede en flush -> Clearcache funktionalitet, som jeg vil binde sammen med mine updates, deletes og adds.
Avatar billede arne_v Ekspert
10. maj 2013 - 17:57 #4
25-50 MB er jo ikke noget problem at cache naar man koeber RAM i 4 GB staenger.
Avatar billede arne_v Ekspert
10. maj 2013 - 18:00 #5
I et single node setup er der ikke mange ben i updates og en write through cache.

Men i et cluster setup kan cache og updates godt blive meget tricky medmindre ens cache er cluster wide - jeg ved ikke om System.Runtime.Cache er det - jeg tvivler.
Avatar billede janus_007 Nybegynder
10. maj 2013 - 21:39 #6
Inden jeg overhovedet tænker i cachingstrategier vil jeg da meget gerne kende til din nuværende performance og dit mål?

Derudover...
Snakker vi høj performance med et lille antal brugere eller mange brugere?

Du skal ikke bare sætte expiration til 10 min, det skal hænge sammen med det data du cacher. Oftest vil man opsætte en cache policy med changemonitors som overvåger det data du cacher.


Men men....
Det absolut nemmeste sted at optimere er at skære EF5 fra og så bruge en bedre ORM...
- det betyder dog mindre hvis du cacher i længere tid.
Avatar billede Syska Mester
10. maj 2013 - 22:14 #7
Performance skal altid være god, men lad for alt i verden med at optimere før et problem opstår ... :-)

Enig ... 10 mins virker som en "Jeg tror dette gør mit site hurtigere" ... det virker i hvert fald helt som den forkerte måde at gøre det på.

Man måler sig til hvor man har problemer og optimere der.

#janus_007
#(")=#(=!" ... what a load of ******
Med mindre du er Stackoverflow værdig i antal brugere, størrelse eller andet, bør din ORM bare virke ... at optimere der kan selvfølgelig betyde noget ... men ... for alt i verden, STOP. Det betyder så lidt at det er de færreste der har noget at vinde der.

SO bruger også memcache og andre ting fordi de netop har så SYGT mange brugere etc.

Brug den ORM du kan finde ud af ...

Hvis man kigger kort på: http://blog.staticvoid.co.nz/2012/3/24/entity_framework_comparative_performance

Så er der ikke specielt meget at vinde, i forhold til alt det man taber. Cache bruger man selvom man har den ene eller anden orm. Memory vs DB er stadig en faktor 100 oftest.
Avatar billede janus_007 Nybegynder
10. maj 2013 - 23:07 #8
#buzzzz, det betyder da i allerhøjeste grad noget om hvilken ORM man vælger.

På performancedelen:
Eager, deferred, lazy loading, parsing af Linq til SQL-udtryk og derudover bare selve ORM'en i sig selv og hvordan den er kodet.

En lille ORM vil altid outperforme et monster som EF og hvad hulen skal SO nu blandes ind i hvad jeg er og siger? Både du og jeg ved at førend man kan hive nogle point sammen på SO kræver det oceaner af tid og commitment til sitet... det er ikke ligefrem det jeg svømmer rundt i :) det er jo ikke ensbetydende med at ens erfaring lige pludselig ikke tæller længere.
Avatar billede Syska Mester
11. maj 2013 - 00:12 #9
Hvis du kan måle den den store forskel på hvad ORM du vælger ... så godt for dig, men jeg ville _ALDRIG_ starte der.

Der er i min verden bedre steder at bruge sin tid.

Jeg har bare svært ved at se det helt store gain i det jeg vil kalde micro optimeringer og sidste udvej.

Men ... enig, EF er jo også mere end bare en ORM. Modsat andre som Dapper etc. som faktisk ikke gør specielt meget ... og efterlader brugeren med mange begrænsninger ...
Avatar billede arne_v Ekspert
11. maj 2013 - 03:26 #10
Den tid der bruges i selve ORM har naeppe nogen betydning for overall performance. Stort framework eller lille framework, god kode eller daarlige kode - aldeles ligegyldigt.

Men der kan godt vaere forskel paa ORM. Hvis de udfoerer det samme SQL er der som ikke grund til at forvente nogen naevnevaerdig forskel. Men bemaerk det lille "hvis". Det er ikke altid tilfaeldet. Hvis den ene ORM udfoerer smartere SQL end den anden, saa kan det betyde en stor forskel i performance. Jeg kan varmt anbefale at proeve at udskrive den udfoerte SQL og checke om den er god naar man bruger ORM. Traditionelt er ORM rigtigt gode til tabeller der er konstrueret til formaalet mens deres effektivitet varierer noget mere med tabel strukturer som er designet til en anden brug ofte for mange aar siden.
Avatar billede arne_v Ekspert
11. maj 2013 - 03:30 #11
Og saa er der naturligvis forskel paa hvilke funktionaliteter som ORM tilbyder - diverse lazy load, key generation, cache muligheder etc..

Der boer man naturligvis vaelge noget der passer med ens behov.

Hvis fokus er cache vil jeg f.eks. kigge en del paa NHibernate.

At introducere second level cache med nogle faa linier i config er nemt.
Avatar billede arne_v Ekspert
11. maj 2013 - 04:13 #12
Med hensyn til cache eviction saa kan jeg ikke se nogen grund til ikke at lade data vaere i cache forever naar data er saa smaa.
Avatar billede CodingJoe Nybegynder
16. maj 2013 - 17:52 #13
Jeg lader lige denne være åben lidt endnu, da jeg kommer med flere indlæg id denne tråd.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 18:12 #14
Nu er jeg endelig gået i gang med at implementere mit design og jeg er løbet ind i følgende problem :(

Jeg forsøger at afvikle to ting parallelt, men det ser ud som om trådene dør midt i det hele. Begge metoder er void:

Min kode ser således ud:

public static void LogActivity(Action delegatedOperation, ActivityLog log)
{
    ActivityAgent.AddActivityLog(log);

    delegatedOperation.Invoke();
}

Nu vil jeg forsøge at køre dem parallelt og forsøger mig med følgende:

public static void LogActivity(Action delegatedOperation, ActivityLog log)
{
    Task.Factory.StartNew(() => ActivityAgent.AddActivityLog(log));

    Task.Factory.StartNew(delegatedOperation.Invoke);
}


Har også prøvet følgende
public async static void LogActivity(Action delegatedOperation, ActivityLog log)
{
    await Task.Run(() => ActivityAgent.AddActivityLog(log));
   
    await Task.Run(() => delegatedOperation.Invoke());
}

...men intet sker i mine metoder. Den ene skriver en entry i en database og den anden skriver ned i en fil.

Hvad gør jeg galt?
Avatar billede arne_v Ekspert
03. juni 2013 - 18:26 #15
Hvis de doer saa er der nok en exception som du skla have fanget og set hvad indeholder.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 18:44 #16
God ide. Lad mig prøve at pakke dem ind i en try catch block.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 18:50 #17
Hmmm ingen exception og det jeg mener med at de dør, er at der sker ingenting :(

Jeg har nogle log jeg skriver og de bliver skrevet ud, ingen data i databasen og ej heller noget i filen.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 18:53 #18
Sjovt, jeg rammer faktisk ikke break points inde i mine metoder.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 18:55 #19
ok, jeg rammer dem, men der sker bare ingenting...de ryger nærmest ud af scope midt under debug.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 19:03 #20
Jeps, der sker åbentbart en exception, når jeg forsøger at køre dem parallelt.

Jeg får denne exception:
[System.Threading.ThreadAbortException] = {Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 19:08 #21
Jeg bruger denne...men må nok ty til at fjerne, min drøm om at køre dem parallelt.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 19:08 #22
public async static void LogActivity(Action delegatedOperation, ActivityLog log)
{
    await Task.Run(() => ActivityAgent.AddActivityLog(log));
 
    await Task.Run(() => delegatedOperation.Invoke());
}
Avatar billede Syska Mester
03. juni 2013 - 19:09 #23
Jeg er også rimelig sikker på du skal håndtere dine Exception på en anden måde når du bruger TPL. Alt efter hvad du kalder.

Lidt googler synes jeg så alligevel ikke taler for min overstående ide. Jeg regner med at du har læst: http://msdn.microsoft.com/en-us/library/dd997415.aspx

Mærkeligt ... er det noget PInvoke tingeling du har gang i? Hvordan håndtere du exceptions nu?

Din sidste post herinde, kan måske skyldes: http://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/817776da-13da-43f5-a189-1727ce4f3b6b/

Men ellers har jeg ikke lige nogen ide.
Avatar billede CodingJoe Nybegynder
03. juni 2013 - 19:18 #24
Tjaaa...det kan være, jeg bare skal droppe det parallelle gejl...det virker jo fint uden, desuden skal jeg nok tænke mig om, hvis jeg skal begynde at bokse med disse typer fejl i min app.
Avatar billede arne_v Ekspert
04. juni 2013 - 02:54 #25
Selvfoelgelig kan det da lade sig goere at faa det til at koere parallelt.


Hvordan forsoeger du at catche exceptions?
Avatar billede CodingJoe Nybegynder
04. juni 2013 - 21:46 #26
:)

Jeg har blot lavet en traditionel try catch rundt om min kode der skriver i db vha. entity framework. Den kaster en thread abot exception. Måske skulle jeg prøve det som buzz taler om
Avatar billede arne_v Ekspert
30. juli 2013 - 04:55 #27
Tid at faa afsluttet her?
Avatar billede CodingJoe Nybegynder
30. juli 2013 - 10:36 #28
Hejsa

Du har ret Arne...selvom jeg stadigvæk ikke fik min tråddel til at virke...jeg har være optaget af andre ting imellem. Så Både Arne og Buzz smid svar ind, så fordeler jeg points.
Avatar billede arne_v Ekspert
31. juli 2013 - 05:31 #29
Det boer vaere muligt med en aller anden kombo af release/debug, 32/64 bit, optimize/non-optimize, debug/non-debug vaere muligt at faa en stack trace.
Avatar billede arne_v Ekspert
31. juli 2013 - 05:31 #30
og et svar
Avatar billede CodingJoe Nybegynder
31. juli 2013 - 10:01 #31
Jeg tror problemet er at min trådkode ligger ovenpå entity framework, hvori det selv kører trådbaseret. Ved ikke om den teori holder.

Jeg fordeler points, når Buzz også har reageret med et svar :)
Avatar billede Syska Mester
01. august 2013 - 20:04 #32
Svar
Avatar billede CodingJoe Nybegynder
08. august 2013 - 09:10 #33
Så er points fordelt.

Jeg tillader mig at skrive herinde...hvis jeg genoptager min udfordring på et senere tidspunkt. :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester