[asp.net] waar het beste cache inladen?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Beste mensen,

Ik heb een vrij redelijke webapp in asp.net. Deze maakt gebruik van data uit een database, en een deel daarvan is wat lastig daar uit te halen, en is redelijk statisch

Dit doe ik dus elke x minuten in een apparte thread en dat cache ik in System.Web.Caching.Cache

Ik heb nu een werkende situatie, maar ben daar niet zo tevreden over, dit om twee redenen

1. Ik start nu een thead die x minuten wacht, een taak uitvoert, weer wacht etc.
C#:
1
while (true) { /* shizzle */ }

Dit zorgt ervoor dat 1 thread 99% van ze tijd uit ze neus zit te vreten. Die thread zou ik liever willen returnen naar de threadpool.

2. Ik start de thread in de application start (middels global.asax)
Dit heeft echter als nadeel, dat wanneer de database even een hickup heeft, of er ergens anders iets fout gaat in het update proces van die cachegegeven, mijn applicationpool stopt.
Deze moet ik dan weer met de hand starten.. op alle servers..


Kortom, ik zit mij hier zo een beetje af te vragen hoe jullie dat doen.
Is er een standaard manier voor? hebben jullie het ook zelf geknutseld? zijn er best practises?

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Je hebt hier gewoon attributes voor die alles voor je regelen:
http://www.asp.net/mvc/ov...ce-with-output-caching-cs

Als het écht lange queries zijn dan kan je idd een lang lopende loop maken, alleen die zal zichzelf wel cancellen zodra de site in suspended state gaat.

Anders kan je nog een externe cache gebruiken die je vult met bv een cronjob.

[ Voor 10% gewijzigd door Megamind op 06-08-2015 23:54 ]


Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 19-09 08:37
@MegaMind: Hij praat waarschijnlijk over object caching, niet output caching.

Om te beginnen is het zowieso niet handig om taken in je asp.net applicatie te verwerken. Zie The Dangers of Implementing Recurring Background Tasks In ASP.NET
Je probleem is dan ook nr 1 op de lijst daar.

Als je draait op een recente versie van .net (4.5.2) kun je het doen met QueueBackgroundWorkItem.

Je kan ook je taken via hangfire uit laten voeren. Dat is een makkelijke en betrouwbare manier om het te doen, maar hiervoor moet eea opgeslagen worden dus moet je database uitgebreid worden met een aantal tabellen.

Ook zou ik de webcache alleen voor outputcaching gebruiken, en voor objecten de memorycache.
Caching is niet zo simpel dus om daar een nuttig antwoord op te geven moet het scenario wat duidelijker zijn.

Beetje ot misschien: Je praat over dat je de applicationpools op meerder servers moet herstarten. Dit doet me denken dat er een bedrijf is die een aantal servers runt voor die applicatie, maar af en toe is die applicatie offline? Is het dan niet verstandig voor dat bedrijf om even wat meer aandacht aan ontwikkeling te geven zodat de broodnodige kwaliteitsverbeteringen doorgevoerd worden?

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
volgens mij praten we een beetje langs elkaar heen.

Ik heb het idd niet over output caching. Ik heb een query die zo'n 3 tot 6 minuten draait en daar komt een shitload aan data uit die ik regelmatig gebruik.

Ik stop die in een objecten structuur in System.Web.Caching.Cache

Wanneer ik die dan wil bevragen haal ik de data daar uit, want dat is veel sneller.

De code die dat nu voor elkaar krijgt is 10 regels ofzo (de daadwerkelijke query uitgesloten natuurlijk) en ik heb weinig behoefte om een compleet nieuw (extern) framework in mijn applicatie te hangen omdat ik niet tevreden ben met die 10 regels.

Volgens mij moet dat prima 'zelf' kunnen.
Ook zou ik de webcache alleen voor outputcaching gebruiken, en voor objecten de memorycache.
Caching is niet zo simpel dus om daar een nuttig antwoord op te geven moet het scenario wat duidelijker zijn.
Die snap ik niet...
Nogmaals: ik heb te dynamische paginas en gebruik dus geen outputcache.
Verder weet ik dat cache invalidation moeilijk is, maar dit is compleet niet het punt waar ik het in het topic over wil hebben.

Ik wil het hebben over hoe ik het beste background taken kan draaien zonder dat mijn applicatie er last van heeft.


ontopic:
Iets dat ik in het verleden wel eens geprobeerd heb is vanuit een extern proces (dus niet de iis site), maar bijv. een scheduled task data toe te voegen aan de System.Web.Caching.Cache..

