Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 3. Kafka

Fortsetzung vun der Iwwersetzung vun engem klenge Buch:
Message Brokers verstoen
Auteur: Jakub Korab, Verlag: O'Reilly Media, Inc., Verëffentlechungsdatum: Juni 2017, ISBN: 9781492049296.

Virdrun iwwersat Deel: Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 1 Aféierung

CHAPTER 3

Kafka

Kafka gouf vu LinkedIn entwéckelt fir e puer vun de Beschränkungen vun traditionelle Message Broker ëmzegoen an ze vermeiden datt verschidde Message Brokeren fir verschidde Punkt-zu-Punkt Interaktiounen opgeriicht sinn, wat an dësem Buch ënner "Skaléieren an eraus" op Säit 28 beschriwwe gëtt. Benotzen Fäll LinkedIn huet haaptsächlech op een-Wee-Intake vu ganz grousse Quantitéiten un Daten vertraut, wéi Säitklicken an Zougangsprotokoller, wärend et ëmmer nach erlaabt datt dës Donnéeë vu verschidde Systemer benotzt ginn ouni d'Produktivitéit vun de Produzenten oder aner Konsumenten ze beaflossen. Tatsächlech ass de Grond datt Kafka existéiert ass d'Aart vu Messageriearchitektur ze kréien déi d'Universal Data Pipeline beschreift.

Mat dësem ultimativen Zil sinn natierlech aner Ufuerderungen entstanen. Kafka soll:

  • Sidd extrem séier
  • Bitt méi Bandbreedung wann Dir mat Messagen schafft
  • Ënnerstëtzt Publisher-Abonnent a Point-to-Point Modeller
  • Maacht net méi lues mat Konsumenten derbäi. Zum Beispill, d'Performance vun der Schlaang an dem Thema an ActiveMQ degradéiert wéi d'Zuel vun de Konsumenten op der Destinatioun wiisst.
  • Sidd horizontal skalierbar; wann ee Broker deen Messagen bestoe kann dat nëmme mat maximaler Diskgeschwindegkeet maachen, dann mécht et Sënn fir iwwer eng eenzeg Brokerinstanz ze goen fir d'Performance ze erhéijen
  • Limitéiert den Zougang fir Messagen ze späicheren an ze recuperéieren

Fir dëst alles z'erreechen, huet de Kafka eng Architektur ugeholl, déi d'Rollen an d'Verantwortung vu Clienten a Messaging Broker nei definéiert huet. De JMS Modell ass ganz broker orientéiert, wou de Broker verantwortlech ass fir Messagen ze verdeelen an d'Clienten nëmme Suergen iwwer d'Schécken an d'Empfang vun Messagen mussen maachen. Kafka, op der anerer Säit, ass Client-centric, mam Client iwwerhëlt vill vun de Funktiounen vun engem traditionelle Broker, sou wéi eng fair Verdeelung vun relevante Messagen un d'Konsumenten, am Austausch fir en extrem schnellen a skalierbare Broker. Fir Leit, déi mat traditionelle Messageriesystemer geschafft hunn, erfuerdert d'Aarbecht mat Kafka eng fundamental Ännerung vum Geescht.
Dës Ingenieursrichtung huet zu der Schafung vun enger Messagerieinfrastruktur gefouert, déi fäeg ass den Duerchgang duerch vill Uerderen ze vergréisseren am Verglach mat engem konventionelle Broker. Wéi mir wäerte gesinn, kënnt dës Approche mat Ofhandlungen, dat heescht datt Kafka net gëeegent ass fir verschidden Arten vun Aarbechtslaascht an installéiert Software.

Unified Destination Model

Fir déi uewe beschriwwen Ufuerderungen z'erfëllen, huet de Kafka publizéiert-Abonnéieren a Punkt-zu-Punkt Messagerie ënner enger Aart vun Destinatioun kombinéiert - Thema. Dëst ass duerchernee fir Leit déi mat Messageriesystemer geschafft hunn, wou d'Wuert "Thema" op e Sendungsmechanismus bezitt, aus deem (vum Thema) d'Liesen net haltbar ass. Kafka Themen sollen als Hybrid Destinatiounstyp ugesi ginn, wéi an der Aféierung an dësem Buch definéiert.

Fir de Rescht vun dësem Kapitel, ausser mir soen explizit anescht, wäert de Begrëff "Thema" op e Kafka Thema bezéien.

Fir voll ze verstoen wéi Themen sech behuelen a wéi eng Garantien se ubidden, musse mir als éischt kucken wéi se am Kafka ëmgesat ginn.
All Thema am Kafka huet säin eegene Logbuch.
D'Produzenten, déi Messagen un de Kafka schécken, schreiwen op dëse Logbuch, an d'Konsumenten liesen aus dem Logbuch mat Zeiger, déi stänneg no vir goen. Periodesch läscht Kafka déi eelst Deeler vum Logbuch, egal ob d'Messagen an deenen Deeler gelies goufen oder net. En zentrale Bestanddeel vum Kafka Design ass datt de Broker egal ass ob Messagen gelies ginn oder net - dat ass d'Verantwortung vum Client.

D'Begrëffer "Log" an "Zeechner" schéngen net an Kafka Dokumentatioun. Dës bekannte Begrëffer ginn hei benotzt fir Verständnis ze hëllefen.

