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

Queues: hoe dubbele acties voorkomen?

Pagina: 1
Acties:

Onderwerpen


  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Stel ik wil een nieuwe user aanmaken. Ik valideer in m'n service layer of die user al bestaat, zo ja dan return ik een error naar de presentation layer, zo nee dan stop ik een message in m'n queue (Azure Service Bus in dit geval) dat de user aangemaakt moet worden.

Wat ik me nou echter bedacht: wat nou als er een message in de queue zit dat die gebruiker aangemaakt moet worden en ondertussen komt er een nieuw verzoek? Dan zitten er twee conflicterende messages in mijn queue.

Ik heb heel erg veel op internet gezocht over queueing, maar dit is nou zo'n probleem waar ik niet uit kom. Tot slot: heeft iemand misschien een goed real world voorbeeld waar messaging wordt toegepast? In letterlijk alle tutorials stoppen ze er een simpele string in die ze bij de worker/listener er uit lezen en tonen in een console. Waar ik meer benieuwd naar ben is hoe andere mensen CRUD operaties doen via messaging, zoals het aanmaken/updaten/deleten van gebruikers/producten/artikelen/whatever.

  • Xeo
  • Registratie: November 2002
  • Laatst online: 18:37

Xeo

Misschien denk ik te simpel.... Maar is het niet mogelijk om te controleren of de gebruiker al bestaat op het moment dat je het bericht uit de queue haalt?

Edit: Misschien blaat ik enorm... Ik heb geen ervaring met Azure... :X

[ Voor 19% gewijzigd door Xeo op 12-04-2012 19:35 ]


  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Nee je blaat volgens mij niet, zou best kunnen. Alleen mijn idee was: ik doe éérst validatie, en alleen de goede berichten stop ik in mijn queue. Op die manier kun je (lijkt mij) kosten beparen omdat je minder messages hoeft te versturen. Nu kan ik ook bij het uitlezen van de message validatie doen, maar dan zit ik weer met dubbele validatie.

  • Xeo
  • Registratie: November 2002
  • Laatst online: 18:37

Xeo

Een alternatief is om de queue te doorlopen om te kijken of er al zo'n dergelijke message in zit, maar dat is ook niet echt optimaal...

[ Voor 63% gewijzigd door Xeo op 12-04-2012 19:38 ]


  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Lijkt me heel erg slecht voor je performance, als het überhaupt al mogelijk is om dat te doen zonder zonder de berichten daadwerkelijk te dequeuen.

  • Spockz
  • Registratie: Augustus 2003
  • Laatst online: 19-11 13:44

Spockz

Live and Let Live

Ik zou het wellicht anders doen, stuur het bericht van `maak user aan' gewoon de queue op en voeg iets toe als een callback of wellicht een messagequeue terug zodat je daarmee een eventuele fout af kunt handelen.

Het probleem wat je schetst is dat je een user wilt toevoegen, die bestaat nog niet dus je stuurt een bericht de queue op, vervolgens blijft dat ding even in de queue. Er komt nog een request om een user aan te maken, jij checkt of hij bestaat (nee, want je originele bericht zit nog in de queue.) dus je stuurt een nieuw bericht de queue in. Vervolgens krijg je dus twee berichten in je queue die zeggen dat dezelfde user aangemaakt moet worden.

Dit ga je alleen ondervangen als je de controle verplaatst naar het moment waar er daadwerkelijk iets gaat gebeuren. Anders zul je altijd houden dat je dit soort dubbele acties kan krijgen. Tenzij je op de plek waar je berichten de queue in duwt een log bijhoudt van dingen die mogelijk nog gaan gebeuren zodat je nieuwe requests kunt filteren.

C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8


  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Spockz schreef op donderdag 12 april 2012 @ 19:55:
Ik zou het wellicht anders doen, stuur het bericht van `maak user aan' gewoon de queue op en voeg iets toe als een callback of wellicht een messagequeue terug zodat je daarmee een eventuele fout af kunt handelen.
Fout afhandelen als in? Een dergelijke callback zou dan toch net zo goed pas over 5 minuten kunnen komen, lijkt me niet dat je een gebruiker zo lang op feedback kunt laten wachten of zijn/haar actie geslaagd is :+

  • Spockz
  • Registratie: Augustus 2003
  • Laatst online: 19-11 13:44

