28. september 2014 - 04:16Der er
18 kommentarer og 1 løsning
Synkronisere aktivitet og sikre kun en udførsel på tværs af servere
Hej,
Jeg er interesseret i at vide, hvordan man bygger en service der kan kalde en given url på et fastsat tidspunkt e.g. kl. 04:00 hver dag. Præcis ligesom et cronjob.
Blot vil jeg gerne vide, hvordan man laver dette på tværs af en stak webservere. Går én webserver ned, skal en af de andre sørge for at udføre opgaven (kalde en url). Det er dog vigtigt at opgaven altid udføres præcis én gang i døgnet og ikke mere.
Hvordan ville man rent teoretisk strikke sådan en service sammen?
Det nemmeste er nok at bruge en database til at synkronisere web serverne.
En database som understoetter transaktioner, transaction isolation level >= repeateable read, SELECT inuse FROM synctbl og UPDATE synctbl SET inuse = TRUE.
Det må du lige uddybe arne_v, du vil bruge transaction til at sikre, at en af noderne ikke opdaterer, imens en anden allerede er i gang med processen. Så langt så godt, men hvad mener du med resten?
Og hvordan sikrer du dig, såfremt database-serveren går ned? Ideelt set, så jeg jo helst at der ikke var nogen hoved-server, som alle var afhængige af.
Men som udgangspunkt er der ikke nogen database-server til at overtage, princippet er, at jeg I vil sætte det op på php-webhoteller på tværs af forskellige udbydere.
Går én webserver/webhost helt ned, vil jeg gerne have at de andre kan klare opgaven. Uanset hvilke(n) webserver der går ned. Det jeg sørger er dybest set at lave min egen lille decentraliserede cloud. Jeg er dog opmærksom på, at der vil være tale om forskellige IP-adresser/domæner, som man vil skulle afprøve i tilfælde af, at en eller flere af noderne er nede.
Min egen tanke var noget i stil med, at server A skal fortælle/indhente accept fra over halvdelen af noderne, for at kan udføre opgaven. Lige så snart server A, har informeret de andre servere om dette, vil de jo så ikke udføre opgaven, og en eventuel server B vil ikke kunne få accept fra over halvdelen til også at udføre opgaven.
Denne fremgangsmåde betyder dog, at der potentielt kan gå ret lang tid førend en server har kontaktet minimum halvdelen af serverne. Så jeg tænkte, at der nok var en bedre måde. Men måske man skal ind og se på noget med én central (database-)server.
Du kan godt lave en loesning med in-memory data og kun kommunikation over netvaerk. Det du har bruge for er ogsaa kendt som en DLM - distributed lock manager.
Ud fra dit indlæg om DLM, har jeg kigget lidt nærmere på ZooKeeper. Med denne viden og dine svar, er jeg kommet frem til, at der nok skal udpeges én hovedserver. Ved fejl, må de andre servere, så sørge for automatisk at udpege en ny.
ZooKeeper fungerer ved at alle write operationer sendes til hovedserveren, som så iværksætter synkronisering med alle de andre servere. Dette princip kunne man sådan set sagtens kopiere. Og så selvfølgelig anvende transactions på hovedserveren.
Mit bud på en løsning: Hovedserver: Antag at vi har n=10 servere. Så snart en server (S1) ikke kan kontakte hovedserveren spørg den de andre servere, om de har forbindelse. Er der ikke forbindelse til hovedserveren udpeges S1 som ny hovedserver. Såfremt S1 ikke får nogle svar, anses den som værende afskåret. Når der igen er forbindelse til de andre, skal S1 derfor synkronisere på ny.
Synkronisering: En klient kontakter S2 med en write-forespørgsel. S2 kontakter hovedserveren, som også gemmer en log om forespørgselen. Hovedserveren accepterer og sender en opdatering rundt til alle servere med ændringen. S2 svarer klienten.
Ved simpel read-forespørgsel til S2, svarer S2 klienten ud fra egen data. En log sendes til hovedserveren.
Planlagte opgaver m.m. Alle serverne sørger på det planlagte tidspunkt at kontakte hovedserveren, som kun tillader første mand at udføre opgaven. Såfremt hovedserveren er utilgængelig, vælges først en ny, hvorefter opgaven udføres.
Bør man overveje deadlock problemer, såfremt S2 har fået tilladelse til at udføre en opgave, men aldrig vender tilbage, når den er løst? Nogen gode forslag hertil?
Jeg synes jo fordelen ved at lave det selv, var at man undgik afhængigheden af én (database-)server. Men det kan da godt ske du har ret i, at det ikke bliver for komplekst til at man kan opnå et ordentligt resultat.
Den ande mulighed var at koere noget andet (formentligt skrevet i Java) ved siden af Apache+PHP paa web serverene og lade PHP snakke med det via noget IPC/netvaerk kommunikation.
Jeg prøver mig frem med at lave min egen PHP-løsning, og vil så prøve at stress-teste den lidt. Så må vi se hvordan det hele performer.
Det kan meget vel være jeg ender med at bruge database-løsningen, men i første omgang, synes jeg, det kunne være interessant at lære lidt mere om DLM og de dertilhørende problemstillinger.
Læg et svar for din gode hjælp og kvalificerede råd!
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.