Dëse Modell ass komplett anescht wéi ActiveMQ, wou Messagen aus all Schlaangen am selwechte Log gespäichert sinn, an de Broker markéiert d'Messagen als geläscht nodeems se gelies goufen.
Loosst eis elo e bësse méi déif gräifen a kucken d'Thema Log méi am Detail.
De Kafka Log besteet aus verschiddene Partitionen (Figur 3-1). Kafka garantéiert strikt Uerdnung an all Partition. Dëst bedeit datt Messagen, déi an enger bestëmmter Uerdnung op d'Partition geschriwwe sinn, an der selwechter Uerdnung gelies ginn. All Partition gëtt als Rolling Log Datei implementéiert déi enthält eng Ënnergrupp (Ënnerdeel) vun alle Messagen, déi op d'Thema vu senge Produzenten geschéckt ginn. Dat erstallt Thema enthält par défaut eng Partition. D'Iddi vu Partitionen ass déi zentral Iddi vu Kafka fir horizontale Skala.

Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 3. Kafka
Figur 3-1. Kafka Partitionen

Wann e Produzent e Message un e Kafka Thema schéckt, entscheet hien op wéi eng Partition de Message schéckt. Mir wäerten dëst méi am Detail méi spéit kucken.

Liesen Messagen

De Client deen d'Messagen liese wëll verwaltet e genannte Pointer genannt Konsument Grupp, déi weist op offset Messagen an der Partition. En Offset ass eng inkrementell Positioun déi um Start vun enger Partition bei 0 ufänkt. Dëse Konsumentgrupp, referenzéiert an der API iwwer de Benotzerdefinéiert group_id, entsprécht ee logesche Konsument oder System.

Déi meescht Messageriesystemer liesen Daten aus der Destinatioun mat multiple Instanzen a Threads fir Messagen parallel ze veraarbecht. Sou wäert et normalerweis vill Konsument Instanzen déi selwecht Konsument Grupp deelen.

De Problem vum Liesen kann wéi follegt duergestallt ginn:

  • Thema huet verschidde Partitionen
  • Multiple Gruppe vu Konsumenten kënnen en Thema zur selwechter Zäit benotzen
  • Eng Grupp vu Konsumenten ka verschidde separat Instanzen hunn

Dëst ass en net-triviale vill-zu-vill Problem. Fir ze verstoen wéi de Kafka Bezéiungen tëscht Konsumentgruppen, Konsumentinstanzen a Partitionen behandelt, kucke mer eng Serie vu progressiv méi komplexe Liesszenarien.

Konsumenten a Konsumentgruppen

Loosst eis als Ausgangspunkt en Thema mat enger Partition huelen (Figur 3-2).

Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 3. Kafka
Figur 3-2. De Konsument liest vun der Partition

Wann eng Konsumentinstanz mat senger eegener group_id zu dësem Thema verbënnt, gëtt et eng Liespartition an en Offset an där Partition zougewisen. D'Positioun vun dësem Offset ass am Client konfiguréiert als Zeiger op déi rezent Positioun (neiste Message) oder fréizäiteg Positioun (eelste Message). De Konsument freet (Ëmfroen) Messagen aus dem Thema, wat verursaacht datt se sequentiell aus dem Logbuch gelies ginn.
D'Offset Positioun gëtt regelméisseg zréck op Kafka engagéiert an als Messagen an engem internen Thema gespäichert _consumer_offsets. Liesen Messagen ginn nach ëmmer net geläscht, am Géigesaz zu engem normale Broker, an de Client kann d'Offset zréckzéien fir scho gekuckte Messagen nei ze veraarbecht.

Wann en zweete logesche Konsument mat enger anerer group_id verbënnt, geréiert en en zweete Pointer deen onofhängeg vum éischten (Figur 3-3). Also wierkt e Kafka-Thema wéi eng Schlaang wou et ee Konsument gëtt a wéi en normalen publizéieren-abonnéieren (Pub-Sub) Thema op dat verschidde Konsumenten abonnéieren, mam zousätzleche Virdeel datt all Messagen gespäichert sinn a méi oft veraarbecht kënne ginn.

Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 3. Kafka
Figur 3-3. Zwee Konsumenten a verschiddene Konsumentgruppen liesen aus der selwechter Partition

Konsumenten an engem Konsument Grupp

Wann eng Konsument Instanz Daten aus enger Partition liest, huet se voll Kontroll iwwer de Pointer a veraarbecht Messagen wéi an der viregter Sektioun beschriwwen.
Wann e puer Fäll vu Konsumenten mat der selwechter group_id zu engem Thema mat enger Partition verbonne waren, da gëtt d'Instanz déi lescht verbonnen Kontroll iwwer de Pointer kritt a vun deem Moment un kritt se all Messagen (Figur 3-4).

Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 3. Kafka
Figur 3-4. Zwee Konsumenten an der selwechter Konsumentgrupp liesen aus der selwechter Partition

Dëse Modus vun der Veraarbechtung, an deem d'Zuel vun de Verbraucherinstanzen d'Zuel vun de Partitionen iwwerschreift, kann als eng Zort exklusiv Konsument geduecht ginn. Dëst kann nëtzlech sinn wann Dir "aktiv-passiv" (oder "waarm-waarm") Clustering vun Äre Konsumenteninstanzen braucht, obwuel verschidde Konsumenten parallel lafen ("aktiv-aktiv" oder "waarm-waarm") vill méi typesch ass wéi Konsumenten.Am Standby.

