Programmering

Arkitekturer til serverbelastningsbalancering, del 1: Lastbalancering på transportniveau

Serverfarme opnår høj skalerbarhed og høj tilgængelighed gennem serverbelastningsafbalancering, en teknik, der får serverfarm til at fremstå for klienter som en enkelt server. I denne todelte artikel udforsker Gregor Roth serverbelastningsbalanceringsarkitekturer med fokus på open source-løsninger. Del 1 dækker det grundlæggende om serverbelastningsafbalancering og diskuterer fordele og ulemper ved serverbelastningsafbalancering på transportniveau. Del 2 dækker serverbelastningsbalanceringsarkitekturer på applikationsniveau, som imødekommer nogle af begrænsningerne i de arkitekturer, der er diskuteret i del 1.

Adgangsbarrieren for mange internetfirmaer er lav. Enhver med en god idé kan udvikle en lille applikation, købe et domænenavn og oprette et par pc-baserede servere til at håndtere indgående trafik. Den oprindelige investering er lille, så opstartsrisikoen er minimal. Men en vellykket billig infrastruktur kan hurtigt blive et alvorligt problem. En enkelt server, der håndterer alle indgående anmodninger, har muligvis ikke kapacitet til at håndtere høje trafikmængder, når virksomheden bliver populær. I sådanne situationer begynder virksomheder ofte at opskalere: de opgraderer den eksisterende infrastruktur ved at købe en større kasse med flere processorer eller tilføje mere hukommelse til at køre applikationerne.

Opskalering er dog kun en kortsigtet løsning. Og det er en begrænset tilgang, fordi omkostningerne ved opgradering er uforholdsmæssigt høje i forhold til gevinsterne i serverfunktion. Af disse grunde følger de mest succesrige internetfirmaer en skalere ud nærme sig. Applikationskomponenter behandles som flere forekomster på serverbedrifter, som er baseret på billig hardware og operativsystemer. Efterhånden som trafikken øges, tilføjes servere.

Server-farm tilgang har sine egne unikke krav. På softwaresiden skal du designe applikationer, så de kan køre som flere forekomster på forskellige servere. Du gør dette ved at opdele applikationen i mindre komponenter, der kan distribueres uafhængigt. Dette er trivielt, hvis applikationskomponenterne er statsløse. Da komponenterne ikke bevarer nogen transaktionstilstand, kan nogen af ​​dem håndtere de samme anmodninger ens. Hvis der kræves mere processorkraft, skal du blot tilføje flere servere og installere applikationskomponenterne.

Et mere udfordrende problem opstår, når applikationskomponenterne er statefulde. For eksempel, hvis applikationskomponenten indeholder indkøbskurvdata, skal en indgående anmodning dirigeres til en applikationskomponentforekomst, der indeholder den anmoders indkøbsvogndata. Senere i denne artikel vil jeg diskutere, hvordan man håndterer sådanne applikationssessionsdata i et distribueret miljø. For at reducere kompleksiteten forsøger de mest succesrige internetbaserede applikationssystemer dog at undgå stateful applikationskomponenter, når det er muligt.

På infrastrukturens side skal behandlingsbelastningen fordeles på gruppen af ​​servere. Dette er kendt som serverbelastningsbalancering. Belastningsafbalanceringsteknologier vedrører også andre domæner, f.eks. Spredning af arbejde blandt komponenter såsom netværkslink, CPU'er eller harddiske. Denne artikel fokuserer på serverbelastningsbalancering.

Tilgængelighed og skalerbarhed

Serverbelastningsbalancering distribuerer serviceanmodninger på tværs af en gruppe reelle servere og får disse servere til at ligne en enkelt stor server for klienterne. Ofte er snesevis af rigtige servere bag en URL, der implementerer en enkelt virtuel tjeneste.

Hvordan virker det? I en meget anvendt serverbelastningsarkitektur er den indgående anmodning rettet mod en dedikeret serverbelastningsbalancer, der er gennemsigtig for klienten. Baseret på parametre som tilgængelighed eller nuværende serverbelastning, bestemmer belastningsbalanceren, hvilken server der skal håndtere anmodningen og videresender den til den valgte server. For at give belastningsbalanceringsalgoritmen de krævede inputdata henter load balancer også oplysninger om servernes sundhed og belastning for at kontrollere, at de kan reagere på trafik. Figur 1 illustrerer denne klassiske load balancer-arkitektur.

Lastafsenderarkitekturen illustreret i figur 1 er kun en af ​​flere tilgange. For at beslutte, hvilken lastbalanceringsløsning der er bedst for din infrastruktur, skal du overveje tilgængelighed og skalerbarhed.