Echter werkt die cache blijkbaar niet procesoverstijgend, en kan ik dus in proces 1 niet bij gecachede data uit proces2
Bummer :(

Jogai:
De link die je stuurt over QueueBackgroundWorkItem is een leuke (alhoewel het slechte voorbeeldcode is met zoveel azure meuk er omheen)
Helaas zitten wij nog op 4.5.1, dus ik weet niet helemaal of we het kunnen gebruiken.
Maar misschien is dit een goede reden om te upgraden..

Maar de grote vraag is dus even:

Als ik die QueueBackgroundWorkItem gebruik, hoe los ik dan mijn twee problemen op.

Want volgens mij blijven ze allebei bestaan.

1. QueueBackgroundWorkItem zal iets aftrappen, en dan terugkomen. Als ik wil dat ie het na x tijd weer aftrapt zal ik een of andere timer moeten gebruiken of moeten wachten (thread.sleep) waardoor mijn thread nog steeds niet vrijgegeven wordt.

2. QueueBackgroundWorkItem zal volgens mij ook de applicationpool stoppen als de task die hij uitvoert fout gaat. Omdat hij gestart wordt vanuit de 'applicationStart' in de global asax. Als er in de applicationStart een fout optreed stopt de app-pool..

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 18-09 16:24

mulder

ik spuug op het trottoir

Kun je niet gewoon cachen in de database; sla het resultaat van de intensieve query op.

oogjes open, snaveltjes dicht


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
mulder schreef op vrijdag 07 augustus 2015 @ 13:38:
Kun je niet gewoon cachen in de database; sla het resultaat van de intensieve query op.
Wat je wilt is inderdaad naar alle waarschijnlijkheid gewoon een indexed view.

Acties:
  • 0 Henk 'm!

  • HansvDr
  • Registratie: Augustus 2009
  • Niet online
Ik heb het ooit opgelost door het resultaat van de zware query in een tabel op te slaan. De zware query draaide via een scheduled task. De zware query werd alleen uitgevoerd als de brondata was aangepast wat ik met een trigger en een eigen status tabel bijhield.

De tabel met het opgeslagen resultaat gebruikte ik in mijn applicatie.

Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Je zou gebruik kunnen maken van een externe cache-service (bijvoorbeeld NCache, maar er zijn er meer), zodat die caching niet meer in je appdomain draait. Al je webapplicaties verbinden dan met die cache om hun data eruit te halen, het vullen van de cache doe je dan vanuit een losse applicatie die je aanroept d.m.v. de task scheduler van Windows.

Voordelen:
1) Je hebt geen thread die de helft van de tijd slaapt
2) Je hebt maar één zware taak die je databaseserver lastigvalt i.p.v. N zware taken (1 per webserver)
3) Je kunt precies bepalen wanneer je de cache invalidate

Je zult wel een beetje werk moeten doen: op alle plekken waar je nu de HttpCache aanroept zal je moeten uitwijken naar je nieuwe cache.



Een simpel alternatief is natuurlijk dat je een "RefreshCache"-achtige pagina maakt die je eens in de zoveel minuten aanroept vanuit een scheduled task. Dit moet je dan wel per webserver configureren. Je hebt dan geen last meer van stoppende apppools door exceptions uit je thread :)

[ Voor 18% gewijzigd door Alex) op 09-08-2015 02:43 ]

We are shaping the future


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
HansvDr schreef op zaterdag 08 augustus 2015 @ 11:08:
Ik heb het ooit opgelost door het resultaat van de zware query in een tabel op te slaan. De zware query draaide via een scheduled task. De zware query werd alleen uitgevoerd als de brondata was aangepast wat ik met een trigger en een eigen status tabel bijhield.

De tabel met het opgeslagen resultaat gebruikte ik in mijn applicatie.
Dat is effectief een indexed view, maar dan met de hand geimplementeerd (en mogelijk minder geoptimaliseerd).

Acties:
  • 0 Henk 'm!

  • HansvDr
  • Registratie: Augustus 2009
  • Niet online
R4gnax schreef op zondag 09 augustus 2015 @ 13:37:
[...]


Dat is effectief een indexed view, maar dan met de hand geimplementeerd (en mogelijk minder geoptimaliseerd).
Dat kan, in onze situatie kon ik geen indexed view gebruiken door de onderliggende data en de query. Dan is een eigen tabel een prima, en snel werkend alternatief. Tenminste, hier wel.
Pagina: 1