Dëst Message Verdeelung Verhalen uewen beschriwwen kann iwwerraschend sinn am Verglach mat wéi eng normal JMS Schlaang behuelen. An dësem Modell ginn Messagen, déi an d'Schlaang geschéckt ginn, gläichméisseg tëscht den zwee Konsumenten verdeelt.

Meeschtens, wa mir verschidde Instanzen vu Konsumenten erstellen, maache mir dat entweder fir Messagen parallel ze veraarbechten, oder fir d'Liesgeschwindegkeet ze erhéijen oder d'Stabilitéit vum Liesprozess ze erhéijen. Well nëmmen eng Konsument Instanz kann Daten aus enger Partition gläichzäiteg liesen, wéi gëtt dat am Kafka erreecht?

Ee Wee fir dëst ze maachen ass eng eenzeg Konsument Instanz ze benotzen fir all d'Messagen ze liesen an se an de Fuedempool weiderzeginn. Wärend dës Approche d'Veraarbechtungsduerchgang erhéicht, erhéicht d'Komplexitéit vun der Konsumentlogik a mécht näischt fir d'Robustitéit vum Liessystem ze erhéijen. Wann eng Kopie vum Konsument erof geet wéinst engem Stroumausfall oder ähnlechen Event, da stoppt d'Subtraktioun.

De kanonesche Wee fir dëse Problem am Kafka ze léisen ass bОméi Partitionen.

Partitionéieren

Partitionen sinn den Haaptmechanismus fir d'Liesen ze paralleliséieren an en Thema iwwer d'Bandbreedung vun enger eenzeger Brokerinstanz ze skaléieren. Fir dëst besser ze verstoen, loosst eis eng Situatioun betruechten wou et en Thema mat zwou Partitionen gëtt an ee Konsument sech op dëst Thema abonnéiert (Figur 3-5).

Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 3. Kafka
Figur 3-5. Ee Konsument liest vu ville Partitionen

An dësem Szenario gëtt de Konsument d'Kontroll iwwer d'Zeecher, déi zu senger group_id entspriechend a béide Partitionen entspriechen, a fänkt un Messagen vu béide Partitionen ze liesen.
Wann en zousätzleche Konsument fir dee selwechte group_id zu dësem Thema bäigefüügt gëtt, verdeelt Kafka eng vun de Partitionen vum éischten op den zweeten Konsument. Duerno liest all Instanz vum Konsument aus enger Partition vum Thema (Figur 3-6).

Fir sécherzestellen datt Messagen parallel an 20 Threads veraarbecht ginn, brauch Dir op d'mannst 20 Partitionen. Wann et manner Partitionen sinn, bleift Dir mat Konsumenten, déi näischt ze schaffen hunn, wéi virdrun an der Diskussioun vun exklusive Konsumenten beschriwwen.

Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 3. Kafka
Figur 3-6. Zwee Konsumenten an der selwechter Konsumentgrupp liesen aus verschiddene Partitionen

Dëse Schema reduzéiert d'Komplexitéit vum Kafka Broker staark am Verglach mat der Messageverdeelung déi néideg ass fir d'JMS Schlaang z'erhalen. Hei musst Dir Iech keng Suergen iwwer déi folgend Punkten maachen:

  • Wéi ee Konsument soll den nächste Message kréien, baséiert op der Ronn-Robin Allocatioun, der aktueller Kapazitéit vu Prefetch-Puffer oder fréiere Messagen (wéi fir JMS Messagegruppen).
  • Wéi eng Noriichte ginn u wéi eng Konsumenten geschéckt an ob se am Fall vun Echec sollen erëm geliwwert ginn.

Alles wat de Kafka Broker muss maachen ass Messagen sequenziell un de Konsument weiderginn wann dee leschte se freet.

Wéi och ëmmer, d'Ufuerderunge fir d'Parallaliséierung vun der Korrektur an der neier Sendung vu gescheiterte Messagen ginn net fort - d'Verantwortung fir si geet einfach vum Broker op de Client. Dëst bedeit datt se an Ärem Code berücksichtegt musse ginn.

Messagen schécken

Et ass d'Verantwortung vum Produzent vun deem Message fir ze entscheeden op wéi eng Partition e Message ze schécken. Fir de Mechanismus ze verstoen, duerch deen dëst gemaach gëtt, musse mir als éischt berücksichtegen wat mir wierklech verschéckt.

Wärend mir am JMS eng Messagestruktur mat Metadaten (Header an Eegeschafte) benotzen an e Kierper mat der Notzlaascht (Notzlaascht), am Kafka ass de Message Pair "Schlësselwäert". De Message Notzlaascht gëtt als Wäert geschéckt. De Schlëssel, op der anerer Säit, gëtt haaptsächlech fir Partitionéierung benotzt a muss enthalen Business Logik spezifesch SchlësselZesummenhang Messagen an der selwechter Partition ze setzen.

Am Kapitel 2 hu mir den Online Wetten Szenario diskutéiert wou verbonne Eventer musse vun engem eenzege Konsument veraarbecht ginn:

  1. De Benotzerkont ass konfiguréiert.
  2. D'Suen ginn op de Kont gesat.
  3. Et gëtt eng Wette gemaach déi Sue vum Kont zréckzéien.

