10. maj 2013 - 09:18Der 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.
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.
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.
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.
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.
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.
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.
#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.
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 ...
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.
Har også prøvet følgende public async static void LogActivity(Action delegatedOperation, ActivityLog log) { await Task.Run(() => ActivityAgent.AddActivityLog(log));
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.}
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.
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
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.
Jeg tillader mig at skrive herinde...hvis jeg genoptager min udfordring på et senere tidspunkt. :)
Synes godt om
Ny brugerNybegynder
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.