Spockz

Live and Let Live

Je probeert hier nu van tevoren te voorspellen wat er gaat gebeuren en wilt aan de hand daarvan al feedback geven. Dat gaat gewoon niet. Niet als je het uitvoeren uitstelt. :) Stel nou dat je een check doet voordat je je actie op de queue zet. Dan kun je meteen feedback geven. Maar wat nou als er een fout optreed die je niet had voorzien of een geval waar je geen controle voor hebt? Dan heb je toch al tegen de gebruiker gezegd dat het allemaal goed is gegaan, zonder dat hetgeen wat hij wilde daadwerkelijk is uitgevoerd.

C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8


  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Daar heb je inderdaad gelijk in. Maar ik snap maar niet hoe je dit dan oplost :P Want je moet toch íets aan de gebruiker laten weten? Het kan zijn dat je worker down is en je message pas na een uur afgehandeld wordt. Hoe werkt zoiets :?

Maar misschien lost een real-world voorbeeld al m'n problemen op :P Heb alleen zelf nog niks kunnen vinden met Google :(

  • Spockz
  • Registratie: Augustus 2003
  • Laatst online: 19-11 13:44

Spockz

Live and Let Live

Het enige wat je kunt doen is melden dat de actie om het te doen gescheduled is. Veel meer dan dat kun je niet met zekerheid zeggen. Tenzij je dus een systeem bedenkt waarbij je alle acties die je wilt doen eerst controleert met de state die je zelf bijhoudt.

Dus als je een bericht "maak user aan" stuurt, hou je zelf in de state bij dat die user bestaat, daar kun je dus vanuit gaan zolang je geen bericht van het tegendeel hebt gehad van je backend. Maar dit soort constructies zijn altijd fragiel en gedoemd om te falen.

Het beste lijkt mij om eerlijk te zijn naar je gebruiker toe. En ook de backend feedback te laten geven, dus je ziet een berichtje "Scheduled user add" -....- "User added".

C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Avalaxy schreef op donderdag 12 april 2012 @ 20:05:
[...]
Fout afhandelen als in? Een dergelijke callback zou dan toch net zo goed pas over 5 minuten kunnen komen, lijkt me niet dat je een gebruiker zo lang op feedback kunt laten wachten of zijn/haar actie geslaagd is :+
De gebruiker heeft maar 5 minuten te wachten :)

Hij kan toch niet inloggen, want de gebruiker bestaat normaliter simpelweg nog niet totdat de callback terug is.

Je kan een gebruiker pas informeren of zijn actie geslaagd is als die door de queue heen is, zolang hij in de queue zit kan je niet zeggen of hij wel of niet slaagt.

Je kan de gebruiker wel informeren of hij door alle validaties heenkomt (simpel : geen validatie foutmelding) maar of de actie geslaagd is weet je pas nadat de callback terug is.

Ik kan me ook voorstellen dat je 2 queues hanteert ( of 1 queue en rechtstreeks contact met de dbase ernaast) zodat je dingen die echt een callback nodig hebben (user aanmaken etc) snel een callback kunnen krijgen, terwijl bijv een twitter bericht in de langzame queue mag komen.
Je kan ook eens kijken of je queuing mechanisme geen prioritys kent.

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Daar had ik idd al aan gedacht. Ik gebruik nu 1 queue voor updaten/schrijven/bewerken en een rechtstreekse verbinding met de DB voor het opvragen van data. Ik zit er aan te denken om een tweede queue te maken voor low-priority stuff.

Of de Azure Service Bus standaard iets heeft voor priorities weet ik niet, maar je kunt natuurlijk ook gewoon de low-priority queue met een groter interval pollen, lijkt me ook prima te werken :)

