Een grondige introductie van gedistribueerde systemen

Wat is een gedistribueerd systeem en waarom is het zo ingewikkeld?

Een beer die gedistribueerde systemen overweegt

Inhoudsopgave

Invoering

  1. Wat is een gedistribueerd systeem?
  2. Waarom een ​​systeem distribueren?
  3. Voorbeeld van database schaling
  4. Gedecentraliseerd versus gedistribueerd

Gedistribueerde systeemcategorieën

  1. Gedistribueerde gegevensopslag
  2. Gedistribueerde informatica
  3. Gedistribueerde bestandssystemen
  4. Gedistribueerde berichten
  5. Gedistribueerde applicaties
  6. Gedistribueerde grootboeken

Samenvatting

Invoering

Met de steeds groeiende technologische expansie van de wereld, worden gedistribueerde systemen steeds meer verspreid. Ze zijn een enorm en complex vakgebied in de informatica.

Dit artikel heeft als doel u op een eenvoudige manier kennis te laten maken met gedistribueerde systemen en laat u een glimp zien van de verschillende categorieën van dergelijke systemen terwijl u niet diep in de details duikt.

Wat is een gedistribueerd systeem?

Een gedistribueerd systeem in zijn meest eenvoudige definitie is een groep computers die samenwerken om voor de eindgebruiker als een enkele computer te verschijnen.

Deze machines hebben een gedeelde status, werken gelijktijdig en kunnen onafhankelijk van elkaar falen zonder de uptime van het hele systeem te beïnvloeden.

Ik stel voor dat we stapsgewijs een voorbeeld van het distribueren van een systeem doornemen, zodat u alles beter kunt begrijpen:

Een traditionele stapel

Laten we gaan met een database! Traditionele databases worden opgeslagen op het bestandssysteem van één enkele machine, wanneer u er informatie in wilt halen / invoegen - u praat rechtstreeks met die machine.

Als we dit databasesysteem willen distribueren, moeten we deze database tegelijkertijd op meerdere machines laten draaien. De gebruiker moet kunnen praten met de machine die hij kiest en mag niet weten dat hij niet tegen een enkele machine praat - als hij een record in knooppunt 1 invoegt, moet knooppunt # 3 dat record kunnen retourneren.

Een architectuur die als verdeeld kan worden beschouwd

Waarom een ​​systeem distribueren?

Systemen worden altijd door noodzaak gedistribueerd. De waarheid is dat het beheren van gedistribueerde systemen een complex onderwerp is vol valkuilen en landmijnen. Het is een hoofdpijn om gedistribueerde systemen te implementeren, te onderhouden en te debuggen, dus waarom zou je daar helemaal niet heen gaan?

Wat u met een gedistribueerd systeem kunt doen, is horizontaal schalen. Terugkerend naar ons vorige voorbeeld van de enkele databaseserver, zou de enige manier om meer verkeer af te handelen, zijn de hardware waarop de database draait te upgraden. Dit wordt verticaal schalen genoemd.

Verticaal schalen is allemaal goed en wel zolang je kunt, maar na een bepaald punt zul je zien dat zelfs de beste hardware niet voldoende is voor voldoende verkeer, en niet te vergeten onpraktisch om te hosten.

Horizontaal schalen betekent eenvoudigweg meer computers toevoegen in plaats van de hardware van één computer te upgraden.

Horizontaal schalen wordt na een bepaalde drempel veel goedkoper

Het is aanzienlijk goedkoper dan verticale schaal na een bepaalde drempel, maar dat is niet het belangrijkste geval voor voorkeur.

Verticale schaling kan uw prestaties alleen maar verhogen tot de nieuwste hardwaremogelijkheden. Deze mogelijkheden blijken onvoldoende voor technologische bedrijven met matige tot grote werklasten.

Het beste van horizontaal schalen is dat u niet weet hoeveel u kunt schalen - wanneer de prestaties achteruitgaan, voegt u gewoon een andere machine toe, tot in het oneindige potentieel.

Eenvoudig schalen is niet het enige voordeel dat u krijgt van gedistribueerde systemen. Fouttolerantie en lage latentie zijn ook even belangrijk.

Fouttolerantie - een cluster van tien machines in twee datacenters is inherent fouttoleranter dan een enkele machine. Zelfs als een datacenter in brand vliegt, zou uw applicatie nog steeds werken.

Lage latentie - De tijd voor een netwerkpakket om de wereld rond te reizen, wordt fysiek begrensd door de snelheid van het licht. De kortst mogelijke tijd voor de retourtijd van een aanvraag (dat wil zeggen heen en weer) in een glasvezelkabel tussen New York en Sydney is 160 ms. Gedistribueerde systemen stellen u in staat om een ​​knooppunt in beide steden te hebben, waardoor verkeer het knooppunt het dichtst in de buurt raakt.

Om een ​​gedistribueerd systeem te laten werken, moet de software die op die machines wordt uitgevoerd, echter specifiek zijn ontworpen om op meerdere computers tegelijk te worden uitgevoerd en de bijbehorende problemen aan te pakken. Dit blijkt geen gemakkelijke prestatie te zijn.

Schaal onze database

Stel je voor dat onze webapplicatie waanzinnig populair werd. Stel je ook voor dat onze database twee keer zoveel zoekopdrachten per seconde begon te krijgen als het aankan. Uw toepassing zou onmiddellijk beginnen af ​​te nemen in prestaties en dit zou opgemerkt worden door uw gebruikers.

Laten we samenwerken en onze database opschalen om aan onze hoge eisen te voldoen.

In een typische webapplicatie leest u normaal gesproken veel vaker informatie dan dat u nieuwe informatie invoegt of oude wijzigt.