Wann all Event e Message ass, deen zu engem Thema gepost gëtt, da wier den natierleche Schlëssel de Kont ID.
Wann e Message mat der Kafka Producer API geschéckt gëtt, gëtt se op eng Partitionsfunktioun iwwerginn, déi, no der Noriicht an den aktuellen Zoustand vum Kafka Cluster, d'ID vun der Partition zréckginn, op déi de Message geschéckt soll ginn. Dës Feature gëtt a Java duerch d'Partitioner Interface implementéiert.

Dësen Interface gesäit esou aus:

interface Partitioner {
    int partition(String topic,
        Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);
}

D'Partitioner Implementatioun benotzt den Standard allgemeng Zweck Hashing Algorithmus iwwer de Schlëssel fir d'Partition ze bestëmmen, oder Round-Robin wann kee Schlëssel spezifizéiert ass. Dëse Standardwäert funktionnéiert gutt an de meeschte Fäll. Wéi och ëmmer, an Zukunft wëllt Dir Är eege schreiwen.

Schreift Är eege Partitionéierungsstrategie

Loosst eis e Beispill kucken wou Dir Metadaten zesumme mat der Message Notzlaascht wëllt schécken. D'Notzlaascht an eisem Beispill ass eng Instruktioun fir en Depot op de Spillkonto ze maachen. Eng Instruktioun ass eppes wat mir gäre garantéieren datt se net bei der Iwwerdroung geännert ginn a wëlle sécher sinn datt nëmmen e vertrauenswürdege Upstream System dës Instruktioun kann initiéieren. An dësem Fall sinn d'Send- a Empfangssystemer d'accord iwwer d'Benotzung vun enger Ënnerschrëft fir de Message ze authentifizéieren.
Am normalen JMS definéiere mir einfach eng "Message Ënnerschrëft" Eegeschafte a fügen se an de Message. De Kafka liwwert eis awer kee Mechanismus fir Metadaten ze vermëttelen, nëmmen e Schlëssel an e Wäert.

Well de Wäert e Banktransfer Notzlaascht ass, deem seng Integritéit mir wëllen erhaalen, hu mir keng aner Wiel wéi d'Datestruktur ze definéieren fir am Schlëssel ze benotzen. Unzehuelen datt mir eng Kont ID fir d'Partitionéierung brauchen, well all Messagen am Zesummenhang mat engem Kont mussen an Uerdnung veraarbecht ginn, komme mir mat der folgender JSON Struktur:

{
  "signature": "541661622185851c248b41bf0cea7ad0",
  "accountId": "10007865234"
}

Well de Wäert vun der Ënnerschrëft ofhängeg vun der Notzlaascht variéiere wäert, gëtt d'Standard-Hashingstrategie vun der Partitioner-Interface net zouverlässeg verwandte Messagen gruppéiert. Dofir musse mir eis eege Strategie schreiwen, déi dëse Schlëssel parseiert an de AccountId Wäert opdeelt.

Kafka enthält Kontrollsumme fir Korruptioun vu Messagen am Geschäft z'entdecken an huet e komplette Set vu Sécherheetsfeatures. Wéi och ëmmer, Industriespezifesch Ufuerderungen, wéi déi hei uewen, erschéngen heiansdo.

D'Partitionéierungsstrategie vum Benotzer muss dofir suergen datt all verbonne Messagen an der selwechter Partition ophalen. Och wann dëst einfach schéngt, kann d'Ufuerderung komplizéiert sinn duerch d'Wichtegkeet vun der Bestellung vu verwandte Messagen a wéi fix d'Zuel vun de Partitionen an engem Thema ass.

D'Zuel vun de Partitionen an engem Thema ka mat der Zäit änneren, well se kënne bäigefüügt ginn wann de Traffic iwwer déi initial Erwaardungen geet. Also kënne Messageschlësselen mat der Partition assoziéiert ginn, op déi se ursprénglech geschéckt goufen, wat e Stéck Staat implizéiert fir tëscht Produzentinstanzen ze gedeelt ginn.

En anere Faktor fir ze berücksichtegen ass déi gläichméisseg Verdeelung vu Messagen iwwer Partitionen. Typesch sinn Schlësselen net gläichméisseg iwwer Messagen verdeelt, an Hashfunktiounen garantéieren keng fair Verdeelung vu Messagen fir e klenge Set vu Schlësselen.
Et ass wichteg ze bemierken datt awer Dir gewielt hutt Messagen opzedeelen, de Separator selwer muss eventuell erëmbenotzt ginn.

Bedenkt d'Ufuerderung fir Daten tëscht Kafka-Cluster a verschiddene geographesche Plazen ze replizéieren. Fir dësen Zweck kënnt Kafka mat engem Kommandozeil-Tool mam Numm MirrorMaker, dat benotzt gëtt fir Messagen aus engem Cluster ze liesen an op en aneren ze transferéieren.

MirrorMaker muss d'Schlëssele vum replizéierten Thema verstoen fir eng relativ Uerdnung tëscht Messagen z'erhalen wann Dir tëscht Cluster replizéiert, well d'Zuel vun de Partitionen fir dat Thema an zwee Cluster vläicht net d'selwecht sinn.

Benotzerdefinéiert Partitionéierungsstrategien si relativ rar, well Standard-Hashing oder Round Robin funktionnéiert gutt an de meeschte Szenarien. Wéi och ëmmer, wann Dir staark Bestellungsgarantie braucht oder Metadaten aus Notzlaascht extrahéiere musst, dann ass d'Partitionéierung eppes wat Dir sollt méi no kucken.

