{"id":52525,"date":"2019-11-10T00:00:00","date_gmt":"2019-11-09T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah"},"modified":"2020-02-18T14:00:16","modified_gmt":"2020-02-18T11:00:16","slug":"rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","title":{"rendered":"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/d8e584d210a6a016a962ad6f956a2078.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFejltolerance og h\u00f8j tilg\u00e6ngelighed er store emner, s\u00e5 vi vil dedikere separate artikler til RabbitMQ og Kafka. Denne artikel handler om RabbitMQ, mens den n\u00e6ste vil v\u00e6re om Kafka i sammenligning med RabbitMQ. Artiklen er lang, s\u00e5 g\u00f8r dig komfortabel.<\/p>\n<p>Lad os se p\u00e5 strategier for fejltolerance, konsistens og h\u00f8j tilg\u00e6ngelighed (HA), samt de kompromiser, der er n\u00f8dvendige i hver strategi. RabbitMQ kan k\u00f8re p\u00e5 et cluster af noder \u2014 og klassificeres s\u00e5 som et distribueret system. N\u00e5r vi taler om distribuerede systemer, handler det ofte om konsistens og tilg\u00e6ngelighed. <\/p>\n<p>Disse begreber beskriver, hvordan systemet opf\u00f8rer sig ved fejl. Fejl i netv\u00e6rksforbindelsen, serverfejl, harddiskfejl, midlertidig utilg\u00e6ngelighed af serveren p\u00e5 grund af affaldssamling, pakke tab eller langsom netv\u00e6rksforbindelse. Alt dette kan f\u00f8re til datatab eller konflikter. Det viser sig, at det n\u00e6rmest er umuligt at have et system, der er b\u00e5de fuldst\u00e6ndig konsistent (uden datatab, uden datainkonsekvenser) og tilg\u00e6ngeligt (det vil tage l\u00e6se- og skriveoperationer) under alle fejlsituationer.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nVi vil se, at konsistens og tilg\u00e6ngelighed befinder sig p\u00e5 forskellige ender af spektret, og du skal v\u00e6lge, hvilken retning du vil optimere imod. Den gode nyhed er, at med RabbitMQ er s\u00e5dan et valg muligt. Du har nogle \"n\u00f8rdede\" kontrolknapper, s\u00e5 du kan justere balancen mod mere konsistens eller mere tilg\u00e6ngelighed.<\/p>\n<p>Vi vil s\u00e6tte fokus p\u00e5, hvilke konfigurationer der f\u00f8rer til datatab p\u00e5 grund af bekr\u00e6ftede opskrivninger. Der er et ansvarssamarbejde mellem udgivere, brokere og forbrugere. N\u00e5r en besked overdrages til brokeren, er det dens opgave at ikke miste beskeden. N\u00e5r brokeren bekr\u00e6fter over for udgiveren, at den har modtaget beskeden, forventer vi ikke, at den g\u00e5r tabt. Men vi vil se, at det faktisk kan ske, afh\u00e6ngigt af konfigurationen af din broker og udgiver.<\/p>\n<h1>Primitiver for et enkelt nodes robusthed<\/h1>\n<p><\/p>\n<h3>Robuste k\u00f8er\/routing<\/h3>\n<p>\nI RabbitMQ findes der to typer af k\u00f8er: langvarige\/vedholdende (durable) og ikke vedholdende (non-durable). Alle k\u00f8er gemmes i Mnesia-databasen. Vedholdende k\u00f8er erkl\u00e6res igen ved opstart af noden og overlever dermed genstart, systemfejl eller servernedbrud (s\u00e5 l\u00e6nge dataene bevares). Dette betyder, at s\u00e5 l\u00e6nge du erkl\u00e6rer routing (exchange) og k\u00f8en som vedholdende, vil k\u00f8- og routinginfrastrukturen komme tilbage i drift.<\/p>\n<p>Ikke-vedholdende k\u00f8er og routing fjernes ved genstart af noden.<\/p>\n<h3>Vedholdende beskeder<\/h3>\n<p>\nAt en k\u00f8 er holdbar, betyder ikke, at alle dens beskeder overlever genstart af noden. Kun de beskeder, der er markeret af udgiveren som <i>vedholdende<\/i> (persistent), vil blive genoprettet. Vedholdende beskeder skaber faktisk ekstra belastning p\u00e5 brokeren, men hvis tab af beskeder ikke er acceptabelt, er der ingen anden udvej.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/8b8e2de4ef82bf8497960657aac0ddb0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 1. Vedholdenhedsmatrix<\/i><\/p>\n<h1>Klyngedannelse med k\u00f8spejling<\/h1>\n<p>\nFor at overleve tab af brokeren har vi brug for redundans. Vi kan samle flere RabbitMQ-noder i en klynge og derefter tilf\u00f8je yderligere redundans ved at replikere k\u00f8erne mellem flere noder. P\u00e5 denne m\u00e5de, hvis en node fejler, taber vi ikke data og forbliver tilg\u00e6ngelige. <\/p>\n<p>K\u00f8spejling:<\/p>\n<ul>\n<li>\u00e9n hovedk\u00f8 (master), der modtager alle kommandoer til skrivning og l\u00e6sning\n<\/li>\n<li>en eller flere spejle, der modtager alle beskeder og metadata fra hovedk\u00f8en. Disse spejle findes ikke til skalering, men udelukkende til redundans.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/35f3d4bdc4f5e10da0e40eb91c5d8280.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 2. K\u00f8spejling<\/i><\/p>\n<p>Spejling oprettes med den relevante politik. Her kan du v\u00e6lge replikationsfaktoren og endda de noder, som k\u00f8en skal placeres p\u00e5. Eksempler:<\/p>\n<ul>\n<li><code>ha-mode: all<\/code>\n<\/li>\n<li><code>ha-mode: exactly, ha-params: 2<\/code> (\u00e9n master og \u00e9t spejl)\n<\/li>\n<li><code>ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2<\/code><\/li>\n<\/ul>\n<p><\/p>\n<h1>Bekr\u00e6ftelse til udgiveren<\/h1>\n<p>\nFor achieving consistent recording, publisher confirmations are necessary. Without them, there is a risk of message loss. Confirmation is sent to the publisher after the message has been written to disk. RabbitMQ writes messages to disk not upon receipt, but periodically, within a few hundred milliseconds. When a queue is mirrored, confirmation is sent only after all mirrors have also written their copy of the message to disk. This means that using confirmations introduces latency, but if data security is important, they are essential.<\/p>\n<h1>Fejlsikker k\u00f8<\/h1>\n<p>\nWhen the broker shuts down or crashes, all leading queues (masters) on that node also go down with it. The cluster then selects the oldest mirror of each master and promotes it as the new master.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/8d8227c00643f35e0dc752b6617e18fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 3. Several mirrored queues and their policies<\/i><\/p>\n<p>Broker 3 crashes. Note that the mirror of Queue C on Broker 2 is promoted to master. Also, note that a new mirror for Queue C is created on Broker 1. RabbitMQ always attempts to maintain the replication factor specified in your policies.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/d08b3ada22e79686d448714f7bab009a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 4. Broker 3 crashes, causing the failure of Queue C<\/i> <\/p>\n<p>Next, Broker 1 crashes! We are left with only one broker. The mirror of Queue B is promoted to master.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/dcc1d542c40c441194fd07e51046c619.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 5<\/i><\/p>\n<p>We have restored Broker 1. Regardless of how successfully the data survived the loss and recovery of the broker, all mirrored queue messages are discarded upon restart. It is important to note this, as there will be consequences. We will soon look at these consequences. Thus, Broker 1 is now again a member of the cluster, and the cluster tries to comply with the policies and therefore creates mirrors on Broker 1.<\/p>\n<p>In this case, the loss of Broker 1 was complete, as was the loss of data, so the unmirrored Queue B is completely lost.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/7ac7ab65ea6dff9c5a49372c04c83a37.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 6. Broker 1 returns to service<\/i><\/p>\n<p>Broker 3 er tilbage i drift, s\u00e5 k\u00f8erne A og B f\u00e5r deres oprettede spejle tilbage for at opfylde deres HA-politikker. Men nu er alle hovedk\u00f8er p\u00e5 \u00e9n node! Dette er ikke ideelt; en bedre fordeling mellem noderne ville v\u00e6re at foretr\u00e6kke. Desv\u00e6rre er der ikke mange muligheder for genbalancering af mestre her. Vi kommer tilbage til dette problem senere, da vi f\u00f8rst skal se p\u00e5 synkroniseringen af k\u00f8en. <\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/a54e53bb01e2f830a54f88acaa668984.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 7. Broker 3 vender tilbage i drift. Alle hovedk\u00f8er er p\u00e5 \u00e9n node!<\/i><\/p>\n<p>S\u00e5ledes skulle du nu have en id\u00e9 om, hvordan spejle sikrer redundans og fejltolerance. Dette garanterer tilg\u00e6ngelighed i tilf\u00e6lde af, at \u00e9n node fejler, og beskytter mod datatab. Men vi er stadig ikke f\u00e6rdige, for det hele er meget mere kompliceret.<\/p>\n<h1>Synkronisering<\/h1>\n<p>\nN\u00e5r et nyt spejl oprettes, vil alle nye beskeder altid blive replikeret til dette spejl og eventuelle andre. Hvad ang\u00e5r de eksisterende data i hovedk\u00f8en, kan vi replikere dem til det nye spejl, s\u00e5 det bliver en fuldst\u00e6ndig kopi af mesteren. Vi kan ogs\u00e5 v\u00e6lge ikke at replikere de eksisterende beskeder og lade hovedk\u00f8en og det nye spejl synkronisere over tid, hvor nye beskeder tilf\u00f8jes i halen, mens eksisterende beskeder fjernes fra hovedk\u00f8ens hoved.<\/p>\n<p>Denne synkronisering udf\u00f8res automatisk eller manuelt og styres vha. k\u00f8politikker. Lad os se p\u00e5 et eksempel.<\/p>\n<p>Vi har to spejlede k\u00f8er. K\u00f8 A synkroniseres automatisk, mens K\u00f8 B synkroniseres manuelt. Begge k\u00f8er indeholder ti beskeder.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/304f2a475fdd0cb6d3069140c667a0a7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 8. To k\u00f8er med forskellige synkroniseringsmetoder<\/i><\/p>\n<p>Nu mister vi Broker 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/49114966f440c407488bb467ff6dbf93.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 9. Broker 3 er nede<\/i><\/p>\n<p>Broker 3 er tilbage i drift. Klyngen opretter et spejl for hver k\u00f8 p\u00e5 en ny node og synkroniserer automatisk den nye K\u00f8 A med mesteren. Dog forbliver spejlet for den nye K\u00f8 B tomt. S\u00e5ledes har vi fuld redundans for K\u00f8 A og kun \u00e9t spejl for eksisterende beskeder i K\u00f8 B.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/adffc1f5eff8806edbd83772f338d67f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 10. Det nye spejl for K\u00f8 A modtager alle eksisterende beskeder, mens det nye spejl for K\u00f8 B ikke g\u00f8r.<\/i><\/p>\n<p>I begge k\u00f8er modtages der yderligere ti beskeder. Derefter falder Broker 2, og K\u00f8 A rulles tilbage til det \u00e6ldste spejl, som findes p\u00e5 Broker 1. Der sker ingen datatab ved nedbrud. I K\u00f8 B er der tyve beskeder i masteren og kun ti i spejlet, da denne k\u00f8 aldrig har replikeret de oprindelige ti beskeder.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/c6cfef4bced5627bf243c2f020a42646.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 11. K\u00f8 A rulles tilbage til Broker 1 uden tab af beskeder<\/i><\/p>\n<p>I begge k\u00f8er modtages der endnu ti beskeder. Nu falder Broker 1. K\u00f8 A skifter uden problemer til spejlet uden tab af beskeder. Men K\u00f8 B f\u00e5r problemer. P\u00e5 dette tidspunkt kan vi optimere enten tilg\u00e6ngeligheden eller konsistensen. <\/p>\n<p>Hvis vi vil optimere tilg\u00e6ngeligheden, s\u00e5 skal politikken <b><i>ha-promote-on-failure<\/i><\/b> s\u00e6ttes til <b><i>always<\/i><\/b>. Denne v\u00e6rdi er standarden, s\u00e5 man kan ganske enkelt undlade at angive politikken overhovedet. I s\u00e5 fald tillader vi reelt fejl i usynkroniserede spejle. Dette vil f\u00f8re til tab af beskeder, men k\u00f8en forbliver tilg\u00e6ngelig for l\u00e6sning og skrivning.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/cd704cf4397184c212e1576b986abbaa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 12. K\u00f8 A rulles tilbage til Broker 3 uden tab af beskeder. K\u00f8 B rulles tilbage til Broker 3 med tab af ti beskeder<\/i><\/p>\n<p>Vi kan ogs\u00e5 indstille <code>ha-promote-on-failure<\/code> til v\u00e6rdien <code>when-synced<\/code>. I dette tilf\u00e6lde vil k\u00f8en vente, indtil Broker 1 med sine data vender tilbage til drift. Efter hans tilbagevenden vil hovedk\u00f8en igen befinde sig p\u00e5 Broker 1 uden tab af data. Tilg\u00e6ngeligheden ofres for datasikkerhed. Men dette er en risikabel tilstand, som kan f\u00f8re til endda total datatab, hvilket vi vil se n\u00e6rmere p\u00e5 snart.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/03fed936fe75220e22f68432ca81b654.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 13. K\u00f8 B forbliver utilg\u00e6ngelig efter tabet af Broker 1<\/i><\/p>\n<p>Du kan stille sp\u00f8rgsm\u00e5let: \u00abM\u00e5ske er det bedre aldrig at bruge automatisk synkronisering?\u00bb. Svaret er, at synkronisering er en blokkerende operation. Under synkroniseringen kan hovedk\u00f8en ikke udf\u00f8re nogen l\u00e6se- eller skriveoperationer!<\/p>\n<p>Lad os overveje et eksempel. Vi har nu meget store k\u00f8er. Hvordan kan de vokse til denne st\u00f8rrelse? Af flere grunde:<\/p>\n<ul>\n<li>K\u00f8erne er ikke aktive\n<\/li>\n<li>Dette er h\u00f8jhastighedsk\u00f8er, og lige nu arbejder forbrugerne langsomt \n<\/li>\n<li>Dette er h\u00f8jhastighedsk\u00f8er, der har lidt et nedbrud, og forbrugerne indhenter<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/dd4b0fd70cbbc0b7defc06536157770d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 14. To store large queues with different synchronization modes<\/i><\/p>\n<p>Now Broker 3 goes down.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/8c31cfdf485ab4c9dfe13e86a151df4f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 15. Broker 3 is down, leaving one master and one mirror in each queue<\/i><\/p>\n<p>Broker 3 comes back online, and new mirrors are created. Main Queue A starts replicating existing messages to the new mirror, during which time the queue is unavailable. It takes two hours to replicate the data, leading to two hours of downtime for this Queue!<\/p>\n<p>However, Queue B remains available throughout this period. It sacrificed some redundancy for availability.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/28e641300a1c3f4d70e29a16db51521e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 16. The queue remains unavailable during synchronization<\/i><\/p>\n<p>After two hours, Queue A also becomes available again and can resume read and write operations.<\/p>\n<h3>Opdateringer<\/h3>\n<p>\nThis blocking behavior during synchronization complicates cluster updates with very large queues. At some point, the node with the master needs to be restarted, which means either switching to the mirror or taking the queue offline during the server update. If we choose to switch, we will lose messages if the mirrors are not synchronized. By default, during broker shutdown, switching to an unsynchronized mirror does not occur. This means that as soon as the broker returns, we do not lose any messages, the only damage was the downtime of the queue. The behavior rules for broker shutdown are set by the policy <code>ha-promote-on-shutdown<\/code>. You can set one of two values:<\/p>\n<ul>\n<li><code>always<\/code>= enable the transition to unsynchronized mirrors\n<\/li>\n<li><code>when-synced<\/code>= switch only to a synchronized mirror; otherwise, the queue becomes unavailable for reading and writing. The queue comes back online as soon as the broker returns<\/li>\n<\/ul>\n<p>\nEither way, with large queues, you have to choose between data loss and unavailability.<\/p>\n<h3>When availability enhances data security<\/h3>\n<p>\nBefore making a decision, one more complication needs to be considered. Although automatic synchronization is better for redundancy, how does it affect data security? Of course, with better redundancy, RabbitMQ is less likely to lose existing messages, but what about new messages from publishers?<\/p>\n<p>Here are some key points to consider:<\/p>\n<ul>\n<li>Kan en udgiver bare returnere en fejl, og kan den overordnede tjeneste eller bruger fors\u00f8ge igen senere?\n<\/li>\n<li>Kan en udgiver gemme meddelelsen lokalt eller i en database, s\u00e5 den kan fors\u00f8ge igen senere?<\/li>\n<\/ul>\n<p>\nHvis udgiveren kun kan kassere meddelelsen, forbedrer tilg\u00e6ngeligheden i virkeligheden ogs\u00e5 datasikkerheden.<\/p>\n<p>Derfor skal der s\u00f8ges efter en balance, og l\u00f8sningen afh\u00e6nger af den specifikke situation.<\/p>\n<h1>Problemer med ha-promote-on-failure=when-synced<\/h1>\n<p>\nId\u00e9 <i><b>ha-promote-on-failure<\/b><\/i>= <i><b>when-synced<\/b><\/i> ligger i, at vi forhindrer skift til et usynkroniseret spejl og dermed undg\u00e5r datatab. K\u00f8en forbliver utilg\u00e6ngelig for l\u00e6sning eller skrivning. I stedet fors\u00f8ger vi at genoprette den faldne broker med intakt data, s\u00e5 den kan genoptage driften som master uden datatab. <\/p>\n<p>Men (og det er et stort men) hvis brokeren har mistet sine data, har vi et stort problem: k\u00f8en er tabt! Alle data er v\u00e6k! Selvom du har spejle, der hovedsageligt indhenter den prim\u00e6re k\u00f8, bliver disse spejle ogs\u00e5 kassere.<\/p>\n<p>For at tilf\u00f8je en node med det samme navn igen, beder vi klusteret om at glemme den tabte node (ved hj\u00e6lp af kommandoen <i>rabbitmqctl forget_cluster_node<\/i>) og starte en ny broker med det samme v\u00e6rtsnavn. S\u00e5 l\u00e6nge klusteret husker den tabte node, husker det den gamle k\u00f8 og usynkroniserede spejle. N\u00e5r klusteret beordres til at glemme den tabte node, glemmes denne k\u00f8 ogs\u00e5. Den skal nu deklareres igen. Vi har mistet alle data, selvom vi havde spejle med en delm\u00e6ngde af data. Det ville have v\u00e6ret bedre at skifte til et usynkroniseret spejl!<\/p>\n<p>Derfor er manuel synkronisering (og undg\u00e5else af synkronisering) kombineret med <code>ha-promote-on-failure=when-synced<\/code>, efter min mening, ret risikabelt. Dokumenter siger, at denne mulighed eksisterer for datasikkerhed, men det er en tve\u00e6gget sv\u00e6rd.<\/p>\n<h1>Masterforbalancering<\/h1>\n<p>\nSom lovet vender vi tilbage til problemet med, at alle mastere samles p\u00e5 en eller flere noder. Dette kan ske selv som f\u00f8lge af en \"rolling\" opdatering af klusteret. I et kluster med tre noder kan alle hovedk\u00f8er samle sig p\u00e5 en eller to noder.<\/p>\n<p>Masterforbalancering kan vise sig at v\u00e6re problematisk af to grunde:<\/p>\n<ul>\n<li>Der er ikke gode v\u00e6rkt\u00f8jer til at udf\u00f8re forbalancering<\/li>\n<li>Synkronisering af k\u00f8er<\/li>\n<\/ul>\n<p>\nFor at omfordele er der en tredjepart <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Ayanda-D\/rabbitmq-queue-master-balancer\">plugin<\/a><\/noindex>, som ikke underst\u00f8ttes officielt. Med hensyn til tredjeparts plugins i RabbitMQ's vejledning <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/upgrade.html\">siges der<\/a><\/noindex>: \u00abPlugin'et giver nogle ekstra konfigurations- og rapporteringsv\u00e6rkt\u00f8jer, men det underst\u00f8ttes ikke og er ikke testet af RabbitMQ-holdet. Brug det p\u00e5 egen risiko\u00bb.<\/p>\n<p>Der er ogs\u00e5 et andet trick til at flytte hovedk\u00f8en via HA-politikker. Det n\u00e6vnes i vejledningen <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/rabbitmq\/support-tools\/blob\/master\/scripts\/rebalance-queue-masters\">script<\/a><\/noindex> til dette. Det fungerer p\u00e5 f\u00f8lgende m\u00e5de:<\/p>\n<ul>\n<li>Fjerner alle spejle med en midlertidig politik med h\u00f8jere prioritet end den eksisterende HA-politik.\n<\/li>\n<li>\u00c6ndrer den midlertidige HA-politik til at bruge 'noder'-modus og angiver den node, som hovedk\u00f8en skal flyttes til.\n<\/li>\n<li>Synkroniserer k\u00f8en for at tvinge migration.\n<\/li>\n<li>N\u00e5r migrationen er afsluttet, slettes den midlertidige politik. Den oprindelige HA-politik tr\u00e6der i kraft, og det \u00f8nskede antal spejle oprettes.<\/li>\n<\/ul>\n<p>\nUlempen er, at denne tilgang m\u00e5ske ikke fungerer, hvis du har store k\u00f8er eller strenge redundanskrav.<\/p>\n<p>Lad os nu se p\u00e5, hvordan RabbitMQ-klynger fungerer med netv\u00e6rksopdelinger.<\/p>\n<h1>Netv\u00e6rkstilkoblingsbrud<\/h1>\n<p>\nNoderne i et distribueret system forbindes via netv\u00e6rkstilkoblinger, og netv\u00e6rksforbindelser kan og vil blive brudt. Hyppigheden af afbrydelser afh\u00e6nger af den lokale infrastruktur eller p\u00e5lideligheden af den valgte sky. Under alle omst\u00e6ndigheder skal distribuerede systemer v\u00e6re i stand til at h\u00e5ndtere dem. Igen st\u00e5r vi overfor valget mellem tilg\u00e6ngelighed og konsistens, og igen er den gode nyhed, at RabbitMQ tilbyder begge muligheder (bare ikke samtidigt).<\/p>\n<p>Med RabbitMQ har vi to hovedmuligheder:<\/p>\n<ul>\n<li>Tillade logisk adskillelse (split-brain). Det sikrer tilg\u00e6ngelighed, men kan medf\u00f8re datatab.\n<\/li>\n<li>Forbyde logisk adskillelse. Kan f\u00f8re til kortvarigt tab af tilg\u00e6ngelighed afh\u00e6ngigt af, hvordan kunderne forbinder til klyngen. Kan ogs\u00e5 resultere i total utilg\u00e6ngelighed i klyngen af to noder.<\/li>\n<\/ul>\n<p>\nMen hvad er logisk adskillelse? Det er, n\u00e5r klyngen opdeles i to p\u00e5 grund af tab af netv\u00e6rksforbindelser. P\u00e5 hver side h\u00e6ves spejlene til mestre, s\u00e5 der i sidste ende er flere mestre pr. k\u00f8.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/d880a935df450fb994edfed0715e026e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 17. Hovedk\u00f8en og to spejle, hver p\u00e5 en separat node. Derefter opst\u00e5r der et netv\u00e6rksfejl, og et spejl adskilles. Den adskilte node ser, at de to andre er faldet fra, og opgraderer sine spejle til master. Nu har vi to hovedk\u00f8er, og begge tillader skrivning og l\u00e6sning.<\/i> <\/p>\n<p>Hvis udgivere sender data til begge mestre, f\u00e5r vi to divergerende kopier af k\u00f8en.<\/p>\n<p>De forskellige tilstande i RabbitMQ sikrer enten tilg\u00e6ngelighed eller konsistens.<\/p>\n<h3>Ignore-tilstand (standard)<\/h3>\n<p>\nDenne tilstand sikrer tilg\u00e6ngelighed. Efter tab af forbindelsen sker der en logisk opdeling. Efter genoprettelse af forbindelsen skal administratoren beslutte, hvilken sektion der skal foretr\u00e6kkes. Den tabende side vil blive genstartet, og alle akkumulerede data fra denne side g\u00e5r tabt.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/4d82c13b5ef21837ba819f5c246a1e41.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 18. Tre udgivere er forbundet til tre m\u00e6glere. Internt dirigerer klyngen alle anmodninger til hovedk\u00f8en p\u00e5 Broker 2.<\/i><\/p>\n<p>Nu mister vi Broker 3. Den ser, at de andre m\u00e6glere er faldet fra, og opgraderer sit spejl til master. S\u00e5 sker der en logisk opdeling.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/c7e01d51b24023bacdd93cfad95c9eab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 19. Logisk opdeling (split-brain). Skrivninger g\u00e5r til to hovedk\u00f8er, og to kopier divergerer.<\/i><\/p>\n<p>Forbindelsen genoprettes, men den logiske opdeling forbliver. Administratoren skal manuelt v\u00e6lge den tabende side. I det f\u00f8lgende tilf\u00e6lde genstarter administratoren Broker 3. Alle meddelelser, som den ikke kunne overf\u00f8re, g\u00e5r tabt.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/51c3ee15024d3c83ba625e3ff9cdeb90.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 20. Administratoren deaktiverer Broker 3.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/0bac8e33de25c0c5381d336d26464858.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 21. Administratoren starter Broker 3, og den tilslutter sig klyngen, mens den mister alle meddelelser, der var der.<\/i><\/p>\n<p>Under tab af forbindelsen og efter genoprettelse var klyngen og denne k\u00f8 tilg\u00e6ngelige for l\u00e6sning og skrivning.<\/p>\n<h3>Autoheal-tilstand<\/h3>\n<p>\nFungerer p\u00e5 samme m\u00e5de som Ignore-tilstanden, bortset fra at klyngen automatisk v\u00e6lger den tabende side efter opdeling og genoprettelse af forbindelsen. Den tabende side genoptages i klyngen tom, og k\u00f8en mister alle meddelelser, der kun blev sendt til den side.<\/p>\n<h3>Pause Minority-tilstand<\/h3>\n<p>\nHvis vi ikke \u00f8nsker at tillade logisk opdeling, er vores eneste mulighed at undlade at l\u00e6se og skrive p\u00e5 den mindre side efter opdelingen af klyngen. N\u00e5r broker ser, at den er p\u00e5 den mindre side, stopper den arbejdet, lukker alle eksisterende forbindelser og afsl\u00e5r nye. En gang i sekundet tjekker den genoprettelsen af forbindelsen. S\u00e5 snart forbindelsen er genoprettet, genoptager den arbejdet og tilslutter sig klyngen.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/7a51cf509b2c94e2ae100c7dedd9d21a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 22. Tre publishere er forbundet til tre brokere. Internt dirigerer klyngen alle foresp\u00f8rgsler til hovedk\u00f8en p\u00e5 Broker 2.<\/i><\/p>\n<p>Derefter adskilles Brokere 1 og 2 fra Broker 3. I stedet for at opgradere sit spejl til master, stopper Broker 3 arbejdet og bliver utilg\u00e6ngelig.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/c12ec38a47e1f8ccceebfa1854f54f21.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 23. Broker 3 stopper arbejdet, afbryder alle kunder og afviser tilslutningsanmodninger.<\/i><\/p>\n<p>S\u00e5 snart forbindelsen er genoprettet, vender den tilbage til klyngen.<\/p>\n<p>Lad os se p\u00e5 et andet eksempel, hvor hovedk\u00f8en er p\u00e5 Broker 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/4cc6a28270f00a280ecb5af5252f4e07.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 24. Hovedk\u00f8en p\u00e5 Broker 3.<\/i><\/p>\n<p>Derefter sker der den samme forbindelsestab. Broker 3 g\u00e5r p\u00e5 pause, da den er p\u00e5 den mindre side. P\u00e5 den anden side ser noderne, at Broker 3 er faldet ud, s\u00e5 det \u00e6ldre spejl fra Broker 1 og 2 opgraderes til master.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/d0d032385533bb53c5a95927afcd3119.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 25. Overgang til Broker 2 ved utilg\u00e6ngelighed af Broker 3.<\/i><\/p>\n<p>N\u00e5r forbindelsen er genoprettet, vil Broker 3 slutte sig til klyngen.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger\" src=\"\/wp-content\/uploads\/2019\/11\/53f8186a040ae07724ef59cf79b72a0c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 26. Klyngen er vendt tilbage til normal drift.<\/i><\/p>\n<p>Det er vigtigt at forst\u00e5 her, at vi opn\u00e5r konsistens, men vi kan ogs\u00e5 opn\u00e5 tilg\u00e6ngelighed, <i><b>hvis<\/b><\/i> vi vil med succes overf\u00f8re kunderne til den st\u00f8rre del af sektionen. For de fleste situationer ville jeg personligt v\u00e6lge Pause Minority-tilstand, men det afh\u00e6nger reelt af den specifikke sag.<\/p>\n<p>For at sikre tilg\u00e6ngelighed er det vigtigt at sikre, at kunderne med succes tilslutter sig noden. Lad os overveje vores muligheder.<\/p>\n<h1>Sikring af kundernes forbindelse<\/h1>\n<p>\nVi har flere m\u00e5der at dirigere kunder tilbage til hoveddelen af klyngen eller til fungerende noder (efter at en node er fejlet) efter et tab af forbindelse. Lad os f\u00f8rst huske, at en bestemt k\u00f8 placeres p\u00e5 en bestemt node, men routingen og politikkerne replikers p\u00e5 alle noder. Kunderne kan oprette forbindelse til enhver node, og den interne routing vil lede dem det rigtige sted hen. Men n\u00e5r en node er sat p\u00e5 pause, afviser den forbindelser, s\u00e5 kunderne skal oprette forbindelse til en anden node. Hvis en node falder ud, kan den overhovedet ikke g\u00f8re meget.<\/p>\n<p>Vores muligheder:<\/p>\n<ul>\n<li>Adgang til klyngen sker via en load balancer, der simpelthen cykler gennem noderne, mens kunderne fors\u00f8ger at oprette forbindelse, indtil det lykkes. Hvis en node ikke fungerer eller er sat p\u00e5 pause, vil forbindelsesfors\u00f8gene til denne node mislykkes, men efterf\u00f8lgende fors\u00f8g vil g\u00e5 til andre servere (i cyklus). Dette er passende til kortvarigt tab af forbindelse eller en nede server, der hurtigt vil blive genoprettet.\n<\/li>\n<li>Adgang til klyngen via en load balancer og fjernelse af s\u00e6ttede\/nede noder fra listen, s\u00e5 snart de opdages. Hvis det g\u00f8res hurtigt, og hvis kunderne kan fors\u00f8ge at oprette forbindelse igen, vil vi opn\u00e5 konstant tilg\u00e6ngelighed.\n<\/li>\n<li>Giv hver kunde en liste over alle noder, og kunden v\u00e6lger en af dem tilf\u00e6ldigt, n\u00e5r de opretter forbindelse. Hvis de f\u00e5r en fejltagelse ved fors\u00f8g p\u00e5 forbindelse, g\u00e5r de videre til den n\u00e6ste node p\u00e5 listen, indtil de opretter forbindelse.\n<\/li>\n<li>Fjern trafik fra den nede\/satte node ved hj\u00e6lp af DNS. Dette g\u00f8res ved hj\u00e6lp af en lav TTL.<\/li>\n<\/ul>\n<p><\/p>\n<h1>Konklusioner<\/h1>\n<p>\nRabbitMQ-klyngedannelse har sine fordele og ulemper. De mest alvorlige ulemper er:<\/p>\n<ul>\n<li>ved tilslutning til klyngen kasserer noder deres data;\n<\/li>\n<li>blokgivende synkronisering f\u00f8rer til utilg\u00e6ngelighed af k\u00f8en.<\/li>\n<\/ul>\n<p>\nAlle vanskelige beslutninger udspringer fra disse to egenskaber ved arkitekturen. Hvis RabbitMQ kunne gemme data ved genforbindelse af klyngen, ville synkroniseringen v\u00e6re hurtigere. Hvis den kunne udf\u00f8re ikke-blokerende synkronisering, ville den bedre kunne underst\u00f8tte store k\u00f8er. At l\u00f8se disse to problemer ville seri\u00f8st forbedre RabbitMQ's ydeevne som en fejltolerant og h\u00f8jtilg\u00e6ngelig messaging-teknologi. Jeg vil ikke anbefale RabbitMQ med klyngefunktionalitet i f\u00f8lgende situationer:<\/p>\n<ul>\n<li>U p\u00e5lidelig netv\u00e6rk.\n<\/li>\n<li>U p\u00e5lidelig lagring.\n<\/li>\n<li>Meget store k\u00f8er.<\/li>\n<\/ul>\n<p>\nN\u00e5r det kommer til indstillinger for h\u00f8j tilg\u00e6ngelighed, kan du overveje f\u00f8lgende:<\/p>\n<ul>\n<li><code>ha-promote-on-failure=always<\/code>\n<\/li>\n<li><code>ha-sync-mode=manual<\/code>\n<\/li>\n<li><code>cluster_partition_handling=ignore<\/code> (eller <code>autoheal<\/code>)\n<\/li>\n<li>vedholdende meddelelser\n<\/li>\n<li>s\u00f8rg for, at klienter forbinder til den aktive knude, n\u00e5r en knude fejler<\/li>\n<\/ul>\n<p>\nFor konsistens (databeskyttelse) overvej f\u00f8lgende indstillinger:<\/p>\n<ul>\n<li>Publisher Confirms og Manual Acknowledgements p\u00e5 forbrugerens side\n<\/li>\n<li><code>ha-promote-on-failure=when-synced<\/code>, hvis udgiverne kan pr\u00f8ve igen senere, og hvis du har meget p\u00e5lidelig lagring! Ellers s\u00e6t <code>=always<\/code>.\n<\/li>\n<li><code>ha-sync-mode=automatic<\/code> (men for store inaktive k\u00f8er kan manuel tilstand v\u00e6re n\u00f8dvendig; overvej desuden, om utilg\u00e6ngelighed vil f\u00f8re til tab af meddelelser)\n<\/li>\n<li>Pause Minority-tilstand\n<\/li>\n<li>vedholdende meddelelser<\/li>\n<\/ul>\n<p>\nVi har endnu ikke d\u00e6kket alle emner vedr\u00f8rende fejltolerance og h\u00f8j tilg\u00e6ngelighed; for eksempel hvordan man sikkert udf\u00f8rer administrative procedurer (s\u00e5som glidende opgraderinger). Vi skal ogs\u00e5 tale om federering og Shovel-plugin.<\/p>\n<p>Hvis jeg har overset noget, s\u00e5 lad mig vide det.<\/p>\n<p>Se ogs\u00e5 min <noindex><a rel=\"nofollow\" href=\"https:\/\/jack-vanlightly.com\/blog\/2018\/9\/10\/how-to-lose-messages-on-a-rabbitmq-cluster\">post<\/a><\/noindex>, hvor jeg gennemf\u00f8rer eksperimenter i RabbitMQ-klyngen med Docker og Blockade for at teste nogle scenarier for meddelelsestab beskrevet i denne artikel.<\/p>\n<p>Tidligere artikler i serien: <br \/>\nNr. 1 \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/416629\/\">habr.com\/ru\/company\/itsumma\/blog\/416629<\/a><\/noindex> <br \/>\nNr. 2 \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/418389\/\">habr.com\/ru\/company\/itsumma\/blog\/418389<\/a><\/noindex> <br \/>\nNr. 3 \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/437446\/\">habr.com\/ru\/company\/itsumma\/blog\/437446<\/a><\/noindex><br \/>\n<br \/>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u2014 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0442\u0435\u043c\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0441\u0432\u044f\u0442\u0438\u043c RabbitMQ \u0438 Kafka \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438. \u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043e RabbitMQ, \u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u2014 \u043e Kafka, \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 RabbitMQ. \u0421\u0442\u0430\u0442\u044c\u044f \u0434\u043b\u0438\u043d\u043d\u0430\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0439\u0442\u0435\u0441\u044c \u043f\u043e\u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438, \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 (HA), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441\u044b, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0434\u0442\u0438 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. RabbitMQ \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-52525","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\".\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47RabbitMQ \u043f\u0440\u043e\u0442\u0438\u0432 Kafka: \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-09T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:16+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47RabbitMQ mod Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed i klynger | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47RabbitMQ \u043f\u0440\u043e\u0442\u0438\u0432 Kafka: \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u0445 | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost-v-klasterah","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-11-09T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:16+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52525","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 03:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:41:25","updated":"2026-01-24 03:54:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/52525","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=52525"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/52525\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=52525"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=52525"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=52525"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}