Er is een manier om de leesprestaties te verbeteren en dat is door de zogenaamde Master-Slave-replicatiestrategie. Hier maakt u twee nieuwe databaseservers die synchroniseren met de hoofdservers. De vangst is dat je alleen van deze nieuwe exemplaren kunt lezen.

Wanneer u informatie invoegt of wijzigt, praat u met de hoofddatabase. Het op zijn beurt informeert de slaven asynchroon over de verandering en zij slaan het ook op.

Gefeliciteerd, u kunt nu 3x zoveel leesvragen uitvoeren! Is dit niet geweldig?

Valkuil

Gotcha! We verloren meteen de C in de ACID-garanties van onze relationele database, wat staat voor Consistentie.

U ziet, er bestaat nu een mogelijkheid waarin we een nieuw record in de database invoegen, er onmiddellijk daarna een leesquery voor uitvoeren en niets terugkrijgen, alsof het niet bestond!

Het doorgeven van de nieuwe informatie van de meester aan de slaaf gebeurt niet onmiddellijk. Er bestaat eigenlijk een tijdvenster waarin u oude informatie kunt ophalen. Als dit niet het geval zou zijn, zou uw schrijfprestatie lijden, omdat deze synchroon zou moeten wachten tot de gegevens werden verspreid.

Gedistribueerde systemen worden geleverd met een handvol afwegingen. Met dit specifieke probleem moet je leven, als je voldoende wilt schalen.

Doorgaan met schalen

Met de slave-databasebenadering kunnen we ons leesverkeer tot op zekere hoogte horizontaal schalen. Dat is geweldig, maar we hebben een muur geraakt met betrekking tot ons schrijfverkeer - het is nog steeds allemaal in één server!

We hebben hier niet veel opties. We moeten gewoon ons schrijfverkeer opsplitsen in meerdere servers, omdat dit niet mogelijk is.

Eén manier is om te kiezen voor een multi-master replicatiestrategie. Daar, in plaats van slaves waar je alleen van kunt lezen, heb je meerdere hoofdknooppunten die lezen en schrijven ondersteunen. Helaas wordt dit heel snel ingewikkeld omdat je nu de mogelijkheid hebt om conflicten te creëren (bijv. Twee records met dezelfde ID invoegen).

Laten we gaan met een andere techniek genaamd sharding (ook partitionering genoemd).

Met sharding splitst u uw server in meerdere kleinere servers, shards genaamd. Deze scherven bevatten allemaal verschillende records - je maakt een regel over wat voor soort records in welke scherf gaan. Het is heel belangrijk om de regel zo te maken dat de gegevens op een uniforme manier worden verspreid.

Een mogelijke benadering hiervoor is om bereiken te definiëren op basis van enige informatie over een record (bijvoorbeeld gebruikers met de naam A-D).

Deze scherfsleutel moet zeer zorgvuldig worden gekozen, omdat de belasting niet altijd gelijk is op basis van willekeurige kolommen. (bijv. meer mensen hebben een naam die begint met C in plaats van Z). Een enkele scherf die meer aanvragen ontvangt dan andere, wordt een hotspot genoemd en moet worden vermeden. Eenmaal opgesplitst, wordt het opnieuw sharding van gegevens ongelooflijk duur en kan dit aanzienlijke downtime veroorzaken, zoals het geval was met de beruchte 11 uur uitval van FourSquare.

Om ons voorbeeld eenvoudig te houden, neem aan dat onze klant (de Rails-app) weet welke database hij voor elk record moet gebruiken. Het is ook vermeldenswaard dat er veel strategieën zijn om te scherpen en dit is een eenvoudig voorbeeld om het concept te illustreren.

We hebben nu behoorlijk veel gewonnen - we kunnen ons schrijfverkeer N keer vergroten, waarbij N het aantal scherven is. Dit geeft ons praktisch bijna geen limiet - stel je voor hoe fijnkorrelig we kunnen krijgen met deze partitionering.

Valkuil

Alles in Software Engineering is min of meer een afweging en dit is geen uitzondering. Scherf is geen eenvoudige prestatie en kan het beste worden vermeden totdat het echt nodig is.

We hebben nu query's uitgevoerd met andere sleutels dan de gepartitioneerde sleutel, ongelooflijk inefficiënt (ze moeten door alle scherven gaan). SQL JOIN-vragen zijn nog erger en complexe vragen worden praktisch onbruikbaar.

Gedecentraliseerd versus gedistribueerd

Voordat we verder gaan, wil ik een onderscheid maken tussen de twee termen.

Hoewel de woorden op elkaar lijken en kunnen worden geconcludeerd dat ze logisch hetzelfde betekenen, heeft hun verschil een aanzienlijke technologische en politieke impact.

Gedecentraliseerd wordt nog steeds in technische zin gedistribueerd, maar het hele gedecentraliseerde systeem is niet het eigendom van één actor. Geen enkel bedrijf kan een gedecentraliseerd systeem bezitten, anders zou het niet meer gedecentraliseerd zijn.

Dit betekent dat de meeste systemen die we vandaag zullen bespreken, kunnen worden gezien als gedistribueerde gecentraliseerde systemen - en dat is wat ze zijn gemaakt.

Als je erover nadenkt, is het moeilijker om een ​​gedecentraliseerd systeem te maken, want dan moet je de zaak aanpakken waarin sommige deelnemers kwaadaardig zijn. Dit is niet het geval met normale gedistribueerde systemen, omdat u weet dat u alle knooppunten bezit.

Opmerking: over deze definitie is veel gedebatteerd en kan worden verward met anderen (peer-to-peer, federatief). In de vroege literatuur is het ook anders gedefinieerd. Hoe dan ook, wat ik je als definitie gaf, is wat ik voel dat het meest wordt gebruikt nu blockchain en cryptocurrencies de term populair maakten.