D'Skalierbarkeet an d'Leeschtungsvirdeeler vu Kafka kommen aus der Verréckelung vun e puer vun de Verantwortung vum traditionelle Broker op de Client. An dësem Fall gëtt eng Entscheedung getraff fir potenziell verbonne Messagen tëscht verschiddene Konsumenten déi parallel schaffen ze verdeelen.

JMS Broker mussen och mat esou Ufuerderunge këmmeren. Interessanterweis erfuerdert de Mechanismus fir verwandte Messagen un dee selwechte Konsument ze schécken, implementéiert duerch JMS Message Groups (eng Variatioun op der Sticky load Balancing (SLB) Strategie), och de Sender fir Messagen als Zesummenhang ze markéieren. Am Fall vun JMS ass de Broker verantwortlech fir dës Grupp vu verwandte Messagen un ee Konsument aus villen ze schécken, an d'Besëtzer vun der Grupp ze transferéieren wann de Konsument fällt.

Produzent Accorden

Partitionéieren ass net déi eenzeg Saach ze berücksichtegen wann Dir Messagen schéckt. Loosst eis e Bléck op d'Send () Methode vun der Produzent Klass an der Java API kucken:

Future < RecordMetadata > send(ProducerRecord < K, V > record);
Future < RecordMetadata > send(ProducerRecord < K, V > record, Callback callback);

Et sollt direkt bemierkt ginn datt béid Methoden Future zréckginn, wat beweist datt d'Sendoperatioun net direkt gemaach gëtt. D'Resultat ass datt e Message (ProducerRecord) an de Sendbuffer fir all aktive Partition geschriwwe gëtt an un de Broker als Hannergrondfaden an der Kafka Clientbibliothéik geschéckt gëtt. Och wann dëst d'Saache onheemlech séier mécht, heescht et datt eng onerfueren Applikatioun Messagen verléieren kann wann säi Prozess gestoppt gëtt.

Wéi ëmmer gëtt et e Wee fir d'Sendoperatioun méi zouverlässeg op d'Käschte vun der Leeschtung ze maachen. D'Gréisst vun dësem Puffer kann op 0 gesat ginn, an de schéckt Applikatioun thread gëtt gezwongen ze waarden bis de Message Transfert un de Broker fäerdeg ass, wéi follegt:

RecordMetadata metadata = producer.send(record).get();

Méi iwwer Messagen liesen

Messagen liesen huet zousätzlech Komplexitéiten, déi musse spekuléiert ginn. Am Géigesaz zu der JMS API, déi e Message Lauschterer an Äntwert op e Message lafen kann, der Konsument Kafka nëmmen Ëmfroen. Loosst eis d'Method méi genau kucken poll()fir dësen Zweck benotzt:

ConsumerRecords < K, V > poll(long timeout);

De Retourwäert vun der Method ass eng Containerstruktur déi verschidde Objekter enthält Konsument Rekord vu potenziell e puer Partitionen. Konsument Rekord ass selwer en Titulaireobjekt fir e Schlësselwäertpaar mat assoziéierten Metadaten, sou wéi d'Partition aus där se ofgeleet ass.

Wéi am Kapitel 2 diskutéiert, musse mir am Kapp behalen wat mat Messagen geschitt nodeems se erfollegräich oder net erfollegräich veraarbecht goufen, zum Beispill wann de Client net fäeg ass d'Botschaft ze verarbeiten oder wann se ofbriechen. Am JMS gouf dëst duerch en Unerkennungsmodus gehandhabt. De Broker läscht entweder den erfollegräich veraarbechte Message, oder liwwert de roude oder gefälschte Message erëm (ugeholl datt Transaktioune benotzt goufen).
Kafka funktionnéiert ganz anescht. Messagen ginn net am Broker nom Korrektur geläscht, a wat geschitt beim Echec ass d'Verantwortung vum Korrekturcode selwer.

Wéi mir gesot hunn, ass de Konsumentgrupp mat der Offset am Logbuch verbonnen. D'Logbuch Positioun, déi mat dësem Offset assoziéiert ass, entsprécht dem nächste Message deen als Äntwert ausgestallt gëtt poll(). De Punkt an der Zäit wou dës Offset eropgeet ass entscheedend fir d'Liesen.

Zréck op de virdru diskutéierte Liesmodell, d'Botschaftveraarbechtung besteet aus dräi Etappen:

  1. Recuperéieren e Message fir liesen.
  2. Veraarbecht de Message.
  3. Confirméieren Message.

De Kafka Konsument kënnt mat enger Konfiguratiounsoptioun enable.auto.commit. Dëst ass eng dacks benotzte Standardastellung, sou wéi et üblech ass mat Astellungen déi d'Wuert "auto" enthalen.

Virun Kafka 0.10, e Client, deen dës Optioun benotzt, géif d'Offset vum leschte Message schécken, deen am nächsten Uruff gelies gëtt poll() no der Veraarbechtung. Dëst bedeit datt all Messagen, déi scho gesammelt gi sinn, nei veraarbecht kënne ginn, wann de Client se scho veraarbecht hat, awer onerwaart zerstéiert gouf ier hien urufft poll(). Well de Broker kee Staat hält iwwer wéi vill Mol e Message gelies gouf, wäert de nächste Konsument deen dee Message erëmfënnt, net wëssen datt eppes Schlechtes geschitt ass. Dëst Verhalen war pseudo-transaktionell. De Offset gouf nëmmen engagéiert wann d'Botschaft erfollegräich veraarbecht gouf, awer wann de Client ofgebrach ass, géif de Broker déi selwecht Noriicht erëm un en anere Client schécken. Dëst Verhalen war konsequent mat der Message Liwwerung Garantie "op d'mannst eemol".