Tilgængelighed defineres af oppetid - tiden mellem fejl. (Nedetid er tiden til at opdage fejlen, reparere den, udføre den nødvendige gendannelse og genstarte opgaver.) Under oppetid skal systemet svare på hver anmodning inden for en forudbestemt, veldefineret tid. Hvis denne tid overskrides, ser klienten dette som en serverfejl. Høj tilgængelighed er grundlæggende redundans i systemet: hvis en server fejler, overtager de andre den mislykkede serverbelastning gennemsigtigt. Fejlen hos en enkelt server er usynlig for klienten.

Skalerbarhed betyder, at systemet kan betjene en enkelt klient såvel som tusindvis af samtidige klienter ved at leve op til servicekvalitetskrav såsom svartid. Under en øget belastning kan et højt skalerbart system øge kapaciteten næsten lineært i forhold til effekten af ​​ekstra hardware-ressourcer.

I scenariet i figur 1 opnås høj skalerbarhed ved at distribuere den indgående anmodning over serverne. Hvis belastningen stiger, kan yderligere servere tilføjes, så længe belastningsbalanceren ikke bliver flaskehalsen. For at nå høj tilgængelighed skal load balancer overvåge serverne for at undgå at videresende anmodninger til overbelastede eller døde servere. Desuden skal selve belastningsbalanceren også være overflødig. Jeg diskuterer dette punkt senere i denne artikel.

Serverbelastningsteknikker

Generelt er serverbelastningsbalanceringsløsninger af to hovedtyper:

  • Transportniveau belastningsbalancering - såsom den DNS-baserede tilgang eller TCP / IP-niveau belastningsbalancering - fungerer uafhængigt af applikationsnyttelasten.
  • Applikationsniveau belastningsbalancering bruger applikationsnyttelasten til at træffe beslutninger om belastningsbalancering.

Load balancing-løsninger kan yderligere klassificeres i softwarebaserede load balancers og hardware-baserede load balancers. Hardware-baserede belastningsafbalancere er specialiserede hardwarekasser, der inkluderer applikationsspecifikke integrerede kredsløb (ASIC), der er tilpasset til en bestemt anvendelse. ASIC'er muliggør videresendelse af netværkstrafik med høj hastighed uden overhead for et generelt operativsystem. Hardware-baserede belastningsafbalancere bruges ofte til belastningsafbalancering på transportniveau. Generelt er hardwarebaserede belastningsbalancere hurtigere end softwarebaserede løsninger. Deres ulempe er deres omkostninger.

I modsætning til hardware-balancering kører softwarebaserede load-balancere på standardoperativsystemer og standardhardwarekomponenter såsom pc'er. Softwarebaserede løsninger kører enten inden for en dedikeret hardwareknude til belastningsbalancering som i figur 1 eller direkte i applikationen.

DNS-baseret belastningsafbalancering