Thanks voor de ideeën in ieder geval, eens kijken of ik er wat van kan bakken.

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Avalaxy schreef op donderdag 12 april 2012 @ 22:16:
Daar had ik idd al aan gedacht. Ik gebruik nu 1 queue voor updaten/schrijven/bewerken en een rechtstreekse verbinding met de DB voor het opvragen van data.
Waarom doe je dit zo (let op : zelf geen ervaring met queues)?
Juist het opvragen van data lijkt me perfect voor een queue, daar doet de tijd er niet echt toe (je hangt er simpelweg een cacheing stuk voor wat ververst wordt met data uit de queue)

De gebruikers insert/updates wil je direct verwerkt hebben lijkt mij (stats / logging inserts/updates kan je wel weer in de low prio queue gooien) terwijl je aan de opvraag kant zeer waarschijnlijk toch al cacheing hebt draaien die het wachten op de queue opvangt.

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Gomez12 schreef op donderdag 12 april 2012 @ 22:25:
[...]

Waarom doe je dit zo (let op : zelf geen ervaring met queues)?
Juist het opvragen van data lijkt me perfect voor een queue, daar doet de tijd er niet echt toe (je hangt er simpelweg een cacheing stuk voor wat ververst wordt met data uit de queue)
Nouja, voor het cachen en ophalen van data heb je geen queue nodig, je kunt gewoon direct dingen uit de DB halen en in een distributed cache oid zetten, en dat serveren aan de gebruiker. Ik zie persoonlijk de toegevoegde waarde van een queue daar niet (al kan iemand dat misschien uitleggen).
De gebruikers insert/updates wil je direct verwerkt hebben lijkt mij (stats / logging inserts/updates kan je wel weer in de low prio queue gooien) terwijl je aan de opvraag kant zeer waarschijnlijk toch al cacheing hebt draaien die het wachten op de queue opvangt.
Dat wil je inderdaad wel, maar dat gaat niet altijd. Als je ineens veel traffic krijgt, mensen verwerken veel transacties, etc. dan wil je dat die ergens in een queue blijven hangen tot er capaciteit is om de aanvragen te verwerken. Op die manier gaat er geen data verloren en kun je de load makkelijk verdelen door meerdere workers naar je queue te laten luisteren. Je zou zelfs je workers compleet offline kunnen halen (bijvoorbeeld om systeemupdates door te voeren), waarna alle aanvragen die opgestapeld zitten in je queue worden verwerkt zodra de worker weer online is.

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Avalaxy schreef op donderdag 12 april 2012 @ 22:31:
[...]
Dat wil je inderdaad wel, maar dat gaat niet altijd. Als je ineens veel traffic krijgt, mensen verwerken veel transacties, etc. dan wil je dat die ergens in een queue blijven hangen tot er capaciteit is om de aanvragen te verwerken. Op die manier gaat er geen data verloren en kun je de load makkelijk verdelen door meerdere workers naar je queue te laten luisteren. Je zou zelfs je workers compleet offline kunnen halen (bijvoorbeeld om systeemupdates door te voeren), waarna alle aanvragen die opgestapeld zitten in je queue worden verwerkt zodra de worker weer online is.
Volgens mij (als je queues zo wil inzetten) dan moet je juist met callbacks gaan werken. Met meerdere workers die naar een queue luisteren is de volgende stap dat je de verschillende workers op verschillende server etc zet. En dan wil je toch echt wel ergens via een callback weten welke worker van welke server de job heeft opgepikt zodat je die server later weer kan terugvinden.

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Gomez12 schreef op donderdag 12 april 2012 @ 22:38:
[...]

En dan wil je toch echt wel ergens via een callback weten welke worker van welke server de job heeft opgepikt zodat je die server later weer kan terugvinden.
Waarom is het relevant om te weten welke server request x afhandelt? Zolang dat maar gewoon gebeurt toch? Uiteindelijk gooien ze het toch allemaal in dezelfde database.

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Avalaxy schreef op donderdag 12 april 2012 @ 22:42:
[...]