Am Kafka 0.10 ass de Client Code geännert ginn, sou datt d'Verpflichtung periodesch vun der Clientbibliothéik ausgeléist gëtt, wéi konfiguréiert auto.commit.interval.ms. Dëst Verhalen ass iergendwou tëscht dem JMS AUTO_ACKNOWLEDGE an DUPS_OK_ACKNOWLEDGE Modi. Wann Dir Autocommit benotzt, kënne Messagen engagéiert ginn, egal ob se tatsächlech veraarbecht goufen - dëst kéint am Fall vun engem luesen Konsument geschéien. Wann e Konsument ofgebrach ass, gi Messagen vum nächste Konsument ofgeholl, ugefaange bei der engagéierter Positioun, wat zu engem verpasste Message kéint resultéieren. An dësem Fall huet de Kafka d'Botschaften net verluer, de Liescode huet se einfach net veraarbecht.

Dëse Modus huet datselwecht Versprieche wéi an der Versioun 0.9: Messagen kënne veraarbecht ginn, awer wann et net geet, kann de Offset net engagéiert ginn, wat d'Liwwerung eventuell verduebelt. Wat méi Messagen Dir hëlt wann Dir ausféiert poll(), Der méi dëse Problem.

Wéi diskutéiert an "Messagen aus enger Queue liesen" op Säit 21, gëtt et net sou eppes wéi eng eemoleg Liwwerung vun engem Message an engem Messageriesystem wann d'Feelermodi berücksichtegt ginn.

Am Kafka ginn et zwou Méiglechkeeten fir eng Offset (Offset) ze engagéieren: automatesch a manuell. A béide Fäll kënnen d'Messagen e puer Mol veraarbecht ginn, wann de Message veraarbecht gouf, awer virum Engagement gescheitert ass. Dir kënnt och wielen de Message guer net ze veraarbecht wann d'Verpflichtung am Hannergrond geschitt ass an Äre Code fäerdeg war ier et veraarbecht ka ginn (vläicht am Kafka 0.9 a fréier).

Dir kënnt de manuelle Offset Commit Prozess an der Kafka Konsument API kontrolléieren andeems Dir de Parameter setzt enable.auto.commit falsch an explizit eng vun de folgende Methoden ze nennen:

void commitSync();
void commitAsync();

Wann Dir de Message "op d'mannst eemol" veraarbecht wëllt, musst Dir d'Offset manuell matmaachen commitSync()andeems Dir dëse Kommando direkt no der Veraarbechtung vun de Messagen ausféiert.

Dës Methoden erlaben net Messagen unerkannt ze ginn ier se veraarbecht ginn, awer si maachen näischt fir potenziell Veraarbechtungsverzögerungen ze eliminéieren wärend se d'Erscheinung vun transaktiounsfäeg sinn. Et gi keng Transaktiounen am Kafka. De Client huet net d'Fäegkeet déi folgend ze maachen:

  • Roll automatesch e gefälschte Message zréck. D'Konsumenten selwer mussen Ausnahmen handhaben, déi aus problematesch Notzlaascht a Backend-Ausfäll entstinn, well se net op de Broker vertrauen kënnen fir Messagen nei ze liwweren.
  • Schéckt Messagen op verschidde Themen an enger atomarer Operatioun. Wéi mir kuerz gesinn, kann d'Kontroll iwwer verschidden Themen a Partitionen op verschiddene Maschinnen am Kafka-Cluster wunnen, déi Transaktiounen net koordinéieren wann se geschéckt ginn. Zu der Zäit vun dësem Schreiwen ass e puer Aarbecht gemaach fir dëst mam KIP-98 méiglech ze maachen.
  • Associéiert e Message vun engem Thema ze liesen mat engem anere Message an en anert Thema ze schécken. Nach eng Kéier hänkt d'Architektur vum Kafka vu villen onofhängege Maschinnen of, déi als ee Bus lafen a kee Versuch gëtt gemaach dëst ze verstoppen. Zum Beispill gëtt et keng API Komponenten déi Iech erlaben ze verlinken Konsument и Produzent an enger Transaktioun. Am JMS gëtt dëst vum Objet geliwwert Sëtzungaus deenen geschaf ginn Message Produzenten и Message Konsumenten.

Wa mir net op Transaktioune kënne vertrauen, wéi kënne mir Semantik méi no ubidden wéi déi vun traditionelle Messageriesystemer?

Wann et eng Méiglechkeet ass datt d'Offset vum Konsument eropgeet ier de Message veraarbecht gouf, sou wéi während engem Konsument Crash, dann huet de Konsument kee Wee fir ze wëssen ob seng Konsumentgrupp de Message verpasst huet wann et eng Partition zougewisen ass. Also eng Strategie ass d'Offset op déi viregt Positioun zréckzespillen. De Kafka Konsument API bitt déi folgend Methoden fir dëst:

void seek(TopicPartition partition, long offset);
void seekToBeginning(Collection < TopicPartition > partitions);