DNS-baseret belastningsbalancering repræsenterer en af ​​de tidlige serverbelastningsbalanceringsmetoder. Internets domænenavnssystem (DNS) knytter IP-adresser til et værtsnavn. Hvis du skriver et værtsnavn (som en del af URL'en) i din browser, beder browseren om, at DNS-serveren løser værtsnavnet til en IP-adresse.

Den DNS-baserede tilgang er baseret på det faktum, at DNS tillader flere IP-adresser (rigtige servere) at blive tildelt et værtsnavn, som vist i DNS-opslagseksemplet i liste 1.

Fortegnelse 1. Eksempel på DNS-opslag

> nslookup amazon.com Server: ns.box Adresse: 192.168.1.1 Navn: amazon.com Adresser: 72.21.203.1, 72.21.210.11, 72.21.206.5

Hvis DNS-serveren implementerer en round-robin-tilgang, ændres rækkefølgen af ​​IP-adresserne for en given vært efter hvert DNS-svar. Normalt prøver klienter som browsere at oprette forbindelse til den første adresse, der returneres fra en DNS-forespørgsel. Resultatet er, at svar på flere klienter fordeles mellem serverne. I modsætning til serverens belastningsbalanceringsarkitektur i figur 1 kræves der ingen mellemliggende belastningsbalanceringshardwareknude.

DNS er en effektiv løsning til global serverbelastningsafbalancering, hvor belastning skal fordeles mellem datacentre forskellige steder. Ofte kombineres den DNS-baserede globale serverbelastningsafbalancering med andre serverbelastningsafbalanceringsløsninger for at distribuere belastningen inden for et dedikeret datacenter.

Selvom det er let at implementere, har DNS-tilgangen alvorlige ulemper. For at reducere DNS-forespørgsler har klienten tendens til at cache DNS-forespørgslerne. Hvis en server ikke er tilgængelig, vil klientcachen såvel som DNS-serveren fortsat indeholde en død serveradresse. Af denne grund gør DNS-tilgangen lidt for at implementere høj tilgængelighed.

TCP / IP-server belastningsbalancering

TCP / IP-serverbelastningsbalancere fungerer ved lavskiftning af lag. En populær softwarebaseret serverbelastningsbalancer på lavt niveau er Linux Virtual Server (LVS). De virkelige servere fremstår for omverdenen som en enkelt "virtuel" server. De indgående anmodninger om en TCP-forbindelse videresendes til de virkelige servere af load balancer, der kører en Linux-kerne, der er patched, så den inkluderer IP Virtual Server (IPVS) -kode.

For at sikre høj tilgængelighed er der i de fleste tilfælde oprettet et par belastningsafbalanceringsnoder med en belastningsafbalanceringsnode i passiv tilstand. Hvis en belastningsbalancering mislykkes, aktiverer hjerteslagsprogrammet, der kører på begge belastningsbalancere, den passive belastningsbalanceringsnode og initierer overtagelsen af ​​den virtuelle IP-adresse (VIP). Mens hjerterytmen er ansvarlig for styring af failover mellem load balancere, bruges simple send / expect-scripts til at overvåge de virkelige serveres sundhed.

Gennemsigtighed over for klienten opnås ved hjælp af en VIP, der er tildelt belastningsbalanceren. Hvis klienten udsender en anmodning, oversættes først det ønskede værtsnavn til VIP. Når den modtager anmodningspakken, bestemmer belastningsbalanceren, hvilken rigtig server der skal håndtere anmodningspakken. Mål-IP-adressen på anmodningspakken omskrives til den reelle IP (RIP) på den rigtige server. LVS understøtter flere planlægningsalgoritmer til distribution af anmodninger til de rigtige servere. Det er ofte indstillet til at bruge round-robin planlægning, svarende til DNS-baseret load balancing. Med LVS træffes beslutning om belastningsafbalancering på TCP-niveau (lag 4 i OSI-referencemodellen).

Efter modtagelse af anmodningspakken håndterer den rigtige server den og returnerer svarpakken. For at tvinge svarpakken til at blive returneret gennem belastningsafbalanceren bruger den virkelige server VIP som sin standardresponsrute. Hvis belastningsbalanceren modtager svarpakken, omskrives kildens IP-adresse til svarpakken med VIP (OSI Model Layer 3). Denne LVS-routingtilstand kaldes NAT-routing (Network Address Translation). Figur 2 viser en LVS-implementering, der bruger NAT-routing.

LVS understøtter også andre routingtilstande som f.eks Direkte serverretur. I dette tilfælde sendes svarpakken direkte til klienten af ​​den rigtige server. For at gøre dette skal VIP også tildeles alle ægte servere. Det er vigtigt at gøre serverens VIP uopløselig for netværket; I modsat fald bliver belastningsbalanceren utilgængelig. Hvis load balancer modtager en anmodningspakke, omskrives MAC-adressen (OSI Model Layer 2) for anmodningen i stedet for IP-adressen. Den rigtige server modtager anmodningspakken og behandler den. Baseret på kilde-IP-adressen sendes svarpakken direkte til klienten og omgår belastningsbalanceren. For webtrafik kan denne tilgang reducere balancerens arbejdsbyrde dramatisk. Typisk overføres mange flere svarpakker end anmodningspakker. For eksempel, hvis du anmoder om en webside, sendes ofte kun en IP-pakke. Hvis der anmodes om en større webside, kræves der flere IP-pakker til svar for at overføre den anmodede side.

Caching

Serverbelastningsbalanceringsløsninger på lavt niveau som f.eks. LVS når deres grænse, hvis caching på applikationsniveau eller understøttelse af applikationssession er påkrævet. Cache er et vigtigt skalerbarhedsprincip for at undgå dyre operationer, der henter de samme data gentagne gange. En cache er en midlertidig butik, der indeholder overflødige data som følge af en tidligere datahentningshandling. Værdien af ​​en cache afhænger af omkostningerne til at hente dataene i forhold til hitfrekvensen og den krævede cache-størrelse.

Baseret på algoritmen til planlægning af load balancer håndteres anmodningerne fra en brugersession af forskellige servere. Hvis der bruges en cache på serversiden, vil afvigende anmodninger blive et problem. En tilgang til at håndtere dette er at placere cachen i et globalt rum. memcached er en populær distribueret cache-løsning, der giver en stor cache på tværs af flere maskiner. Det er en partitioneret, distribueret cache, der bruger ensartet hashing til at bestemme cache-serveren (dæmonen) for en given cacheindgang. Baseret på cache-nøglens hash-kode kortlægger klientbiblioteket altid den samme hash-kode til den samme cache-serveradresse. Denne adresse bruges derefter til at gemme cacheindgangen. Figur 3 illustrerer denne cache-tilgang.

Listing 2 anvendelser spymemcached, a memcached klient skrevet i Java til cache HttpResponse meddelelser på tværs af flere maskiner. Det spymemcached biblioteket implementerer den krævede klientlogik, jeg lige har beskrevet.

Liste 2. memcached-baseret HttpResponse cache