Waarom is het relevant om te weten welke server request x afhandelt? Zolang dat maar gewoon gebeurt toch? Uiteindelijk gooien ze het toch allemaal in dezelfde database.
Ik zat te denken aan meerdere image servers, of meerdere fileservers of meerdere db-servers. Ergens op een centraal punt moet bijgehouden waar image x staat. Niet dat het maar de queue in is gegooid en dat het nu ergens staat.

Als je meerdere workers op meerdere file-servers hebt die een message kunnen opvangen, dan weet je dbase nog niet op welke server de fysieke file staat. Die info krijg je volgens mij enkel uit de callback (waarna je het weer in de db kan verwerken).

Ik denk dan meer in de richting van cdn's / megaupload etc. Er moet een file opgeslagen worden, waar is niet relevant, oftewel je gooit de file de queue in de eerst beschikbare worker schrijft de file weg. Daarna wordt de callback geregistreerd in de dbase zodat die weet waar de file staat.

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 01:14

The Eagle

I wear my sunglasses at night

me heeft nog wel eens met messaging en integration brokers van doen, dus here goes:
Bij (web)messaging heb je twee verschillende types: synchronous en asynchronous.
Asynchronous is fire-and forget; die komt dus bij het ontvangende systeem in de queue terecht en wordt op een gegeven moment wel verwerkt.
Bij synchronous messaging wacht de verzendende partij net zo lang tot hij een acknowledge heeft dat de message verwerkt is. Dat kan in TS' geval een oplossing zijn, dwz: controleer voor verzenden eerst of er niet nog unacknowledged messages zijn die betrekking hebben op de zelfde data (dttm stamp icm data).

Wordt in TS' geval async messaging gebruikt, dan zal TS er in zijn verzendende systeem voro moeten zorgen dat een volledige dataset wordt overgestuurd, en in het ontvangende moet een controle zijn op de datetimestamp van zowel de message, alsook in relatie tot de bestaande data en de met de message binnengekomen nieuwe data. Alleen dan kan een message goed verwerkt worden.

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


  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 22-11 16:12
Oh op die fiets. Dat hoef ik allemaal niet te regelen want dat houdt Azure bij. Als ik een BLOB upload weet de BLOB Storage API waar die BLOB zich bevindt en returnt die naar mij. Zelfde voor de database, die is onder water sharded over meerdere servers maar daar heb ik verder niks mee te maken.
Thanks voor de uitleg. Ik zat eerst te denken aan async, maar wellicht is synchronous wel een goede optie. Eens uitzoeken hoe dat werkt :)

[ Voor 23% gewijzigd door Avalaxy op 12-04-2012 23:30 ]


  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 10-10 08:02
Volgens als data realtime nodig is, is een queue niet het antwoord op je probleem.


Facebook doet dit bijvoorbeeld ook. Bij het aanmaken van een nieuw account wordt er realtime (dus synchr.) gecontroleerd of die naam al bestaat. Zo ja wordt er een bericht getoond dat die naam als bestaat.

Bij het versturen van status update wordt jouw bericht aan de queue toegevoegd en plopt binnen een paar tellen op je scherm, waarna de andere nodes van facebook dit bericht binnen redelijke tijd ook krijgen. Maar die distributie regelt hun database laag, en niet de applicatie laag. Kortom ze gebruiken meerdere queues, maar dat moet in hun geval ook wel ;)

Nu denk ik dat in het geval van facebook met hun miljoenen gebruikers wel ergens een binnenbocht is genomen qua usercheck, of in ieder geval iets van een dedicated systeem wat puur en alleen users bij houdt. Geen idee wat hun groei-ratio per seconde/minuut is, maar ik kan mij voorstellen dat dit best hard gaat op sommige momenten.

Kortom, ik denk dat het slimmer is om eerst je scopes te bepalen, wat realtime moet, en wat kan wachten en op basis daarvan gaan besluiten wat je moet queue'n.

Driving a cadillac in a fool's parade.

Pagina: 1