Methode sichen () kann mat Method benotzt ginn
offsetsForTimes(Map timestampsToSearch) op e bestëmmte Punkt an der Vergaangenheet an e Staat zréckzekréien.

Implizit, d'Benotzung vun dëser Approche bedeit datt et ganz wahrscheinlech ass datt e puer Messagen, déi virdru veraarbecht goufen, gelies an erëm veraarbecht ginn. Fir dëst ze vermeiden, kënne mir idempotent Liesen benotzen, wéi am Kapitel 4 beschriwwen, fir virdru gekuckte Messagen ze verfollegen an Duplikaten ze eliminéieren.

Alternativ kann Äre Konsumentcode einfach gehale ginn, soulaang Message Verloscht oder Duplikatioun akzeptabel ass. Wa mir Benotzungsfäll betruechten, fir déi Kafka allgemeng benotzt gëtt, wéi d'Handhabung vu Log-Evenementer, Metriken, Klickverfolgung, etc., verstinn mir datt de Verloscht vun eenzelne Messagen onwahrscheinlech e wesentlechen Impakt op d'Ëmgéigend Uwendungen huet. An esou Fäll sinn d'Standardwäerter perfekt akzeptabel. Op der anerer Säit, wann Är Uwendung Bezuelungen muss schécken, musst Dir suergfälteg ëm all eenzel Message këmmeren. Et kënnt alles op de Kontext erof.

Perséinlech Observatioune weisen datt wann d'Intensitéit vun de Messagen eropgeet, de Wäert vun all eenzelne Message erofgeet. Grouss Messagen tendéieren wäertvoll ze sinn wann se an enger aggregéierter Form gekuckt ginn.

Héich Disponibilitéit

Dem Kafka seng Approche fir héich Disponibilitéit ass ganz anescht wéi dem ActiveMQ seng Approche. Kafka ass ronderëm Skala-out Cluster entworf wou all Broker Instanzen Messagen zur selwechter Zäit kréien a verdeelen.

E Kafka Cluster besteet aus multiple Broker Instanzen déi op verschiddene Server lafen. Kafka gouf entwéckelt fir op gewéinlech Standalone Hardware ze lafen, wou all Node seng eegen dedizéierten Späichere huet. D'Benotzung vun Network Attached Storage (SAN) ass net recommandéiert well verschidde Rechenknäppchen fir Zäit konkurréiere kënnen.Ыe Stockage Intervalle a schafen Konflikter.

Kafka ass ëmmer op System. Vill grouss Kafka Benotzer hunn hir Cluster ni zougemaach an d'Software aktualiséiert ëmmer mat engem sequentielle Restart. Dëst gëtt erreecht andeems Dir Kompatibilitéit mat der viregter Versioun fir Messagen an Interaktiounen tëscht Broker garantéiert.

Courtiere verbonne mat engem Servercluster ZooKeeper, déi als Konfiguratiounsdatenregistrierung handelt a benotzt gëtt fir d'Rollen vun all Broker ze koordinéieren. ZooKeeper selwer ass e verdeelt System deen héich Disponibilitéit ubitt duerch d'Replikatioun vun Informatioun andeems se etabléiert quorum.

Am Basisfall gëtt en Thema an engem Kafka-Cluster erstallt mat de folgenden Eegeschaften:

  • D'Zuel vun de Partitionen. Wéi virdru diskutéiert, hänkt de genaue Wäert deen hei benotzt vum gewënschten Niveau vun der parallele Liesung of.
  • De Replikatiounsfaktor (Faktor) bestëmmt wéivill Broker-Instanzen am Cluster Logbicher fir dës Partition enthalen.

Benotzt ZooKeepers fir Koordinatioun, Kafka probéiert nei Partitionen gerecht ze verdeelen ënner de Broker am Cluster. Dëst gëtt vun enger eenzeger Instanz gemaach déi als Controller handelt.

An der Runtime fir all Thema Partition Kontroller Rollen un engem Broker zouginn Leader (Leader, Meeschter, Presentateur) an Matleefer (Unhänger, Sklaven, Ënneruerter). De Broker, deen als Leader fir dës Partition handelt, ass verantwortlech fir all d'Messagen ze kréien, déi vun de Produzenten geschéckt ginn an d'Messagen un d'Konsumenten ze verdeelen. Wann Messagen op eng Themapartition geschéckt ginn, gi se op all Brokernoden replizéiert, déi als Follower fir dës Partition handelen. All Node mat Logbicher fir eng Partition gëtt genannt replica. E Broker kann als Leader fir e puer Partitionen handelen an als Follower fir anerer.

E Follower deen all Messagen enthält, déi vum Leader gehal ginn, gëtt genannt synchroniséiert Replika (eng Replik déi an engem synchroniséierten Zoustand ass, in-synchroniséiert Replika). Wann e Broker, deen als Leader fir eng Partition handelt, erof geet, kann all Broker deen aktuell ass oder synchroniséiert ass fir dës Partition d'Leaderroll iwwerhuelen. Et ass en onheemlech nohaltege Design.

En Deel vun der Produzent Konfiguratioun ass de Parameter acks, wat feststellt wéivill Repliken d'Empfang vun engem Message unerkennen (erkennen) musse ier den Applikatiouns thread weider schéckt: 0, 1 oder all. Wann opgestallt all, dann, wann e Message kritt ass, schéckt de Leader eng Bestätegung zréck un de Produzent soubal en Bestätegungen (Unerkennungen) vum Rekord aus e puer Hiweiser kritt (och selwer) definéiert vum Thema Astellung min.insync.repliken (Standard 1). Wann de Message net erfollegräich replizéiert ka ginn, da werft de Produzent eng Applikatioun Ausnam (NotEnoughReplicas oder NotEnoughReplicasAfterAppend).

