Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Orleans tillhandahåller klusterhantering via ett inbyggt medlemskapsprotokoll, som ibland kallas klustermedlemskap. Målet med det här protokollet är att alla silor (Orleans servrar) ska komma överens om uppsättningen silor som för närvarande lever, identifiera misslyckade silor och tillåta att nya silor ansluter till klustret.
Protokollet förlitar sig på en extern tjänst för att tillhandahålla en abstraktion av IMembershipTable.
IMembershipTable är en platt, beständig tabell som används för två ändamål. För det första fungerar det som en mötespunkt där silor kan hitta varandra och där Orleans klienter kan hitta silor. För det andra lagrar den den aktuella medlemskapsvyn (lista över aktiva silor) och hjälper till att komma överens om den här vyn.
För närvarande finns det flera implementeringar av IMembershipTable: baserat på Azure Table Storage, Azure Cosmos DB, ADO.NET (PostgreSQL, MySQL/MariaDB, SQL Server, Oracle), Apache ZooKeeper, Consul IO, AWS DynamoDB, MongoDB, Redis, Apache Cassandra och en minnesintern implementering för utveckling.
Förutom IMembershipTabledeltar varje silo i ett fullständigt distribuerat peer-to-peer-medlemskapsprotokoll som identifierar misslyckade silor och når en överenskommelse om uppsättningen levande silor. Den interna implementeringen av Orleansmedlemskapsprotokollet beskrivs nedan.
Medlemskapsprotokollet
Vid start lägger varje silo till en post för sig själv i en välkänd delad tabell med hjälp av en implementering av IMembershipTable. Orleans använder en kombination av siloidentitet (
ip:port:epoch) och tjänstdistributions-ID (kluster-ID) som unika nycklar i tabellen. Epok är helt enkelt tiden i tidsenheter när den här silon startade, vilket säkerställer attip:port:epochär unik inom en Orleans driftsättning.Silos övervakar varandra direkt via programavsökningar ("är du vid liv"
heartbeats). Prober skickas som direktmeddelanden från silo till silo över samma TCP-sockets som används för regelbunden kommunikation. På så sätt korrelerar avsökningar fullständigt med faktiska nätverksproblem och serverhälsa. Varje silo avsöker en konfigurerbar uppsättning andra silor. En silo väljer vem som ska undersökas genom att beräkna konsekventa hashfunktioner av andra silos identiteter, bildar en virtuell ring av alla identiteter och väljer X efterföljande silor på ringen. (Detta är en välkänd distribuerad teknik som kallas konsekvent hashning och används ofta i många distribuerade hash-tabeller, till exempel Chord DHT).Om en silo S inte tar emot Y-avsökningssvar från en övervakad server P misstänker den P genom att skriva sin tidsstämplade misstanke till P:s rad i
IMembershipTable.Om P har fler än Z misstankar inom K sekunder skriver S att P är avliden i P:s rad och sänder en snabbbild av den aktuella medlemskapstabellen till alla andra silor. Silos uppdaterar tabellen regelbundet, så snapshottet är en optimering för att minska den tid det tar för alla silor att lära sig om den nya medlemskapsvyn.
Mer detaljerat:
Misstanken skrivs till
IMembershipTablei en särskild kolumn i raden som motsvarar P. När S misstänker P, skriver det: "vid tiden TTT misstänkte S P".En misstanke räcker inte för att förklara P död. Du behöver Z-misstankar från olika silor inom ett konfigurerbart tidsfönster T (vanligtvis 3 minuter) för att förklara P död. Misstanken skrivs med optimistisk samtidighetskontroll som tillhandahålls av
IMembershipTable.Den misstänkte siloN läser P:s rad.
Om
Sär den sista misstänkte (det har redan funnits Z-1 misstänkta inom period T, som registrerats i misstankekolumnen), beslutar S att förklara P död. I det här fallet lägger S till sig själv i listan över misstänkta och skriver även i P:s statuskolumn att P är Död.Annars, om S inte är den sista misstänkte, lägger S bara till sig själv i den misstänktes kolumn.
I båda fallen använder tillbakaskrivningen versionsnumret eller ETag som lästes tidigare, och serialiserar uppdateringar till den här raden. Om skrivningen misslyckas på grund av version-/ETag-omatchning försöker S igen (läser igen och försöker skriva, såvida inte P redan har markerats som dött).
På hög nivå är den här sekvensen med "read, local modify, write back" en transaktion. Lagringstransaktioner används dock inte nödvändigtvis. "Transaktionskoden" körs lokalt på en server och optimistisk samtidighet som tillhandahålls av
IMembershipTablegaranterar isolering och atomitet.
Varje silo läser regelbundet hela medlemskapstabellen för sin distribution. På så sätt lär sig silor om nya silor som ansluter sig och om andra silor som förklaras döda.
Sändning av ögonblicksbild: För att minska frekvensen för periodiska tabellläsningar skickar den varje gång en silo skriver till tabellen (misstanke, ny koppling osv.) en ögonblicksbild av det aktuella tabelltillståndet till alla andra silor. Eftersom medlemskapstabellen är konsekvent och monotont versionerad skapar varje uppdatering en unikt version av ögonblicksbilden som kan delas på ett säkert sätt. Detta möjliggör omedelbar spridning av medlemskapsändringar utan att vänta på den periodiska läscykeln. Den periodiska läsningen underhålls fortfarande som en återställningsmekanism om ögonblicksbildsdistributionen misslyckas.
Ordnade medlemskapsvyer: Medlemskapsprotokollet säkerställer att alla medlemskapskonfigurationer är globalt helt ordnade. Den här beställningen ger två viktiga fördelar:
Garanterad anslutning: När en ny silo ansluter till klustret måste den verifiera dubbelriktad anslutning till varannan aktiv silo. Om någon befintlig silo inte svarar (vilket potentiellt indikerar ett problem med nätverksanslutningen) tillåts inte den nya silon ansluta. Detta säkerställer fullständig anslutning mellan alla silor i klustret vid start. Se kommentaren om
IAmAlivenedan för ett undantag i katastrofåterställningsscenarier.Konsekventa kataloguppdateringar: Protokoll på högre nivå, till exempel den distribuerade kornkatalogen, förlitar sig på att alla silor har en konsekvent, monoton vy över medlemskap. Detta möjliggör smartare lösning av duplicerade kornaktiveringar. Mer information finns i grain-katalogdokumentationen .
Detaljer om implementering:
IMembershipTablekräver atomiska uppdateringar för att garantera en global total ändringsordning:- Implementeringar måste uppdatera både tabellposterna (lista över silor) och versionsnumret atomiskt.
- Uppnå detta med hjälp av databastransaktioner (som i SQL Server) eller atomiska jämförelse- och växlingsåtgärder med hjälp av ETags (som i Azure Table Storage).
- Den specifika mekanismen beror på funktionerna i det underliggande lagringssystemet.
En särskild medlemsversionsrad i tabellen spårar ändringar:
- Varje skrivning till tabellen (misstankar, dödsdeklarationer, kopplingar) ökar det här versionsnumret.
- Alla skrivningar serialiseras via den här raden med hjälp av atomiska uppdateringar.
- Den monotont ökande versionen garanterar en total ordning på alla medlemskapsändringar.
När silo S uppdaterar statusen för silo P:
- S läser först det senaste tabelltillståndet.
- I en enda atomisk åtgärd uppdaterar den både P:s rad och ökar versionsnumret.
- Om atomuppdateringen misslyckas (till exempel på grund av samtidiga ändringar), görs ett nytt försök med exponentiell tillbakadragning.
skalbarhetsöverväganden:
Serialisering av alla skrivningar via versionsraden kan påverka skalbarheten på grund av ökad konkurrens. Protokollet har visat sig vara effektivt i produktion med upp till 200 silor men kan möta utmaningar över tusen silor. För mycket stora distributioner förblir andra delar av Orleans (meddelanden, kornkatalog, värd) skalbara även om medlemskapsuppdateringar blir en flaskhals.
Standardkonfiguration: Standardkonfigurationen har handjusterats under produktionsanvändningen i Azure. Som standard: varje silo övervakas av tre andra silor, två misstankar räcker för att förklara en silo död och misstankar beaktas endast från de senaste tre minuterna (annars är de inaktuella). Prober skickas var tionde sekund, och du måste missa tre prober för att du ska misstänka en silo.
Självövervakning: Feldetektorn innehåller idéer från Hashicorps Lifeguard forskning (artikel, föredrag, blogg) för att förbättra klusterstabiliteten under katastrofala händelser där en stor del av klustret drabbas av partiella fel. Komponenten
LocalSiloHealthMonitorpoängsätter varje silos hälsa med hjälp av flera heuristiker:- Aktiv status i medlemskapstabellen
- Inga misstankar från andra silor
- Senaste lyckade provsvar
- Nyligen mottagna avsökningsbegäranden
- Svarstid för trådpool (arbetsuppgifter som utförs inom 1 sekund)
- Timer noggrannhet (aktivering inom 3 sekunder enligt schemat)
En silos hälsopoäng påverkar dess timeouter för avsökning: ohälsosamma silor (poäng 1-8) har ökad timeout jämfört med friska silor (poäng 0). Detta ger två fördelar:
- Ger sonder mer tid att lyckas när nätverket eller systemet är under belastning.
- Gör det mer troligt att ohälsosamma silor röstas döda innan de felaktigt kan rösta ut friska silor.
Detta är särskilt värdefullt i scenarier som en resursbrist i trådpool, där långsamma noder annars felaktigt misstänker friska noder på grund av att de inte kan bearbeta svar tillräckligt snabbt.
Indirekt avsökning: En annan livräddarinspirerad funktion som förbättrar noggrannheten för felidentifiering genom att minska risken för att en felaktig eller partitionerad silo felaktigt bedömer en felfri silo som död. När en övervakningssilo har två sondförsök kvar för en målsilo innan den röstar för att förklara den som död, använder den indirekt sondering.
- Övervakningssilon väljer slumpmässigt en annan silo som mellanhand och ber den att avsöka målet.
- Mellanhanden försöker kontakta målsilon.
- Om målet inte svarar inom tidsgränsen skickar mellanhanden en negativ bekräftelse.
- Om övervakningssilon får en negativ bekräftelse från mellanhanden, och mellanhanden förklarar sig i gott skick (genom självövervakning, som beskrivs ovan), röstar övervakningssilon för att förklara målet som dött.
- Med standardkonfigurationen av två obligatoriska röster räknas en negativ bekräftelse från en indirekt avsökning som båda rösterna, vilket möjliggör snabbare deklaration av döda silor när flera perspektiv bekräftar felet.
Tillämpa perfekt felidentifiering: När en silo har förklarats död i tabellen anser alla att den är död, även om den inte är riktigt död (t.ex. bara tillfälligt partitionerad eller hjärtslagsmeddelanden försvann). Alla slutar kommunicera med den. När silon får reda på att den är död (genom att läsa dess nya status från tabellen) avslutas processen. Därför måste en infrastruktur finnas på plats för att starta om silon som en ny process (ett nytt epoknummer genereras vid start). När det är värdat i Azure sker detta automatiskt. Annars krävs en annan infrastruktur, till exempel en Windows-tjänst som konfigurerats för automatisk omstart vid fel eller en Kubernetes-distribution.
Vad händer om tabellen inte är tillgänglig under en tid:
När lagringstjänsten är avstängd, otillgänglig eller har kommunikationsproblem deklarerar Orleans protokollet INTE av misstag silor döda. Operativa avdelningar fortsätter att fungera utan problem. Orleans kommer dock inte att kunna deklarera en silo som död (om den upptäcker en död silo via missade sondningar, kan den inte skriva in detta faktum i tabellen) och kommer inte att kunna tillåta nya silor att ansluta. Så fullständigheten lider, men noggrannheten gör det inte – partitioneringen från tabellen får aldrig Orleans att av misstag förklara en silo som död. Också i en partiell nätverkspartition (där vissa silor kan komma åt tabellen och andra inte kan) kan Orleans deklarera en silo död, men det tar tid för alla andra silor att få reda på det. Identifieringen kan fördröjas, men Orleans dödar aldrig en silo felaktigt på grund av att tabellen inte är tillgänglig.
IAmAliveskriver för diagnostik och katastrofåterställningFörutom pulsslag som skickas mellan silor uppdaterar varje silo regelbundet en "I Am Alive"-tidsstämpel i sin tabellrad. Detta har två syften:
Diagnostik: Ger systemadministratörer ett enkelt sätt att kontrollera klustrets liveness och avgöra när en silo senast var aktiv. Tidsstämpeln uppdateras som standard var 30:e sekund.
Katastrofåterställning: Om en silo inte har uppdaterat sin tidsstämpel under flera perioder (konfigurerad via
NumMissedTableIAmAliveLimit, standard: 3), ignorerar nya silor den under anslutningskontroller vid start. Detta gör att klustret kan återställas från scenarier där silor kraschade utan korrekt rensning.
Medlemskapstabell
Som nämnts, IMembershipTable fungerar som en mötesplats för silor för att hitta varandra och för Orleans klienter att hitta silor. Det hjälper också till att samordna överenskommelsen om medlemskapssynen. Huvudlagringsplatsen Orleans innehåller implementeringar för många system, inklusive Azure Table Storage, Azure Cosmos DB, PostgreSQL, MySQL/MariaDB, SQL Server, Apache ZooKeeper, Consul IO, Apache Cassandra, MongoDB, Redis, AWS DynamoDB och en minnesintern implementering för utveckling.
Azure Table Storage: I den här implementeringen fungerar Azure-distributions-ID:t som partitionsnyckel och siloidentiteten (
ip:port:epoch) fungerar som radnyckel. Tillsammans garanterar de en unik nyckel per silo. För samtidighetskontroll används optimistisk samtidighetskontroll baserat på Azure Table ETags . Varje gång data läses från tabellen lagras ETag för varje läst rad och används när man försöker skriva tillbaka. Azure Table-tjänsten tilldelar och kontrollerar automatiskt ETags vid varje skrivning. För transaktioner med flera rader används stödet för batchtransaktioner som tillhandahålls av Azure Table , vilket garanterar serialiserbara transaktioner över rader med samma partitionsnyckel.SQL Server: I den här implementeringen skiljer det konfigurerade distributions-ID:t mellan distributioner och vilka silor som tillhör vilka distributioner. Siloidentiteten definieras som en kombination av
deploymentID, ip, port, epochi lämpliga tabeller och kolumner. Relationsserverdelen använder optimistisk samtidighetskontroll och transaktioner, ungefär som att använda ETags i Azure Table-implementeringen. Relationsimplementeringen förväntar sig att databasmotorn genererar ETag. För SQL Server 2000 hämtas den genererade ETag från ett anrop tillNEWID(). På SQL Server 2005 och senare används ROWVERSION . Orleans läser och skriver relations-ETags som ogenomskinligaVARBINARY(16)taggar och lagrar dem i minnet som base64-kodade strängar. Orleans stöder infogningar med flera rader med hjälp avUNION ALL(för Oracle, inklusiveDUAL), som för närvarande används för att infoga statistikdata. Den exakta implementeringen och logiken för SQL Server finns på CreateOrleansTables_SqlServer.sql.Apache ZooKeeper: I den här implementeringen används det konfigurerade distributions-ID:t som en rotnod och siloidentiteten (
ip:port@epoch) som dess underordnade nod. Tillsammans garanterar de en unik väg för varje silo. För samtidighetskontroll används optimistisk samtidighetskontroll baserat på nodversionen . Varje gång data läses från distributionsrotnoden lagras och används versionen för varje läst underordnad silonod när man försöker skriva tillbaka. Varje gång en nods data ändras ökar ZooKeeper-tjänsten versionsnumret atomiskt. För transaktioner med flera rader används multimetoden , vilket garanterar serialiserbara transaktioner över silonoder med samma överordnade distributions-ID-nod.Consul IO: Consuls nyckel-/värdearkiv användes för att implementera medlemstabellen. Mer information finns i Konsuldistribution .
AWS DynamoDB: I den här implementeringen används klusterdistributions-ID:t som partitionsnyckel och Silo-identitet (
ip-port-generation) som RangeKey, vilket gör posten unik. Optimistisk samtidighet uppnås med hjälpETagav attributet genom att göra villkorsstyrda skrivningar på DynamoDB. Implementeringslogik liknar Azure Table Storage.Apache Cassandra: I den här implementeringen fungerar kompositen av tjänst-ID och kluster-ID som partitionsnyckel och siloidentiteten (
ip:port:epoch) som radnyckel. Tillsammans garanterar de en unik rad per silo. För samtidighetskontroll används optimistisk samtidighetskontroll baserat på en statisk kolumnversion med hjälp av en Lightweight Transaction. Den här versionskolumnen delas för alla rader i partitionen/klustret, vilket ger ett konsekvent inkrementellt versionsnummer för varje klusters medlemskapstabell. Det finns inga transaktioner med flera rader i den här implementeringen.Minnesintern emulering för utvecklingskonfiguration: Ett särskilt systemkorn används för den här implementeringen. Det här kornet finns på en utsedd primär silo, som endast används för en utvecklingskonfiguration. Vid verklig produktionsanvändning krävs ingen primär silo.
Designbakgrund
En naturlig fråga kan vara varför inte helt förlita sig på Apache ZooKeeper eller etcd för implementeringen av klustermedlemskap, eventuellt med hjälp av ZooKeepers färdiga stöd för gruppmedlemskap med tillfälliga noder? Varför implementera vårt medlemskapsprotokoll? Det fanns främst tre orsaker:
Distribution/värd i molnet:
Zookeeper är inte en värdbaserad tjänst. Det innebär att kunderna i en molnmiljö Orleans måste distribuera, köra och hantera sin instans av ett ZK-kluster. Detta är en onödig börda som inte tvingades på kunderna. Genom att använda Azure Table Orleans förlitar du dig på en värdbaserad, hanterad tjänst, vilket gör kundernas liv mycket enklare. I grund och botten använder du molnet som en plattform, inte infrastruktur i molnet. Å andra sidan, när du kör lokalt och hanterar dina servrar, är det ett genomförbart alternativ att förlita sig på ZK som en implementering av
IMembershipTable.Direkt funktionsfelsdetektering:
När du använder ZK:s gruppmedlemskap med tillfälliga noder sker detektering av fel mellan servrarna (ZK-klienterna) Orleans och ZK-servrarna. Detta kanske inte nödvändigtvis korrelerar med faktiska nätverksproblem mellan Orleans servrar. Önskan var att felidentifieringen korrekt återspeglar kommunikationens intraklustertillstånd. Mer specifikt, i den här designen, om en Orleans silo inte kan kommunicera med
IMembershipTable, anses den inte vara död och kan fortsätta att fungera. Om ZK-gruppmedlemskap med tillfälliga noder däremot användes kan en frånkoppling från en ZK-server leda till att en Orleans silo (ZK-klient) förklaras död, medan den kan vara aktiv och fullt fungerande.Portabilitet och flexibilitet:
Som en del av Orleansfilosofin tvingar Orleans inte ett starkt beroende av någon viss teknik utan ger snarare en flexibel design där olika komponenter enkelt kan växlas med olika implementeringar. Det här är precis det syfte som abstraktionen
IMembershipTabletjänar.
Egenskaper för medlemskapsprotokollet
Kan hantera valfritt antal fel:
Den här algoritmen kan hantera valfritt antal fel (f<=n), inklusive fullständig omstart av klustret. Detta står i kontrast till "traditionella" Paxos-baserade lösningar, som kräver ett kvorum (vanligtvis en majoritet). Produktionssituationer har visat scenarier där mer än hälften av silorna inte fungerade. Det här systemet förblev funktionellt, medan Paxos-baserat medlemskap inte skulle kunna göra framsteg.
Det är mycket lite trafik till tabellen:
Verkliga sonder går direkt mellan servrar, inte till tabellen. Routning av sonder genom tabellen skulle generera betydande trafik och vara mindre exakt ur ett perspektiv av felidentifiering – om en silo inte kunde nå tabellen skulle den missa att skriva dess 'Jag lever'-signal och andra system skulle förklara den död.
Justerbar noggrannhet jämfört med fullständighet:
Även om du inte kan uppnå både perfekt och exakt feldetektion, vill du vanligtvis ha förmågan att balansera noggrannhet (att inte vilja förklara en levande silo död) med fullständighet (att kunna förklara en död silo död så snart som möjligt). De konfigurerbara rösterna för att deklarera döda och missade avsökningar tillåter handel med dessa två aspekter. Mer information finns i Yale University: Computer Science Failure Detectors.
Skala:
Protokollet kan hantera tusentals, förmodligen till och med tiotusentals, servrar. Detta står i kontrast till traditionella Paxos-baserade lösningar, till exempel gruppkommunikationsprotokoll, som är kända för att inte skala bortom tiotals noder.
Diagnostik:
Tabellen är också mycket praktisk för diagnostik och felsökning. Systemadministratörer kan omedelbart hitta den aktuella listan över levande silor i tabellen, samt se historien om alla dödade silor och misstankar. Detta är särskilt användbart när du diagnostiserar problem.
Varför behövs tillförlitlig beständig lagring för implementeringen av
IMembershipTable:Permanent lagring används för
IMembershipTabletvå ändamål. För det första fungerar det som en mötespunkt där silor kan hitta varandra och där Orleans klienter kan hitta silor. För det andra hjälper tillförlitlig lagring till att samordna avtal om medlemskapssynen. Felidentifiering sker direkt peer-to-peer mellan silor, men medlemskapsvyn lagras i tillförlitlig lagring och mekanismen för samtidighetskontroll som tillhandahålls av den här lagringen används för att nå en överenskommelse om vem som lever och vem som är död. På sätt och vis outsourcar det här protokollet det svåra problemet med distribuerad konsensus till molnet. På så sätt används den underliggande molnplattformens fulla kraft och använder den verkligen som PaaS (Platform as a Service).IAmAlive:Förutom pulsslag som skickas mellan silor uppdaterar varje silo också regelbundet en "I Am Alive"-kolumn i sin tabellrad. Den här kolumnen "I Am Alive" används endast för manuell felsökning och diagnostik och används inte av själva medlemskapsprotokollet. Det skrivs vanligtvis med mycket lägre frekvens (en gång var 5:e minut) och fungerar som ett mycket användbart verktyg för systemadministratörer för att kontrollera klustrets liv eller enkelt ta reda på när silon senast levde.
Erkännanden
Bekräftelser för Alex Kogans bidrag till utformningen och implementeringen av den första versionen av det här protokollet. Detta arbete gjordes som en del av en sommarpraktik i Microsoft Research sommaren 2011.
Implementeringen av ZooKeeper baserad IMembershipTable gjordes av Shay Hazor, implementeringen av SQL IMembershipTable gjordes av Veikko Eeva, implementeringen av AWS DynamoDB IMembershipTable gjordes av Gutemberg Ribeiro, implementeringen av Consul based IMembershipTable gjordes av Paul North, och slutligen var genomförandet av Apache Cassandra IMembershipTable anpassat från OrleansCassandraUtilsArshia001.