Gedistribueerde systeemcategorieën

We gaan nu door een aantal gedistribueerde systeemcategorieën en vermelden hun grootste publiek bekende productiegebruik. Houd er rekening mee dat de meeste getoonde cijfers verouderd zijn en waarschijnlijk aanzienlijk groter zijn vanaf het moment dat u dit leest.

Gedistribueerde gegevensopslag

Gedistribueerde datastores worden het meest gebruikt en erkend als gedistribueerde databases. De meeste gedistribueerde databases zijn NoSQL niet-relationele databases, beperkt tot sleutel-waarde semantiek. Ze bieden ongelooflijke prestaties en schaalbaarheid ten koste van consistentie of beschikbaarheid.

Bekende schaal - het is bekend dat Apple in 2015 75.000 Apache Cassandra-knooppunten gebruikt die meer dan 10 petabytes aan gegevens opslaan

We kunnen niet in discussie gaan over gedistribueerde datastores zonder eerst de CAP-stelling te introduceren.

CAP-stelling

Bewezen in 2002, stelt de CAP-stelling dat een gedistribueerde gegevensopslag niet tegelijkertijd consistent, beschikbaar en partitietolerant kan zijn.

Kies 2 van de 3 (maar niet consistentie en beschikbaarheid)

Enkele snelle definities:

  • Consistentie - Wat u achtereenvolgens leest en schrijft, wordt verwacht (onthoudt de gotcha met de databasereplicatie enkele alinea's geleden?)
  • Beschikbaarheid - het hele systeem gaat niet dood - elk niet-falend knooppunt retourneert altijd een reactie.
  • Verdeling van partities - Het systeem blijft functioneren en behoudt zijn consistentie / beschikbaarheid garanties ondanks netwerkpartities

In werkelijkheid moet partitietolerantie een gegeven zijn voor elke gedistribueerde gegevensopslag. Zoals op veel plaatsen vermeld, waaronder dit geweldige artikel, kun je geen consistentie en beschikbaarheid hebben zonder partitietolerantie.

Denk er eens over na: als je twee knooppunten hebt die informatie accepteren en hun verbinding sterft - hoe zullen ze dan allebei beschikbaar zijn en je tegelijkertijd consistentie bieden? Ze hebben geen manier om te weten wat het andere knooppunt doet en kunnen als zodanig offline worden (niet beschikbaar) of werken met oude informatie (inconsistent).

Wat doen we?

Uiteindelijk moet u kiezen of u wilt dat uw systeem sterk consistent of zeer beschikbaar is onder een netwerkpartitie.

De praktijk leert dat de meeste applicaties meer waarde hechten aan beschikbaarheid. U hoeft niet altijd een sterke consistentie te hebben. Zelfs dan is die afweging niet noodzakelijkerwijs gemaakt omdat u de 100% beschikbaarheidsgarantie nodig hebt, maar eerder omdat netwerklatentie een probleem kan zijn bij het synchroniseren van machines om een ​​sterke consistentie te bereiken. Deze en meer factoren zorgen ervoor dat applicaties meestal kiezen voor oplossingen die een hoge beschikbaarheid bieden.

Zulke databases worden genesteld met het zwakste consistentiemodel - uiteindelijke consistentie (verklaring van sterke versus uiteindelijke consistentie). Dit model garandeert dat als er geen nieuwe updates voor een bepaald item worden gemaakt, uiteindelijk alle toegangen tot dat item de laatst bijgewerkte waarde zullen retourneren.

Die systemen bieden BASE-eigenschappen (in tegenstelling tot traditionele ACID van databases)

  • In principe beschikbaar - het systeem retourneert altijd een reactie
  • Zachte status - Het systeem kan in de loop van de tijd veranderen, zelfs wanneer er geen invoer is (vanwege eventuele consistentie)
  • Eventuele consistentie - Bij afwezigheid van invoer zullen de gegevens zich vroeg of laat verspreiden naar elk knooppunt - en dus consistent worden

Voorbeelden van dergelijke beschikbare gedistribueerde databases - Cassandra, Riak, Voldemort

Natuurlijk zijn er andere datastores die de voorkeur geven aan een sterkere consistentie - HBase, Couchbase, Redis, Zookeeper

De CAP-stelling is op zichzelf al meerdere artikelen waard - sommige over hoe u de CAP-eigenschappen van een systeem kunt aanpassen, afhankelijk van hoe de client zich gedraagt ​​en andere over hoe het niet goed wordt begrepen.

Cassandra

Cassandra, zoals hierboven vermeld, is een gedistribueerde No-SQL-database die de AP-eigenschappen prefereert buiten het CAP, met een constante consistentie. Ik moet toegeven dat dit misschien een beetje misleidend is, omdat Cassandra zeer configureerbaar is - je kunt het ook zorgen voor een sterke consistentie ten koste van de beschikbaarheid, maar dat is niet het gebruikelijke gebruik.

Cassandra gebruikt consistente hashing om te bepalen welke knooppunten uit uw cluster de gegevens moeten beheren die u doorgeeft. U stelt een replicatiefactor in, die in principe aangeeft hoeveel knooppunten u uw gegevens wilt repliceren.

Voorbeeld schrijven

Tijdens het lezen leest u alleen van die knooppunten.

Cassandra is enorm schaalbaar en biedt een absurd hoge schrijfdoorvoer.

Mogelijk bevooroordeeld diagram, met benchmarks per seconde. Vanaf hier genomen.

Hoewel dit diagram misschien bevooroordeeld is en het lijkt erop dat het Cassandra vergelijkt met databases die zijn ingesteld om een ​​sterke consistentie te bieden (anders kan ik niet zien waarom MongoDB de prestaties zou verlagen wanneer een upgrade van 4 naar 8 knooppunten wordt uitgevoerd), zou dit toch moeten laten zien wat een correct ingestelde Cassandra cluster is in staat.

Hoe dan ook, in de wisselwerking tussen gedistribueerde systemen die horizontale schaling en een ongelooflijk hoge doorvoer mogelijk maakt, biedt Cassandra geen enkele fundamentele functies van ACID-databases - namelijk transacties.

overeenstemming

Databasetransacties zijn lastig te implementeren in gedistribueerde systemen omdat ze vereisen dat elk knooppunt overeenstemming bereikt over de juiste actie (afbreken of vastleggen). Dit staat bekend als consensus en het is een fundamenteel probleem in gedistribueerde systemen.

Het bereiken van het type overeenkomst dat nodig is voor het probleem van de 'transactie-commit' is eenvoudig als de deelnemende processen en het netwerk volledig betrouwbaar zijn. Echte systemen zijn echter onderhevig aan een aantal mogelijke fouten, zoals procescrashes, netwerkpartitionering en verloren, vervormde of dubbele berichten.

Dit levert een probleem op - het is onmogelijk gebleken te garanderen dat binnen een beperkt tijdsbestek op een niet-betrouwbaar netwerk een juiste consensus wordt bereikt.

In de praktijk zijn er echter algoritmen die vrij snel overeenstemming bereiken over een niet-betrouwbaar netwerk. Cassandra biedt eigenlijk lichtgewicht transacties door het gebruik van het Paxos-algoritme voor verdeelde consensus.

Gedistribueerde informatica

Gedistribueerd computergebruik is de sleutel tot de instroom van Big Data-verwerking die we de afgelopen jaren hebben gezien. Het is de techniek van het splitsen van een enorme taak (bijv. 100 miljard records samengevoegd), waarvan geen enkele computer in staat is om praktisch zelfstandig te werken, in veel kleinere taken, die elk in een enkele commodity-machine passen. U splitst uw enorme taak op in veel kleinere, laat ze op veel machines parallel uitvoeren, de gegevens op de juiste manier samenvoegen en u hebt uw eerste probleem opgelost. Met deze benadering kunt u weer horizontaal schalen - neem bij een grotere taak eenvoudigweg meer knooppunten mee in de berekening.

Bekende schaal - Folding @ Home had 160k actieve machines in 2012

Een vroege innovator op dit gebied was Google, dat vanwege de grote hoeveelheid gegevens een nieuw paradigma voor gedistribueerde berekening moest uitvinden: MapReduce. Ze publiceerden er in 2004 een artikel over en later creëerde de open source-gemeenschap daarop Apache Hadoop.

MapReduce

MapReduce kan eenvoudig worden gedefinieerd als twee stappen - het in kaart brengen van de gegevens en het terugbrengen tot iets zinvols.

Laten we het nog eens met een voorbeeld bekijken:

Stel dat we medium zijn en onze enorme informatie hebben opgeslagen in een secundaire gedistribueerde database voor opslagdoeleinden. We willen gegevens ophalen van het aantal claps dat elke dag in april 2017 (een jaar geleden) wordt uitgegeven.

Dit voorbeeld wordt zo kort, duidelijk en eenvoudig mogelijk gehouden, maar stel je voor dat we met heel veel gegevens werken (bijvoorbeeld miljarden claps analyseren). We slaan al deze informatie natuurlijk niet op één machine op en we analyseren dit allemaal niet met slechts één machine. We zullen ook geen query's uitvoeren op de productiedatabase, maar eerder op een 'magazijn'-database die speciaal is gebouwd voor offline taken met lage prioriteit.

Elke kaarttaak is een afzonderlijk knooppunt dat zoveel mogelijk gegevens omzet. Elke taak doorloopt alle gegevens in het gegeven opslagknooppunt en wijst deze toe aan een eenvoudige tuple van de datum en de nummer één. Vervolgens worden drie tussenstappen (waarover niemand spreekt) gedaan - Shuffle, Sort en Partition. Ze rangschikken de gegevens in principe verder en verwijderen deze naar de juiste verkleinopdracht. Omdat we te maken hebben met big data, hebben we elke taak verkleinen gescheiden om op slechts één datum te werken.

Dit is een goed paradigma en stelt u verrassend in staat om er veel mee te doen - u kunt bijvoorbeeld meerdere MapReduce-taken koppelen.

Betere technieken

MapReduce is tegenwoordig enigszins verouderd en brengt een aantal problemen met zich mee. Omdat het in batches (taken) werkt, ontstaat er een probleem waarbij als uw taak mislukt - u de hele zaak opnieuw moet starten. Het mislukken van een taak van 2 uur kan uw hele gegevensverwerkingspijplijn echt vertragen en dat wilt u niet in het minst, vooral tijdens piekuren.

Een ander probleem is de tijd die je wacht totdat je resultaten ontvangt. In realtime analysesystemen (die allemaal big data hebben en dus gedistribueerd computergebruik gebruiken) is het belangrijk dat uw nieuwste gegevens zo vers mogelijk zijn en zeker niet een paar uur geleden.

Als zodanig zijn er andere architecturen ontstaan ​​die deze problemen aanpakken. Namelijk Lambda Architecture (mix van batchverwerking en streamverwerking) en Kappa Architecture (alleen streamverwerking). Deze vooruitgang in het veld heeft nieuwe tools opgeleverd die hen in staat stellen - Kafka Streams, Apache Spark, Apache Storm, Apache Samza.

Gedistribueerde bestandssystemen

Gedistribueerde bestandssystemen kunnen worden beschouwd als gedistribueerde datastores. Ze zijn hetzelfde als een concept - het opslaan en openen van een grote hoeveelheid gegevens op een cluster van machines die allemaal als één worden weergegeven. Ze gaan meestal hand in hand met Distributed Computing.

Bekende schaal - Yahoo staat erom bekend HDFS op meer dan 42.000 knooppunten te gebruiken voor opslag van 600 Petabytes aan gegevens, ver terug in 2011

Wikipedia definieert het verschil dat gedistribueerde bestandssystemen toegang geven tot bestanden met dezelfde interfaces en semantiek als lokale bestanden, niet via een aangepaste API zoals de Cassandra Query Language (CQL).

HDFS

Hadoop Distributed File System (HDFS) is het gedistribueerde bestandssysteem dat wordt gebruikt voor gedistribueerde computing via het Hadoop-framework. Met een brede acceptatie, wordt het gebruikt om grote bestanden (GB of TB in grootte) op te slaan en te repliceren op vele machines.

De architectuur bestaat voornamelijk uit NameNodes en DataNodes. NameNodes zijn verantwoordelijk voor het bijhouden van metagegevens over het cluster, zoals welk knooppunt welke bestandsblokken bevat. Ze fungeren als coördinatoren voor het netwerk door uit te zoeken waar bestanden het beste kunnen worden opgeslagen en gerepliceerd, waarbij de gezondheid van het systeem wordt gevolgd. DataNodes slaan eenvoudig bestanden op en voeren commando's uit, zoals het repliceren van een bestand, het schrijven van een nieuw bestand en andere.

Het is niet verwonderlijk dat HDFS het best wordt gebruikt met Hadoop voor berekeningen, omdat het gegevensbewustzijn biedt voor de berekeningstaken. Deze taken worden vervolgens uitgevoerd op de knooppunten die de gegevens opslaan. Dit maakt gebruik van gegevenslocatie - optimaliseert berekeningen en vermindert de hoeveelheid verkeer via het netwerk.

IPFs

Interplanetary File System (IPFS) is een opwindend nieuw peer-to-peer protocol / netwerk voor een gedistribueerd bestandssysteem. Gebruikmakend van Blockchain-technologie, beschikt het over een volledig gedecentraliseerde architectuur zonder enige eigenaar of faalpunt.

IPFS biedt een naamsysteem (vergelijkbaar met DNS) genaamd IPNS en geeft gebruikers gemakkelijk toegang tot informatie. Het slaat bestanden op via historische versiebeheer, vergelijkbaar met Git. Hiermee hebt u toegang tot alle vorige statussen van een bestand.

Het is nog steeds zwaar in ontwikkeling (v0.4 op het moment van schrijven) maar heeft al projecten gezien die er overheen willen bouwen (FileCoin).

Gedistribueerde berichten

Berichtensystemen bieden een centrale plaats voor opslag en verspreiding van berichten / gebeurtenissen binnen uw algehele systeem. Hiermee kunt u uw applicatielogica ontkoppelen van direct praten met uw andere systemen.

Bekende schaal - LinkedIn's Kafka-cluster verwerkte dagelijks 1 biljoen berichten met pieken van 4,5 miljoen berichten per seconde.

Simpel gezegd, een berichtenplatform werkt op de volgende manier:

Een bericht wordt uitgezonden vanuit de toepassing die het mogelijk maakt (een producent genoemd), gaat het platform in en wordt gelezen door mogelijk meerdere toepassingen die erin geïnteresseerd zijn (consumenten genoemd).

Als u een bepaalde gebeurtenis op een paar plaatsen moet opslaan (bijv. Gebruikerscreatie naar database, magazijn, e-mailverzendservice en wat u verder nog kunt verzinnen), is een berichtenplatform de schoonste manier om dat bericht te verspreiden.

Consumenten kunnen informatie uit de brokers halen (pull-model) of de brokers informatie rechtstreeks naar de consumenten pushen (push-model).

Er zijn een aantal populaire eersteklas berichtenplatforms:

RabbitMQ - Berichtenmakelaar waarmee u fijnere controle over berichttrajecten kunt krijgen via routeringsregels en andere eenvoudig configureerbare instellingen. Kan een slimme makelaar worden genoemd, omdat het veel logica bevat en de berichten die er doorheen gaan nauwgezet bijhoudt. Biedt instellingen voor zowel AP als CP van CAP. Gebruikt een push-model voor het melden van de consument.

Kafka - Berichtenmakelaar (en allesplatform) dat een beetje lager niveau is, omdat het niet bijhoudt welke berichten zijn gelezen en geen complexe routeringslogica toestaat. Dit helpt het verbazingwekkende prestaties te bereiken. Naar mijn mening is dit het grootste vooruitzicht in deze ruimte met actieve ontwikkeling door de open-sourcecommunity en ondersteuning door het Confluent-team. Kafka wordt aantoonbaar het meest gebruikt door toptechbedrijven. Ik schreef hier een grondige inleiding over, waar ik in detail inga op al zijn goedheid.

Apache ActiveMQ - De oudste van het stel, daterend uit 2004. Gebruikt de JMS API, wat betekent dat deze is afgestemd op Java EE-toepassingen. Het werd herschreven als ActiveMQ Artemis, dat uitstekende prestaties levert die vergelijkbaar zijn met Kafka.

Amazon SQS - Een berichtenservice aangeboden door AWS. Hiermee kunt u deze snel integreren met bestaande applicaties en hoeft u niet meer met uw eigen infrastructuur te werken, wat een groot voordeel kan zijn, omdat systemen zoals Kafka notoir lastig zijn in te stellen. Amazon biedt ook twee vergelijkbare services - SNS en MQ, waarvan de laatste in feite ActiveMQ is, maar wordt beheerd door Amazon.

Gedistribueerde applicaties

Als je 5 Rails-servers oprolt achter een enkele load-balancer die allemaal is verbonden met één database, kun je dat dan een gedistribueerde applicatie noemen? Herinner mijn definitie van hierboven:

Een gedistribueerd systeem is een groep computers die samenwerken om voor de eindgebruiker als één computer te verschijnen. Deze machines hebben een gedeelde status, werken gelijktijdig en kunnen onafhankelijk van elkaar falen zonder de uptime van het hele systeem te beïnvloeden.

Als u de database als een gedeelde status beschouwt, zou u kunnen stellen dat deze kan worden geclassificeerd als een gedistribueerd systeem - maar u hebt het mis, omdat u het deel “samenwerken” van de definitie hebt gemist.

Een systeem wordt alleen gedistribueerd als de knooppunten met elkaar communiceren om hun acties te coördineren.

Daarom kan zoiets als een applicatie die zijn back-endcode uitvoert op een peer-to-peer-netwerk beter worden geclassificeerd als een gedistribueerde applicatie. Hoe dan ook, dit is allemaal onnodige classificatie die geen doel dient, maar illustreert hoe kieskeurig we zijn over het groeperen van dingen.

Bekende schaal - BitTorrent-zwerm van 193.000 knooppunten voor een aflevering van Game of Thrones, april 2014

Erlang Virtual Machine

Erlang is een functionele taal met geweldige semantiek voor gelijktijdigheid, distributie en fouttolerantie. De Erlang Virtual Machine zorgt zelf voor de distributie van een Erlang-applicatie.

Het model werkt door veel geïsoleerde lichtgewichtprocessen te hebben, allemaal met de mogelijkheid om met elkaar te praten via een ingebouwd systeem voor het doorgeven van berichten. Dit wordt het actormodel genoemd en de Erlang OTP-bibliotheken kunnen worden gezien als een gedistribueerd actorraamwerk (volgens de lijnen van Akka voor de JVM).

Het model helpt het bij het bereiken van grote gelijktijdigheid, simpelweg - de processen zijn verspreid over de beschikbare kernen van het systeem waarop ze worden uitgevoerd. Aangezien dit niet te onderscheiden is van een netwerkinstelling (afgezien van de mogelijkheid om berichten te laten vallen), kan Erlang's VM verbinding maken met andere Erlang VM's die in hetzelfde datacenter of zelfs op een ander continent draaien. Deze zwerm virtuele machines draait een enkele applicatie en behandelt machinefouten via overname (een ander knooppunt wordt gepland om te draaien).

In feite is de gedistribueerde taallaag toegevoegd om fouttolerantie te bieden. Software die op een enkele machine draait, loopt altijd het risico dat die ene machine sterft en uw applicatie offline haalt. Software die op veel knooppunten draait, maakt een gemakkelijkere verwerking van hardwarefouten mogelijk, op voorwaarde dat de applicatie met dat in gedachten werd gebouwd.

BitTorrent

BitTorrent is een van de meest gebruikte protocollen voor het overdragen van grote bestanden via torrents op het web. Het belangrijkste idee is om bestandsoverdracht tussen verschillende peers in het netwerk te vergemakkelijken zonder dat u via een hoofdserver hoeft te gaan.

Met een BitTorrent-client maakt u verbinding met meerdere computers over de hele wereld om een ​​bestand te downloaden. Wanneer u een .torrent-bestand opent, maakt u verbinding met een zogenaamde tracker, een machine die fungeert als coördinator. Het helpt bij peer discovery en toont u de knooppunten in het netwerk die het gewenste bestand hebben.

een voorbeeldnetwerk

Je hebt de noties van twee soorten gebruikers, een leecher en een seeder. Een leecher is de gebruiker die een bestand downloadt en een seeder is de gebruiker die het bestand uploadt.

Het grappige van peer-to-peer-netwerken is dat u als gewone gebruiker lid kunt worden van en een bijdrage kunt leveren aan het netwerk.

Met BitTorrent en zijn voorgangers (Gnutella, Napster) kunt u vrijwillig bestanden hosten en uploaden naar andere gebruikers die ze willen. De reden dat BitTorrent zo populair is, is dat het de eerste in zijn soort was die prikkels bood om bij te dragen aan het netwerk. Freeriden, waarbij een gebruiker alleen bestanden zou downloaden, was een probleem met de vorige protocollen voor het delen van bestanden.

BitTorrent lost freeriden in zekere mate op door seeders meer te laten uploaden naar degenen die de beste downloadsnelheden bieden. Het werkt door u te stimuleren om te uploaden tijdens het downloaden van een bestand. Helaas zorgt niets ervoor dat u actief blijft in het netwerk nadat u klaar bent. Dit veroorzaakt een gebrek aan seeders in het netwerk die het volledige bestand hebben en omdat het protocol sterk afhankelijk is van dergelijke gebruikers, kwamen oplossingen zoals particuliere trackers tot bloei. Voor privé-trackers moet u lid zijn van een community (vaak alleen op uitnodiging) om deel te nemen aan het gedistribueerde netwerk.

Na vooruitgang in het veld, werden trackerloze torrents uitgevonden. Dit was een upgrade van het BitTorrent-protocol dat niet afhankelijk was van gecentraliseerde trackers voor het verzamelen van metadata en het vinden van peers, maar in plaats daarvan nieuwe algoritmen gebruikte. Een voorbeeld hiervan is Kademlia (Mainline DHT), een gedistribueerde hashtabel (DHT) waarmee u peers kunt vinden via andere peers. In feite voert elke gebruiker de taken van een tracker uit.

Gedistribueerde grootboeken

Een gedistribueerd grootboek kan worden beschouwd als een onveranderlijke, alleen-toevoegen database die wordt gerepliceerd, gesynchroniseerd en gedeeld via alle knooppunten in het gedistribueerde netwerk.

Bekende schaal - Ethereum Network kende een piek van 1,3 miljoen transacties per dag op 4 januari 2018.

Ze maken gebruik van het Event Sourcing-patroon, zodat u de status van het grootboek op elk gewenst moment in de geschiedenis kunt herbouwen.

Blockchain

Blockchain is de huidige onderliggende technologie die wordt gebruikt voor gedistribueerde grootboeken en markeerde in feite hun start. Deze nieuwste en grootste innovatie in de gedistribueerde ruimte maakte het mogelijk om het eerste echt gedistribueerde betalingsprotocol ooit te creëren - Bitcoin.

Blockchain is een gedistribueerd grootboek met een geordende lijst van alle transacties die ooit in zijn netwerk hebben plaatsgevonden. Transacties worden gegroepeerd en opgeslagen in blokken. De hele blockchain is in wezen een gekoppelde lijst met blokken (vandaar de naam). Deze blokken zijn rekenkundig duur om te maken en zijn nauw met elkaar verbonden door cryptografie.

Eenvoudig gezegd, elk blok bevat een speciale hash (die begint met X aantal nullen) van de inhoud van het huidige blok (in de vorm van een Merkle-boom) plus de hash van het vorige blok. Deze hash vereist veel CPU-vermogen om te worden geproduceerd, omdat de enige manier om het te bedenken is door brute-force.

Vereenvoudigde blockchain

Mijnwerkers zijn de knooppunten die proberen de hash te berekenen (via bruteforce). De mijnwerkers concurreren allemaal met elkaar om wie een willekeurige reeks (een nonce) kan bedenken die, in combinatie met de inhoud, de bovengenoemde hash produceert. Zodra iemand de juiste nonce vindt, zendt hij deze uit naar het hele netwerk. Deze string wordt dan geverifieerd door elk afzonderlijk knooppunt en geaccepteerd in hun keten.

Dit vertaalt zich in een systeem waarbij het absurd duur is om de blockchain te wijzigen en absurd eenvoudig om te verifiëren dat er niet mee is geknoeid.

Het is kostbaar om de inhoud van een blok te wijzigen, omdat dat een andere hash zou produceren. Onthoud dat de hash van elk volgend blok ervan afhankelijk is. Als u een transactie in het eerste blok van de bovenstaande afbeelding zou wijzigen - zou u de Merkle-root wijzigen. Dit zou op zijn beurt de hash van het blok veranderen (hoogstwaarschijnlijk zonder de benodigde voorloopnullen) - dat zou de hash van blok # enzovoort veranderen, enzovoort. Dit betekent dat je een nieuwe nonce moet forceren voor elk blok na het blok dat je zojuist hebt aangepast.

Het netwerk vertrouwt en repliceert altijd de langste geldige keten. Om het systeem te bedriegen en uiteindelijk een langere keten te produceren, heb je meer dan 50% van het totale CPU-vermogen nodig dat door alle knooppunten wordt gebruikt.

Blockchain kan worden gezien als een gedistribueerd mechanisme voor opkomende consensus. Consensus wordt niet expliciet bereikt - er is geen verkiezing of vast moment waarop consensus optreedt. In plaats daarvan is consensus een opkomend product van de asynchrone interactie van duizenden onafhankelijke knooppunten, alle volgende protocolregels.

Deze ongekende innovatie is onlangs een boom in de technische ruimte geworden met mensen die voorspellen dat dit de creatie van Web 3.0 zal markeren. Het is op dit moment absoluut de meest opwindende ruimte in de wereld van software-engineering, vol met extreem uitdagende en interessante problemen die wachten om te worden opgelost.

Bitcoin

Wat eerdere gedistribueerde betalingsprotocollen misten, was een manier om het probleem van dubbele uitgaven in realtime, op een gedistribueerde manier, praktisch te voorkomen. Onderzoek heeft interessante voorstellen opgeleverd [1], maar Bitcoin was de eerste die een praktische oplossing implementeerde met duidelijke voordelen ten opzichte van anderen.

Het dubbele bestedingsprobleem stelt dat een acteur (bijv. Bob) zijn middel niet op twee plaatsen kan uitgeven. Als Bob $ 1 heeft, zou hij het niet aan zowel Alice als Zack moeten kunnen geven - het is slechts één actief, het kan niet worden gedupliceerd. Het blijkt echt moeilijk om deze garantie echt te bereiken in een gedistribueerd systeem. Er zijn een aantal interessante mitigatiebenaderingen die voorafgingen aan blockchain, maar ze lossen het probleem niet op een praktische manier op.

Dubbele uitgaven worden gemakkelijk opgelost door Bitcoin, omdat er slechts één blok tegelijk aan de keten wordt toegevoegd. Dubbel uitgeven is onmogelijk binnen een enkel blok, dus zelfs als er twee blokken tegelijkertijd worden gemaakt - komt er slechts één op de uiteindelijk langste keten.

Bitcoin vertrouwt op de moeilijkheid om CPU-vermogen te verzamelen.

Terwijl in een stemsysteem een ​​aanvaller alleen knooppunten aan het netwerk hoeft toe te voegen (wat gemakkelijk is, omdat vrije toegang tot het netwerk een ontwerpdoel is), krijgt een aanvaller in een CPU-stroomschema een fysieke beperking: toegang krijgen tot meer en meer krachtige hardware.

Dit is ook de reden dat kwaadwillende groepen knooppunten meer dan 50% van de rekenkracht van het netwerk moeten beheersen om een ​​succesvolle aanval uit te voeren. Minder dan dat, en de rest van het netwerk zal sneller een langere blockchain creëren.

Ethereum

Ethereum kan worden gezien als een programmeerbaar blockchain-gebaseerd softwareplatform. Het heeft zijn eigen cryptocurrency (Ether) die de inzet van slimme contracten op zijn blockchain van brandstof voorziet.

Slimme contracten zijn een stuk code opgeslagen als een enkele transactie in de Ethereum-blockchain. Om de code uit te voeren, hoeft u alleen maar een transactie uit te voeren met een smart contract als bestemming. Dit zorgt er op zijn beurt voor dat de mijnwerkersknooppunten de code uitvoeren en alle wijzigingen die het oploopt. De code wordt uitgevoerd in de Ethereum Virtual Machine.

Solidity, de eigen programmeertaal van Ethereum, wordt gebruikt om slimme contracten te schrijven. Het is een turing-complete programmeertaal die rechtstreeks in verbinding staat met de Ethereum-blockchain, zodat u status zoals saldi of andere slimme contractresultaten kunt opvragen. Om oneindige lussen te voorkomen, vereist de code enige hoeveelheid Ether.

Omdat de blockchain kan worden geïnterpreteerd als een reeks statusveranderingen, zijn er veel gedistribueerde applicaties (DApp's) gebouwd bovenop Ethereum en vergelijkbare platforms.

Verder gebruik van gedistribueerde grootboeken

Bewijs van bestaan ​​- Een service voor het anoniem en veilig opslaan van bewijs dat er op een bepaald moment een bepaald digitaal document bestond. Handig om documentintegriteit, eigendom en tijdstempels te waarborgen.

Decentralized Autonomous Organisations (DAO) - organisaties die blockchain gebruiken om consensus te bereiken over de verbeteringsproposities van de organisatie. Voorbeelden zijn het beheerssysteem van Dash, het SmartCash-project

Gedecentraliseerde authenticatie - Bewaar uw identiteit op de blockchain, zodat u overal eenmalige aanmelding (SSO) kunt gebruiken. Sovrin, Civic

En nog veel, veel meer. De gedistribueerde grootboektechnologie heeft echt eindeloze mogelijkheden geopend. Sommige worden waarschijnlijk op dit moment uitgevonden!

Samenvatting

In de korte tijd van dit artikel hebben we het voor elkaar gekregen om te definiëren wat een gedistribueerd systeem is, waarom je er een zou gebruiken en elke categorie een beetje zou doornemen. Enkele belangrijke dingen om te onthouden zijn:

  • Gedistribueerde systemen zijn complex
  • Ze worden gekozen door de noodzaak van schaal en prijs
  • Ze zijn moeilijker om mee te werken
  • CAP-stelling - Consistentie / beschikbaarheid compromis
  • Ze hebben 6 categorieën: gegevensopslag, computergebruik, bestandssystemen, berichtensystemen, grootboeken, toepassingen

Eerlijk gezegd hebben we op gedistribueerde systemen nauwelijks het oppervlak geraakt. Ik kreeg niet de kans om kernproblemen zoals consensus, replicatiestrategieën, volgorde en tijd van gebeurtenissen, fouttolerantie, het uitzenden van een bericht via het netwerk en anderen grondig aan te pakken en uit te leggen.

Voorzichtigheid

Laat me je verlaten met een waarschuwing voor afscheid:

U moet zoveel mogelijk afdwalen van gedistribueerde systemen. De complexiteit die zij met zichzelf oplopen is niet de moeite waard als u het probleem kunt voorkomen door het op een andere manier op te lossen of een andere kant-en-klare oplossing.

[1]
Bestrijding van dubbele uitgaven met behulp van Cooperative P2P-systemen, 25-27 juni 2007 - een voorgestelde oplossing waarin elke ‘munt’ kan vervallen en waaraan een getuige (validator) wordt toegewezen.

Bitgold, december 2005 - Een overzicht op hoog niveau van een protocol dat extreem lijkt op dat van Bitcoin. Er wordt gezegd dat dit de voorloper is van Bitcoin.

Verdere verspreiding van gedistribueerde systemen:

Martin Kleppmann ontwerpt gegevensintensieve toepassingen - Een geweldig boek dat alles over gedistribueerde systemen en meer bestrijkt.

Cloud Computing Specialization, University of Illinois, Coursera - Een lange reeks cursussen (6) over gedistribueerde systeemconcepten, applicaties

Jepsen - Blog met uitleg over veel gedistribueerde technologieën (ElasticSearch, Redis, MongoDB, enz.)

Bedankt dat je de tijd hebt genomen om dit lange artikel (~ 5600 woorden) te lezen!

Als je dit toevallig informatief vond of dacht dat het je waarde gaf, zorg er dan voor dat je het zoveel klappen geeft als je denkt dat het verdient en overweeg het te delen met een vriend die een inleiding tot dit prachtige vakgebied zou kunnen gebruiken.

~ Stanislav Kozlovski

Bijwerken

Ik werk momenteel bij Confluent. Confluent is een Big Data-bedrijf dat is opgericht door de makers van Apache Kafka zelf! Ik ben enorm dankbaar voor de kans die ze me hebben gegeven - ik werk momenteel aan Kafka zelf, wat geweldig is! Wij bij Confluent helpen het hele open-source Kafka-ecosysteem vorm te geven, inclusief een nieuw beheerd Kafka-as-a-service cloudaanbod.

We nemen veel functies aan (met name SRE / Software Engineers) in Europa en de VS! Als je geïnteresseerd bent om aan Kafka zelf te werken, op zoek bent naar nieuwe kansen of gewoon nieuwsgierig bent, stuur me dan een berichtje op Twitter en ik zal alle geweldige voordelen delen die je hebt als je in een bedrijf in de Bay Area werkt.