Eng typesch Konfiguratioun erstellt en Thema mat engem Replikatiounsfaktor vun 3 (1 Leader, 2 Follower pro Partition) an de Parameter min.insync.repliken ass op 2 gesat. An dësem Fall erlaabt de Stärekoup ee vun de Brokeren, déi d'Themapartition verwalten, erof goen ouni Clientapplikatiounen ze beaflossen.

Dëst bréngt eis zréck op de scho vertraute Commerce tëscht Leeschtung an Zouverlässegkeet. Replikatioun geschitt op Käschte vun zousätzlech Waardezäit fir Bestätegungen (Unerkennungen) vun Unhänger. Obwuel, well et parallel leeft, Replikatioun op mindestens dräi Wirbelen huet déi selwecht Leeschtung wéi zwee (d'Erhéijung vun der Netzbandbreedung ignoréiert).

Andeems Dir dëst Replikatiounsschema benotzt, vermeit de Kafka clever de Besoin fir all Message kierperlech op Disk mat der Operatioun ze schreiwen sync(). All Message, déi vum Produzent geschéckt gëtt, gëtt an de Partitionsprotokoll geschriwwe ginn, awer wéi am Kapitel 2 diskutéiert gëtt, gëtt d'Schreiwen op eng Datei am Ufank am Buffer vum Betribssystem gemaach. Wann dëse Message op eng aner Kafka Instanz replizéiert gëtt an a senger Erënnerung ass, heescht de Verloscht vum Leader net datt de Message selwer verluer ass - et kann duerch eng synchroniséiert Replik iwwerholl ginn.
Refus fir d'Operatioun ze maachen sync() heescht datt de Kafka Messagen esou séier ka kréien wéi se an d'Erënnerung schreiwen. Ëmgekéiert, wat Dir méi laang kënnt vermeiden datt d'Erënnerung op den Disk spülen, wat besser. Aus dësem Grond ass et net ongewéinlech datt Kafka Broker 64 GB oder méi Erënnerung zougewisen hunn. Dës Gedächtnisverbrauch bedeit datt eng eenzeg Kafka Instanz einfach mat Geschwindegkeete vill Dausende Mol méi séier lafe kann wéi en traditionelle Message Broker.

Kafka kann och konfiguréiert ginn fir d'Operatioun z'applizéieren sync() Paketen ze mellen. Well alles am Kafka Package-orientéiert ass, funktionnéiert et tatsächlech ganz gutt fir vill Benotzungsfäll an ass en nëtzlecht Tool fir Benotzer déi ganz staark Garantien erfuerderen. Vill vun der purer Leeschtung vu Kafka kënnt aus de Messagen, déi un de Broker als Päck geschéckt ginn an datt dës Messagen vum Broker a sequentiellen Blocken gelies ginn null Kopie Operatiounen (Operatiounen während deenen d'Aufgab fir Daten aus engem Erënnerungsberäich an en anert ze kopéieren net ausgefouert gëtt). Déi lescht ass e grousse Leeschtungs- a Ressourcegewënn an ass nëmme méiglech duerch d'Benotzung vun enger ënnerierdesch Logdatenstruktur déi de Partitionsschema definéiert.

Vill besser Leeschtung ass méiglech an engem Kafka Cluster wéi mat engem eenzege Kafka Broker, well Thema Partitionen iwwer vill separat Maschinnen ausskalen kënnen.

Resultater

An dësem Kapitel hu mir gekuckt wéi d'Kafka Architektur d'Relatioun tëscht Clienten a Broker nei virstellt fir eng onheemlech robust Messagerie Pipeline ze bidden, mat Duerchsatz vill Mol méi grouss wéi dee vun engem konventionelle Message Broker. Mir hunn d'Funktionalitéit diskutéiert déi se benotzt fir dëst z'erreechen a kuerz d'Architektur vun Uwendungen gekuckt déi dës Funktionalitéit ubidden. Am nächste Kapitel wäerte mir allgemeng Probleemer kucken, déi Messagerie-baséiert Uwendungen brauchen fir Strategien ze léisen an ze diskutéieren fir mat hinnen ze handelen. Mir wäerten d'Kapitel ofschléissen andeems Dir beschriwwe gëtt wéi Dir iwwer Messagerietechnologien am Allgemengen schwätzt, sou datt Dir hir Gëeegentheet fir Är Benotzungsfäll evaluéiere kënnt.

Virdrun iwwersat Deel: Verstoen Message Courtiere. Léiert d'Mechanik vu Messagerie mat ActiveMQ a Kafka. Kapitel 1

Iwwersetzung gemaach: tele.gg/middle_java

Fir weidergitt ...

Nëmme registréiert Benotzer kënnen un der Ëmfro deelhuelen. Umellen, wann ech glift.

Ass Kafka an Ärer Organisatioun benotzt?

  • datt

  • Nee

  • Fréier benotzt, elo net

  • Mir plangen ze benotzen

38 Benotzer hunn gestëmmt. 8 Benotzer hu sech enthalen.

Source: will.com

Setzt e Commentaire