{"id":52541,"date":"2019-11-11T00:00:00","date_gmt":"2019-11-10T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost"},"modified":"2020-02-18T14:00:17","modified_gmt":"2020-02-18T11:00:17","slug":"rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","title":{"rendered":"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/6557ce69c2b3070622feca8b3c228b09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">den forrige artikel<\/a><\/noindex> Vi har unders\u00f8gt RabbitMQ-klyngedannelse for at sikre fejltolerance og h\u00f8j tilg\u00e6ngelighed. Lad os nu dykke dybere ned i Apache Kafka.<\/p>\n<p>Her er en reproduktionsenhed en partition. Hver topic har en eller flere partitioner. I hver partition er der en leder med eller uden f\u00f8lgere. Ved oprettelse af en topic angives antallet af partitioner og reproduktionsfaktoren. Den normale v\u00e6rdi er 3, hvilket betyder tre replikaer: en leder og to f\u00f8lgere.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/36deb6d506223c2ee2ec147d5c215789.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 1. Fire partitioner er fordelt mellem tre m\u00e6glere.<\/i><\/p>\n<p>Alle l\u00e6se- og skriveanmodninger g\u00e5r til lederen. F\u00f8lgerne sender regelm\u00e6ssigt anmodninger til lederen om at modtage de seneste beskeder. Forbrugere henvender sig aldrig til f\u00f8lgerne; de sidstn\u00e6vnte eksisterer kun for redundans og fejltolerance.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/715c51d75cb45863cfad4b37e81b9a9a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h1>Partitionsfejl<\/h1>\n<p>\nN\u00e5r en m\u00e6gler falder ud, stopper lederne af flere partitioner ofte med at fungere. I hver af dem bliver en f\u00f8lger fra en anden node leder. Dette er dog ikke altid tilf\u00e6ldet, da synkroniseringsfaktoren ogs\u00e5 spiller ind: om der er synkroniserede f\u00f8lgere, og hvis der ikke er, om overgangen til en usynkroniseret replika er tilladt. Men lad os ikke g\u00f8re det mere kompliceret.<\/p>\n<p>Broker 3 falder ud af netv\u00e6rket \u2014 og for partition 2 v\u00e6lges en ny leder p\u00e5 broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/b8cfce64cf6b848b0659de023f9d9b63.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 2. Broker 3 d\u00f8r, og dens f\u00f8lger p\u00e5 broker 2 v\u00e6lges som ny leder for partition 2.<\/i><\/p>\n<p>Derefter falder broker 1 ud, og partition 1 mister ogs\u00e5 sin leder; rollen overg\u00e5r til broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/9f5409c723da7ff059b93f9b23e7d5f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 3. Der er kun \u00e9n broker tilbage. Alle ledere er p\u00e5 samme broker med nul redundans.<\/i><\/p>\n<p>N\u00e5r broker 1 vender tilbage til netv\u00e6rket, tilf\u00f8jer den fire f\u00f8lgere, hvilket sikrer noget redundans til hver partition. Men alle ledere forbliver stadig p\u00e5 broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/f9c8e42f51258b7fd7f6f35dc7b8cc3b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 4. Lederne forbliver p\u00e5 broker 2.<\/i><\/p>\n<p>N\u00e5r broker 3 genstartes, vender vi tilbage til tre replikaer pr. partition. Men alle ledere forbliver stadig p\u00e5 broker 2.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/9c8c02be4161f8468b5dbc1e3f6ecb3a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 5. Ubalanceret placering af lederne efter genopretning af brokerne 1 og 3.<\/i><\/p>\n<p>Kafka har et v\u00e6rkt\u00f8j til en mere fintf\u00f8lende genbalancering af ledere end RabbitMQ. Der m\u00e5tte bruges et tredjepartsplugin eller script, der \u00e6ndrede politikkerne for migration af hovednoden ved at reducere redundansen under migreringen. Desuden m\u00e5tte der accepteres utilg\u00e6ngelighed under synkroniseringen for store k\u00f8er.<\/p>\n<p>Kafka har et koncept med \"foretrukne replikaer\" til lederrollen. N\u00e5r der oprettes partitioner af et emne, fors\u00f8ger Kafka at fordele lederne j\u00e6vnt over noderne og markerer disse f\u00f8rste ledere som foretrukne. Over tid kan lederne p\u00e5 grund af servergenstarter, fejl og forbindelse problemer befinde sig p\u00e5 andre noder, som i det ovenfor beskrevne ekstreme tilf\u00e6lde.<\/p>\n<p>For at rette op p\u00e5 dette tilbyder Kafka to muligheder:<\/p>\n<ul>\n<li>Mulighed <i>auto.leader.rebalance.enable=true<\/i> tillader kontrolnoden automatisk at genindse lederne til de foretrukne replikaer og dermed genoprette en j\u00e6vn fordeling.\n<\/li>\n<li>En administrator kan k\u00f8re skriptet <i>kafka-preferred-replica-election.sh<\/i> for at omfordele manuelt.<\/li>\n<\/ul>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/831930b06809637018fecb6d7d5a558d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 6. Replikater efter ombalancering<\/i><\/p>\n<p>Dette var en forenklet version af fejlen, men virkeligheden er mere kompleks, selvom intet her er for kompliceret. Det hele drejer sig om synkroniserede replikaer (In-Sync Replicas, ISR).<\/p>\n<h1>Synkroniserede replikaer (ISR)<\/h1>\n<p>\nISR er et s\u00e6t replikater af en partition, der betragtes som \"synkroniseret\". Her er der en leder, mens der m\u00e5ske ikke er nogen f\u00f8lgere. En f\u00f8lger betragtes som synkroniseret, hvis den har taget n\u00f8jagtige kopier af alle lederens meddelelser inden for intervallet <i>replica.lag.time.max.ms<\/i>.<\/p>\n<p>En f\u00f8lger fjernes fra ISR-s\u00e6ttet, hvis den:<\/p>\n<ul>\n<li>ikke har anmodet om at hente inden for intervallet <i>replica.lag.time.max.ms<\/i> (betegnes som d\u00f8d)\n<\/li>\n<li>ikke har haft tid til at opdatere sig inden for intervallet <i>replica.lag.time.max.ms<\/i> (betegnes som langsom)<\/li>\n<\/ul>\n<p>\nF\u00f8lgere anmoder om at hente inden for intervallet <i>replica.fetch.wait.max.ms<\/i>, som som standard er 500 ms.<\/p>\n<p>For klart at forklare form\u00e5let med ISR, skal vi se p\u00e5 bekr\u00e6ftelser fra producenten (producer) og nogle fejlscenarier. Producenterne kan v\u00e6lge, hvorn\u00e5r brokerne sender bekr\u00e6ftelse:<\/p>\n<ul>\n<li>acks=0, bekr\u00e6ftelse sendes ikke\n<\/li>\n<li>acks=1, bekr\u00e6ftelse sendes, efter at lederen har skrevet meddelelsen til sin lokale log\n<\/li>\n<li>acks=all, bekr\u00e6ftelse sendes, efter at alle replikaer i ISR har skrevet meddelelsen til deres lokale logs<\/li>\n<\/ul>\n<p>\nI Kafka-terminologi, hvis ISR har gemt meddelelsen, sker der en \u00abcommit\u00bb. Acks=all er den sikreste mulighed, men det medf\u00f8rer ogs\u00e5 en ekstra forsinkelse. Lad os se p\u00e5 to eksempler p\u00e5 fejl og hvordan de forskellige muligheder for 'acks' interagerer med konceptet ISR.<\/p>\n<h3>Acks=1 og ISR<\/h3>\n<p>\nI dette eksempel vil vi se, at hvis lederen ikke venter p\u00e5 at gemme hver besked fra alle f\u00f8lgere, kan der opst\u00e5 datatab ved lederfejl. Overgang til en usynkroniseret follower kan tillades eller forhindres ved indstilling <i>unclean.leader.election.enable<\/i>.<\/p>\n<p>I dette eksempel er acks=1 indstillet hos producenten. Partitionen er fordelt over de tre m\u00e6glere. Broker 3 er forsinket; han synkroniserede med lederen for otte sekunder siden og er nu forsinket med 7456 beskeder. Broker 1 er kun forsinket med en sekund. Vores producent sender en besked og modtager hurtigt et ack tilbage uden overhead fra langsomme eller d\u00f8de f\u00f8lgere, som lederen ikke venter p\u00e5.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/f194e6309b732b772574392eff482a8b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 7. ISR med tre replikaer<\/i><\/p>\n<p>Broker 2 fejler, og producenten modtager en forbindelsefejl. Efter overgangen til lederskabet til broker 1 mister vi 123 beskeder. Followeren p\u00e5 broker 1 var en del af ISR, men blev ikke helt synkroniseret med lederen, da han faldt.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/367f219daebafefe585059f67fdedf6f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 8. Beskeder g\u00e5r tabt ved fejl<\/i><\/p>\n<p>I konfigurationen <i>bootstrap.servers<\/i> er der angivet flere m\u00e6glere hos producenten, og han kan sp\u00f8rge en anden m\u00e6gler, hvem der blev den nye leder af partitionen. Derefter opretter han forbindelse til broker 1 og forts\u00e6tter med at sende beskeder.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/ba45c51f4ce1f63f10b2fa0e1487b223.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 9. Sending af beskeder genoptages efter en kort pause<\/i><\/p>\n<p>Broker 3 er endnu mere forsinket. Han anmoder om data, men kan ikke synkronisere. Dette kan skyldes en langsom netv\u00e6rksforbindelse mellem m\u00e6glere, lagringsproblemer osv. Han fjernes fra ISR. Nu best\u00e5r ISR kun af en replika \u2013 lederen! Producenten forts\u00e6tter med at sende beskeder og modtage bekr\u00e6ftelser.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/592c74632e3a8d80c2b4fc15bde5d401.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 10. Follower p\u00e5 broker 3 fjernes fra ISR<\/i><\/p>\n<p>Broker 1 falder, og lederrollen g\u00e5r til broker 3 med et tab p\u00e5 15286 beskeder! Producenten modtager en fejlmeddelelse. Overgangen til en leder uden for ISR var kun muligt p\u00e5 grund af indstillingen <i>unclean.leader.election.enable=true<\/i>. Hvis denne er indstillet til <i>false<\/i>, ville overgangen ikke v\u00e6re sket, og alle l\u00e6se- og skriveanmodninger ville v\u00e6re blevet afvist. I s\u00e5 fald venter vi p\u00e5, at broker 1 kommer tilbage med sine intakte data i den replika, der igen vil tage lederskabet.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/30f01ca715ccc194890ae061a3ef7396.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 11. Broker 1 falder. Et stort antal beskeder g\u00e5r tabt ved fejl<\/i><\/p>\n<p>Producenten opretter forbindelse til den seneste broker og ser, at denne nu er leder af sektionen. Han begynder at sende meddelelser til broker 3.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/986532d9b22b6514b6039c8460b1beb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 12. Efter en kort pause sendes meddelelserne igen til sektion 0<\/i><\/p>\n<p>Vi har set, at producenten konstant har sendt meddelelser, bortset fra de korte pauser til at etablere nye forbindelser og finde en ny leder. Denne konfiguration sikrer tilg\u00e6ngelighed gennem konsistens (datasikkerhed). Kafka har mistet tusindvis af meddelelser, men fortsatte med at modtage nye poster.<\/p>\n<h3>Acks=all og ISR<\/h3>\n<p>\nLad os gentage dette scenarie igen, men med <i>acks=all<\/i>. Broker 3 har i gennemsnit en forsinkelse p\u00e5 fire sekunder. Producenten sender en meddelelse med <i>acks=all<\/i>, og f\u00e5r nu ikke et hurtigt svar. Lederen venter, indtil meddelelsen er gemt af alle replikaer i ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/95b1abdc92e699f7bc41ebab249a2e08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 13. ISR med tre replikaer. \u00c9n arbejder langsomt, hvilket medf\u00f8rer en forsinkelse i skrivningen.<\/i><\/p>\n<p>Efter fire sekunders ekstra forsinkelse sender broker 2 ack. Alle replikaer er nu helt opdaterede.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/64356dc8d2641a3e22947126dd047f39.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 14. Alle replikaer gemmer meddelelser og sender ack<\/i><\/p>\n<p>Broker 3 er nu endnu mere bagud og fjernes fra ISR. Forsinkelsen mindskes betydeligt, da der ikke er nogen langsomme replikaer tilbage i ISR. Broker 2 venter nu kun p\u00e5 broker 1, som har en gennemsnitlig forsinkelse p\u00e5 500 ms.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/5d3bd67dc53cb868fa40b358ed483a1d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 15. Replica p\u00e5 broker 3 fjernes fra ISR<\/i><\/p>\n<p>S\u00e5 falder broker 2, og lederskabet g\u00e5r til broker 1 uden tab af meddelelser.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/e3f0417aa7714ea5eae8a8e8d61662bd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 16. Broker 2 falder<\/i><\/p>\n<p>Producenten finder en ny leder og begynder at sende meddelelser til ham. Forsinkelsen bliver endnu mindre, da ISR nu kun best\u00e5r af \u00e9n replik! Derfor tilf\u00f8jer optionen <i>acks=all<\/i> ingen redundans.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/fec9aae9977757d5f61c2909ceae0536.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 17. Replica p\u00e5 broker 1 overtager lederskabet uden tab af meddelelser<\/i><\/p>\n<p>S\u00e5 falder broker 1, og lederskabet g\u00e5r til broker 3 med et tab p\u00e5 14238 meddelelser!<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/730b3951fb75ab3a782fc6d064615212.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 18. Broker 1 d\u00f8r, og overgangen af lederskab med indstillingen unclean f\u00f8rer til omfattende datatab<\/i><\/p>\n<p>Vi kunne have undg\u00e5et at indstille optionen <i>unclean.leader.election.enable<\/i> til v\u00e6rdien <i>true<\/i>. Som standard er den lig med <i>false<\/i>. Indstillingen <i>acks=all<\/i> med <i>unclean.leader.election.enable=true<\/i> sikrer tilg\u00e6ngelighed med en vis ekstra datasikkerhed. Men som du kan se, kan vi stadig miste meddelelser.<\/p>\n<p>Men hvad nu, hvis vi \u00f8nsker at \u00f8ge datasikkerheden? Vi kan indstille <i>unclean.leader.election.enable = false<\/i>, men det beskytter os ikke n\u00f8dvendigvis mod datatab. Hvis lederen falder h\u00e5rdt og medf\u00f8rer datatab, vil beskederne stadig g\u00e5 tabt, plus adgangen g\u00e5r tabt, indtil administratoren genopretter situationen.<\/p>\n<p>Det er bedre at garantere redundans for alle beskeder, eller i modsat fald at afvise optagelsen. S\u00e5 kan tab af data fra brokerens synspunkt kun ske ved to eller flere samtidige fejlagtigheder.<\/p>\n<h3>Acks=all, min.insync.replicas og ISR<\/h3>\n<p>\nMed konfigurationen af emnet <i>min.insync.replicas<\/i> \u00f8ger vi datasikkerheden. Lad os endnu en gang gennemg\u00e5 den sidste del af det tidligere scenarie, men denne gang med <i>min.insync.replicas=2<\/i>.<\/p>\n<p>S\u00e5 broker 2 har en leder replika, og f\u00f8lgesvennen p\u00e5 broker 3 er blevet fjernet fra ISR.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/5831463293f1837d3232756894e97162.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 19. ISR best\u00e5ende af to replikaer<\/i><\/p>\n<p>Broker 2 falder, og lederskabet overg\u00e5r til broker 1 uden tab af beskeder. Men nu best\u00e5r ISR kun af \u00e9n replika. Det lever ikke op til minimumsantalet for optagelse, og derfor svarer broker p\u00e5 fors\u00f8get p\u00e5 optagelse med en fejl. <i>NotEnoughReplicas<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/6b2ee477f4c33ec84f3068b792814e5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 20. Antallet af ISR er en mindre end angivet i min.insync.replicas<\/i><\/p>\n<p>Denne konfiguration ofrer tilg\u00e6ngelighed til fordel for konsistens. F\u00f8r vi bekr\u00e6fter en besked, sikrer vi, at den optages p\u00e5 mindst to replikaer. Dette giver producenten meget st\u00f8rre tillid. Her er tab af beskeder kun muligt, hvis to replikaer fejler samtidigt i et kort \u00f8jeblik, mens beskeden ikke er replikeret til en ekstra f\u00f8lgesvend, hvilket er usandsynligt. Men hvis du er superparanoid, kan du s\u00e6tte replikationsforholdet til 5, og <i>min.insync.replicas<\/i> s\u00e5 p\u00e5 3. Her skal tre brokere falde samtidig for at miste optagelsen! Naturligvis vil du betale ekstra forsinkelse for en s\u00e5dan p\u00e5lidelighed.<\/p>\n<h1>N\u00e5r tilg\u00e6ngelighed er n\u00f8dvendig for databeskyttelse<\/h1>\n<p>\nSom i <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/471858\/\">i tilf\u00e6lde af RabbitMQ<\/a><\/noindex>, nogle gange er tilg\u00e6ngelighed n\u00f8dvendig for databeskyttelse. Du skal t\u00e6nke over dette:<\/p>\n<ul>\n<li>Kan udgiveren blot 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 svaret er nej, s\u00e5 \u00f8ger optimering af tilg\u00e6ngelighed datasikkerheden. Du taber mindre data, hvis du v\u00e6lger tilg\u00e6ngelighed frem for at afvise optagelsen. S\u00e5 alt handler om at finde balancen, og l\u00f8sningen afh\u00e6nger af den konkrete situation.<\/p>\n<h1>Meningen med ISR<\/h1>\n<p>\nISR-s\u00e6ttet giver mulighed for at v\u00e6lge den optimale balance mellem databeskyttelse og forsinkelse. For eksempel at sikre tilg\u00e6ngelighed under svigt af de fleste replikaer, mens man minimerer indflydelsen fra d\u00f8de eller langsomme replikaer med hensyn til forsinkelse.<\/p>\n<p>Vi v\u00e6lger selv v\u00e6rdien <i>replica.lag.time.max.ms<\/i> i overensstemmelse med vores behov. I bund og grund betyder denne parameter, hvor stor en forsinkelse vi er villige til at acceptere ved <i>acks=all<\/i>. Standardv\u00e6rdien er ti sekunder. Hvis det er for lang tid for dig, kan du reducere den. S\u00e5 vil hyppigheden af \u00e6ndringer i ISR stige, da f\u00f8lgere vil blive fjernet og tilf\u00f8jet oftere.<\/p>\n<p>I RabbitMQ drejer det sig blot om et s\u00e6t spejle, der skal replikeres. Langsame spejle f\u00f8rer til ekstra forsinkelse, og man kan vente p\u00e5 responsen fra d\u00f8de spejle op til udl\u00f8bet af livstiden for pakkerne, der kontrollerer tilg\u00e6ngeligheden af hver node (net tick). ISR er en interessant m\u00e5de at undg\u00e5 disse problemer med \u00f8get forsinkelse. Men vi risikerer at miste redundans, da ISR kun kan reduceres til lederen. For at undg\u00e5 denne risiko, brug indstillingen <i>min.insync.replicas<\/i>.<\/p>\n<h1>Klientforbindelsesgaranti<\/h1>\n<p>\nI indstillingerne <i>bootstrap.servers<\/i> for producent og forbruger, kan man angive flere m\u00e6glere til klientens forbindelse. Ideen er, at n\u00e5r en node er nede, er der stadig flere backup-noder, som klienten kan oprette forbindelse til. Det er ikke n\u00f8dvendigvis lederne af partitionerne, men blot en platform for den indledende indl\u00e6sning. Klienten kan sp\u00f8rge dem, hvilken node lederpartitionen til l\u00e6sning\/skrivning er placeret p\u00e5.<\/p>\n<p>I RabbitMQ kan klienterne forbinde til enhver node, og den interne router sender anmodningen det rigtige sted hen. Dette betyder, at du kan placere en load balancer foran RabbitMQ. Kafka kr\u00e6ver, at klienterne forbinder til den node, hvor lederen af den relevante partition er placeret. I denne situation kan man ikke placere en load balancer. Listen <i>bootstrap.servers<\/i> er kritisk for, at klienterne kan henvende sig til de rigtige noder og finde dem efter en fejl.<\/p>\n<h1>Kafka-konsensusarkitektur<\/h1>\n<p>\nIndtil nu har vi ikke set p\u00e5, hvordan klyngen opdager, at en m\u00e6glersystem er nede, og hvordan der v\u00e6lges en ny leder. For at forst\u00e5, hvordan Kafka arbejder med netv\u00e6rksopdelinger, skal man f\u00f8rst forst\u00e5 konsensusarkitekturen.<\/p>\n<p>Hver Kafka-klynge implementeres sammen med en Zookeeper-klynge \u2013 en service til distribueret konsensus, der muligg\u00f8r, at systemet opn\u00e5r konsensus om en bestemt tilstand med prioritet for konsistens over tilg\u00e6ngelighed. For at godkende l\u00e6se- og skriveoperationer kr\u00e6ves der enighed fra flertallet af Zookeeper-noderne.<\/p>\n<p>Zookeeper opretholder klyngets tilstand:<\/p>\n<ul>\n<li>En liste over emner, partitioner, konfiguration, nuv\u00e6rende lederreplikater, foretrukne replikater.\n<\/li>\n<li>Medlemmer af klyngen. Hver broker pinger Zookeeper-klyngen. Hvis Zookeeper ikke modtager et ping inden for en bestemt tidsramme, registrerer det brokeren som utilg\u00e6ngelig.\n<\/li>\n<li>Valg af prim\u00e6re og sekund\u00e6re noder til controlleren.<\/li>\n<\/ul>\n<p>\nController-noden er en af Kafka-brokerne, der er ansvarlig for valg af lederreplikater. Zookeeper sender notifikationer til controlleren om medlemskab i klyngen og \u00e6ndringer af emner, og controlleren skal handle i overensstemmelse med disse \u00e6ndringer.<\/p>\n<p>For eksempel, lad os tage et nyt emne med ti partitioner og en replikationsfaktor p\u00e5 3. Controlleren skal v\u00e6lge lederen for hver partition, idet den fors\u00f8ger at optimere fordelingen af ledere mellem brokeren. <\/p>\n<p>For hver partition skal controlleren:<\/p>\n<ul>\n<li>opdatere oplysningerne i Zookeeper om ISR og lederen;\n<\/li>\n<li>sende en LeaderAndISRCommand-kommando til hver broker, der har en replikation af denne partition, og informere brokerne om ISR og lederen.<\/li>\n<\/ul>\n<p>\nN\u00e5r en broker med en leder falder, sender Zookeeper en notifikation til controlleren, som derefter v\u00e6lger en ny leder. Igen opdaterer controlleren f\u00f8rst Zookeeper, f\u00f8r den sender kommandoen til hver broker og informerer dem om \u00e6ndringen i lederskabet.<\/p>\n<p>Hver leder er ansvarlig for et s\u00e6t ISR. Konfigurationen <i>replica.lag.time.max.ms<\/i> definerer, hvem der skal inkluderes. N\u00e5r ISR \u00e6ndres, sender lederen nye oplysninger til Zookeeper.<\/p>\n<p>Zookeeper er altid informeret om eventuelle \u00e6ndringer, s\u00e5 i tilf\u00e6lde af en fejl overg\u00e5r ledelsen glat til den nye leder.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/3adb1d204b28e3ed85bef3530fa2b738.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 21. Kafka-konsensus<\/i><\/p>\n<h1>Replikationsprotokol<\/h1>\n<p>\nAt forst\u00e5 detaljerne i replikation hj\u00e6lper med bedre at forst\u00e5 potentielle scenarier for datatab.<\/p>\n<h3>Foresp\u00f8rgsler om hentning, Log End Offset (LEO) og Highwater Mark (HW)<\/h3>\n<p>\nVi har gennemg\u00e5et, hvordan f\u00f8lgere periodisk sender anmodninger til lederen om hentning (fetch). Standardintervallet er 500 ms. Dette adskiller sig fra RabbitMQ, hvor replikering initieres af masteren, ikke af k\u00f8ens spejl. Masteren sender \u00e6ndringer til spejlene.<\/p>\n<p>Lederen og alle f\u00f8lgere gemmer loggens slutoffset (Log End Offset, LEO) og Highwater-m\u00e6rket (HW). LEO-m\u00e6rket gemmer offset for den seneste besked i den lokale replika, mens HW gemmer offset for den seneste commit. Husk, at for status som \u00abcommit\u00bb skal beskeden v\u00e6re gemt i alle repliker i ISR. Dette betyder, at LEO normalt lidt foran HW.<\/p>\n<p>N\u00e5r lederen modtager en besked, gemmer han den lokalt. F\u00f8lgeren anmoder om hentning ved at overf\u00f8re sin LEO. Derefter sender lederen et beskedpakke, der starter fra denne LEO, og overf\u00f8rer det aktuelle HW. N\u00e5r lederen f\u00e5r information om, at alle replikas har gemt beskeden med det angivne offset, flytter han HW-m\u00e6rket. Kun lederen kan flytte HW, og s\u00e5ledes f\u00e5r alle f\u00f8lgere at vide den aktuelle v\u00e6rdi i svarene p\u00e5 deres anmodninger. Dette betyder, at f\u00f8lgere kan v\u00e6re bagud b\u00e5de med hensyn til beskeder og viden om HW. Forbrugere modtager beskeder kun indtil det aktuelle HW.<\/p>\n<p>Bem\u00e6rk, at \u00abgemt\u00bb (persisted) betyder optaget i hukommelsen, ikke p\u00e5 disken. For at sikre ydeevne synkroniserer Kafka til disken med et bestemt interval. RabbitMQ har ogs\u00e5 et s\u00e5dant interval, men det sender en bekr\u00e6ftelse til publishere f\u00f8rst efter, at master og alle spejle har gemt beskeden p\u00e5 disken. Kafka-udviklere har af hensyn til ydeevnen besluttet at sende ack, s\u00e5 snart beskeden er gemt i hukommelsen. Kafka satser p\u00e5, at redundans kompenserer for risikoen ved kortvarig opbevaring af bekr\u00e6ftede beskeder kun i hukommelsen.<\/p>\n<h1>Lederfejl<\/h1>\n<p>\nN\u00e5r lederen fejler, informerer Zookeeper controlleren, som v\u00e6lger en ny leder-replika. Den nye leder fasts\u00e6tter et nyt HW-m\u00e6rke i overensstemmelse med sin LEO. Derefter modtager f\u00f8lgere information om den nye leder. Afh\u00e6ngigt af Kafka-versionen v\u00e6lger f\u00f8lgere en af to scenarier:<\/p>\n<ol>\n<li>Afsk\u00e6rer den lokale log til det kendte HW og sender en anmodning til den nye leder om beskeder efter dette m\u00e6rke.\n<\/li>\n<li>Sender en anmodning til lederen for at finde HW p\u00e5 det tidspunkt, hvor han blev valgt som leder, og derefter trimme loggen til denne offset. Derefter begynder den at lave periodiske foresp\u00f8rgsler om udtr\u00e6k, der starter fra denne offset.<\/li>\n<\/ol>\n<p>\nEn follower kan v\u00e6re n\u00f8dt til at trimme loggen af f\u00f8lgende grunde:<\/p>\n<ul>\n<li>N\u00e5r en leder fejler, vinder den f\u00f8rste follower fra ISR-s\u00e6ttet, der er registreret i Zookeeper, valget og bliver leder. Alle followers i ISR betragtes som \"synkroniserede\", men de har m\u00e5ske ikke modtaget kopier af alle meddelelser fra den tidligere leder. Det er muligt, at den valgte follower ikke har den mest opdaterede kopi. Kafka sikrer, at der ikke er uoverensstemmelser mellem replikaerne. For at undg\u00e5 uoverensstemmelser skal hver follower trimme sin log til HW-v\u00e6rdien for den nye leder p\u00e5 det tidspunkt, de blev valgt. Dette er endnu en grund til, hvorfor konfigurationen <i>acks=all<\/i> er vigtig for konsistens.\n<\/li>\n<li>Meddelelser skrives periodisk til disk. Hvis alle noder i klyngen svigter samtidigt, vil replikaerne p\u00e5 diske have forskellige offsets. Det er muligt, at n\u00e5r brokerne igen vender tilbage til netv\u00e6rket, vil den nye leder, der v\u00e6lges, v\u00e6re bag sine followers, fordi den blev gemt til disk tidligere end de andre.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Genforbindelse med klyngen<\/h3>\n<p>\nVed genforbindelse med klyngen optr\u00e6der replikaerne ligesom ved lederfejl: de tjekker lederen og trimmer deres log til dens HW (p\u00e5 tidspunktet for valget). Til sammenligning opfatter RabbitMQ genforbundne noder som helt nye. I begge tilf\u00e6lde smider brokeren enhver eksisterende tilstand v\u00e6k. Hvis automatisk synkronisering bruges, skal masteren replikere alt det nuv\u00e6rende indhold til det nye spejl med metoden \"og lad hele verden vente\". Under denne operation accepterer masteren ingen l\u00e6se- eller skriveoperationer. Denne tilgang skaber problemer i store k\u00f8er.<\/p>\n<p>Kafka er en distribueret log, og generelt opbevarer den flere meddelelser end RabbitMQ, hvor data fjernes fra k\u00f8en efter l\u00e6sning. Aktive k\u00f8er b\u00f8r forblive relativt sm\u00e5. Men Kafka er en log med sin egen opbevaringspolitik, som kan fasts\u00e6tte en periode i dage eller uger. Taktikken med at l\u00e5se k\u00f8en og fuld synkronisering er helt uacceptabel for en distribueret log. I stedet besk\u00e6rer Kafka-f\u00f8lgere simpelthen deres log til HW-lederen (p\u00e5 tidspunktet for dens valg), hvis deres kopi er foran lederen. I det mere sandsynlige tilf\u00e6lde, hvor f\u00f8lgere er bagud, begynder de blot at anmode om optagelser, startende fra deres nuv\u00e6rende LEO.<\/p>\n<p>Nye eller genforenede f\u00f8lgere starter uden for ISR og deltager ikke i commits. De arbejder blot sidel\u00f8bende med gruppen og modtager meddelelser s\u00e5 hurtigt som muligt, indtil de indhenter lederen og kommer ind i ISR. Der er ingen l\u00e5sning, og der er ikke behov for at kaste alle dine data v\u00e6k.<\/p>\n<h1>Netv\u00e6rkstilkoblingsbrud<\/h1>\n<p>\nKafka har flere komponenter end RabbitMQ, s\u00e5 der er et mere komplekst s\u00e6t adf\u00e6rd, n\u00e5r der opst\u00e5r forbindelsesbrud i klyngen. Men Kafka blev oprindeligt designet til klynger, s\u00e5 l\u00f8sningerne er meget velovervejede.<\/p>\n<p>Her er nogle scenarier med forbindelsesbrud:<\/p>\n<ul>\n<li>Scenarie 1. F\u00f8lgeren ser ikke lederen, men ser stadig Zookeeper.\n<\/li>\n<li>Scenarie 2. Lederen ser ingen f\u00f8lgere, men ser stadig Zookeeper.\n<\/li>\n<li>Scenarie 3. F\u00f8lgeren ser lederen, men ser ikke Zookeeper.\n<\/li>\n<li>Scenarie 4. Lederen ser f\u00f8lgere, men ser ikke Zookeeper.\n<\/li>\n<li>Scenarie 5. F\u00f8lgeren er helt adskilt fra b\u00e5de andre Kafka-noder og Zookeeper.\n<\/li>\n<li>Scenarie 6. Lederen er helt adskilt fra b\u00e5de andre Kafka-noder og Zookeeper.\n<\/li>\n<li>Scenarie 7. Kafka-controllerens node ser ikke en anden Kafka-node.\n<\/li>\n<li>Scenarie 8. Kafka-controlleren ser ikke Zookeeper.<\/li>\n<\/ul>\n<p>\nHver scenarie har sit eget adf\u00e6rdsm\u00f8nster.<\/p>\n<h3>Scenarie 1. F\u00f8lgeren ser ikke lederen, men ser stadig Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/5f51ae679933b2b5a69e21831465d121.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 22. Scenarie 1. ISR med tre replikaer<\/i><\/p>\n<p>Forbindelsesbrud frakobler broker 3 fra broker 1 og 2, men ikke fra Zookeeper. Broker 3 kan ikke l\u00e6ngere sende anmodninger om optagelser. Efter tidens udl\u00f8b <i>replica.lag.time.max.ms<\/i> Han fjernes fra ISR og deltager ikke i meddelelsescommits. S\u00e5 snart forbindelsen er genoprettet, vil han genoptage foresp\u00f8rgsler om hentning og slutte sig til ISR, n\u00e5r han n\u00e5r lederens niveau. Zookeeper vil forts\u00e6tte med at modtage pings og betragte broker som levende og rask.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/976b7ff080ee6a6d76a165f614f40e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 23. Scenarie 1. Broker fjernes fra ISR, hvis der ikke er modtaget en foresp\u00f8rgsel om hentning fra ham inden for intervallet replica.lag.time.max.ms<\/i><\/p>\n<p>Der er ingen logisk opdeling (split-brain) eller neds\u00e6ttelse af en node, som i RabbitMQ. I stedet reduceres redundansen. <\/p>\n<h3>Scenarie 2. Lederen ser ingen f\u00f8lgere, men ser stadig Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/ff6aaa053d73e8b7c97111979bcf97aa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 24. Scenarie 2. Leder og to f\u00f8lgere<\/i><\/p>\n<p>Brud p\u00e5 netv\u00e6rksforbindelsen adskiller lederen fra f\u00f8lgerne, men broker ser stadig Zookeeper. Ligesom i det f\u00f8rste scenarie komprimeres ISR, men denne gang kun til lederen, da alle f\u00f8lgere holder op med at sende foresp\u00f8rgsler om hentning. Igen er der ingen logisk opdeling. I stedet sker der tab af redundans for nye meddelelser, indtil forbindelsen er genoprettet. Zookeeper forts\u00e6tter med at modtage pings og betragter broker som levende og rask.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/3c69e8327da241407f76719fc022c37a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 25. Scenarie 2. ISR er kun komprimeret til lederen<\/i><\/p>\n<h3>Scenarie 3. F\u00f8lger ser lederen, men ser ikke Zookeeper<\/h3>\n<p>\nF\u00f8lgeren adskilles fra Zookeeper, men ikke fra broker med lederen. Som et resultat forts\u00e6tter f\u00f8lgeren med at lave foresp\u00f8rgsler om hentning og v\u00e6re medlem af ISR. Zookeeper modtager ikke l\u00e6ngere pings og registrerer nedbruddet af broker, men da det kun er en f\u00f8lger, er der ingen konsekvenser efter genoprettelsen.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/1183bcfe45a3225ae3ef1a0651f61350.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 26. Scenarie 3. F\u00f8lgeren forts\u00e6tter med at sende foresp\u00f8rgsler om hentning til lederen<\/i><\/p>\n<h3>Scenarie 4. Lederen ser f\u00f8lgere, men ser ikke Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/b3bf27fcb0eb806b27ad00f098e50a26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 27. Scenarie 4. Leder og to f\u00f8lgere<\/i><\/p>\n<p>Lederen er adskilt fra Zookeeper, men ikke fra brokerne med f\u00f8lgerne. <\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/82d9f2e5868566678befc414d1885bfd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 28. Scenarie 4. Lederen er isoleret fra Zookeeper<\/i><\/p>\n<p>Efter noget tid vil Zookeeper registrere nedbruddet af broker og informere controlleren. Denne vil v\u00e6lge en ny leder blandt f\u00f8lgerne. Men den oprindelige leder vil forts\u00e6tte med at tro, at han er lederen og vil forts\u00e6tte med at modtage indtastninger med <i>acks=1<\/i>. F\u00f8lgerne sender ikke l\u00e6ngere foresp\u00f8rgsler om hentning, s\u00e5 han vil anse dem for d\u00f8de og fors\u00f8ge at komprimere ISR til sig selv. Men da han ikke har forbindelse til Zookeeper, vil han ikke v\u00e6re i stand til at g\u00f8re dette, og i dette \u00f8jeblik vil han opgive yderligere modtagelse af indtastninger. <\/p>\n<p>Meddelelser <i>acks=all<\/i> de vil ikke f\u00e5 bekr\u00e6ftelse, fordi ISR f\u00f8rst inkluderer alle replikaer, og beskederne n\u00e5r ikke frem til dem. N\u00e5r den oprindelige leder fors\u00f8ger at fjerne dem fra ISR, vil han ikke kunne g\u00f8re det og stoppe med at modtage nogen beskeder overhovedet.<\/p>\n<p>Kunderne vil snart bem\u00e6rke lederen, der skifter, og begynder at sende optegnelser til den nye server. S\u00e5 snart netv\u00e6rket er genoprettet, vil den oprindelige leder se, at han ikke l\u00e6ngere er leder, og sk\u00e6re sin log ned til den HW-v\u00e6rdi, den nye leder havde p\u00e5 tidspunktet for nedbruddet for at undg\u00e5 logforskelle. Derefter vil han begynde at sende foresp\u00f8rgsler til den nye leder. Alle optegnelser fra den oprindelige leder, der ikke er replikeret til den nye leder, vil g\u00e5 tabt. Det vil sige, at beskeder, der ikke er bekr\u00e6ftet af den oprindelige leder i de sekunder, hvor der var to ledere, vil g\u00e5 tabt.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/d88d6f33c13dccb814c0f206ec72512b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 29. Scenarie 4. Lederen p\u00e5 broker 1 bliver f\u00f8lger efter netv\u00e6rksgenopretningen<\/i><\/p>\n<h3>Scenarie 5. F\u00f8lgeren er helt adskilt fra b\u00e5de andre Kafka-noder og Zookeeper<\/h3>\n<p>\nF\u00f8lgeren er helt isoleret fra b\u00e5de andre Kafka-noder og Zookeeper. Han fjernes simpelthen fra ISR, indtil netv\u00e6rket er genoprettet, og s\u00e5 indhenter han de andre.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/b092607f777014fd945f18734dd7f4e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 30. Scenarie 5. Isoleret f\u00f8lger fjernes fra ISR<\/i><\/p>\n<h3>Scenarie 6. Lederen er helt adskilt fra b\u00e5de andre Kafka-noder og Zookeeper<\/h3>\n<p>\n<img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/bb808d534dbf65748eb0b481f86b4926.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 31. Scenarie 6. Lederen og to f\u00f8lgere<\/i><\/p>\n<p>Lederen er helt isoleret fra sine f\u00f8lgere, controlleren og Zookeeper. I en kort periode vil han forts\u00e6tte med at modtage optegnelser fra <i>acks=1<\/i>.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/6fda78bcd26ef6b916579d447e9fb1f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 32. Scenarie 6. Isolation af lederen fra andre Kafka-noder og Zookeeper<\/i><\/p>\n<p>Uden at modtage foresp\u00f8rgsler efter udl\u00f8bet <i>replica.lag.time.max.ms<\/i>, vil han fors\u00f8ge at komprimere ISR til sig selv, men kan ikke g\u00f8re det, da der ikke er forbindelse til Zookeeper, hvorefter han stopper med at modtage optegnelser. <\/p>\n<p>I mellemtiden vil Zookeeper markere den isolerede broker som d\u00f8d, og controlleren vil v\u00e6lge en ny leder.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/73d611a411fc64d835af2c714e9eba0a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 33. Scenarie 6. To ledere<\/i><\/p>\n<p>Den oprindelige leder kan modtage optegnelser i et par sekunder, men stopper derefter med at modtage nogen beskeder. Kunderne opdateres hvert 60. sekund med de seneste metadata. De vil blive informeret om lederens skift og begynde at sende optegnelser til den nye leder.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/ae99380c8a84fac15f440b699b9c552b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 34. Scenarie 6. Producenterne skifter til den nye leder<\/i><\/p>\n<p>Alle bekr\u00e6ftede optegnelser lavet af den oprindelige leder vil g\u00e5 tabt fra det tidspunkt, hvor forbindelsen blev tabt. N\u00e5r netv\u00e6rket er genoprettet, vil den oprindelige leder opdage gennem Zookeeper, at han ikke l\u00e6ngere er leder. Han vil derefter forkorte sin log til HW for den nye leder p\u00e5 tidspunktet for valget og begynde at sende anmodninger som f\u00f8lgesvend.<\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ vs Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed\" src=\"\/wp-content\/uploads\/2019\/11\/10f0983a829b03ca9bbc62e12cbf8a5d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fig. 35. Scenarie 6. Den oprindelige leder bliver f\u00f8lgesvend efter genoprettelse af netv\u00e6rksforbindelsen<\/i><\/p>\n<p>I denne situation kan der i en kort periode v\u00e6re en logisk opdeling, men kun hvis <i>acks=1<\/i> og <i>min.insync.replicas<\/i> den ogs\u00e5 1. Den logiske opdeling afsluttes automatisk enten efter genoprettelse af netv\u00e6rket, n\u00e5r den oprindelige leder indser, at han ikke l\u00e6ngere er leder, eller n\u00e5r alle klienter forst\u00e5r, at lederen er skiftet, og begynder at skrive til den nye leder \u2013 afh\u00e6ngigt af hvad der sker f\u00f8rst. I begge tilf\u00e6lde vil der ske tab af nogle meddelelser, men kun med <i>acks=1<\/i>.<\/p>\n<p>Der er en anden mulighed i dette scenario, hvor f\u00f8lgesvende er blevet forsinket umiddelbart f\u00f8r netv\u00e6rksopdelingen, og lederen har komprimeret ISR til kun sig selv. Derefter bliver han isoleret p\u00e5 grund af tab af forbindelse. En ny leder v\u00e6lges, men den oprindelige leder forts\u00e6tter med at tage optegnelser, selv <i>acks=all<\/i>, fordi der ikke er nogen andre i ISR end ham. Disse optegnelser vil g\u00e5 tabt efter genoprettelse af netv\u00e6rket. Den eneste m\u00e5de at undg\u00e5 dette scenario p\u00e5 er <i>min.insync.replicas = 2<\/i>.<\/p>\n<h3>Scenarie 7. Kafka-controlleren ser ikke en anden Kafka-node<\/h3>\n<p>\nGenerelt vil controlleren ikke kunne videregive nogen information om leder\u00e6ndringer til den frakoblede Kafka-node. I v\u00e6rste fald vil dette f\u00f8re til en kortvarig logisk opdeling, som i scenarie 6. Ofte vil m\u00e6gleren simpelthen ikke blive kandidat til lederskab i tilf\u00e6lde af den sidste fejlfunktion.<\/p>\n<h3>Scenarie 8. Kafka-controlleren ser ikke Zookeeper<\/h3>\n<p>\nDen frakoblede controller vil ikke modtage ping fra Zookeeper og v\u00e6lge en ny Kafka-node som controller. Den oprindelige controller kan forts\u00e6tte med at fremstille sig selv som s\u00e5dan, men han modtager ikke notifikationer fra Zookeeper, s\u00e5 han vil ikke have nogen opgaver at udf\u00f8re. N\u00e5r netv\u00e6rket er genoprettet, vil han indse, at han ikke l\u00e6ngere er controller, men er blevet en almindelig Kafka-node.<\/p>\n<h3>Konklusioner fra scenarierne<\/h3>\n<p>\nVi ser, at tabet af forbindelse til f\u00f8lgere ikke f\u00f8rer til tab af meddelelser, men blot midlertidigt reducerer redundansen, indtil netv\u00e6rket genoprettes. Dette kan dog f\u00f8re til datatab, hvis en eller flere noder g\u00e5r tabt.<\/p>\n<p>Hvis lederen p\u00e5 grund af tab af forbindelse er adskilt fra Zookeeper, kan det f\u00f8re til tab af meddelelser fra <i>acks=1<\/i>. Manglende forbindelse til Zookeeper for\u00e5rsager en kortvarig logisk opdeling med to ledere. Dette problem l\u00f8ses af parameteren <i>acks=all<\/i>.<\/p>\n<p>Parameter <i>min.insync.replicas<\/i> med to eller flere replikaer giver ekstra garantier for, at s\u00e5danne kortsigtede scenarier ikke f\u00f8rer til tab af meddelelser, som i scenario 6.<\/p>\n<h1>Resume om tab af meddelelser<\/h1>\n<p>\nLad os opremse alle m\u00e5der, man kan miste data i Kafka:<\/p>\n<ul>\n<li>Enhver fejl i lederen, hvis meddelelser blev bekr\u00e6ftet via <i>acks=1<\/i>\n<\/li>\n<li>Enhver urenset (unclean) lederovergang, dvs. til en follower uden for ISR, selv med <i>acks=all<\/i>\n<\/li>\n<li>Isolation af lederen fra Zookeeper, hvis meddelelser blev bekr\u00e6ftet via <i>acks=1<\/i>\n<\/li>\n<li>Fuldt isolation af lederen, som allerede har komprimeret ISR-gruppen til sig selv. Alle meddelelser vil g\u00e5 tabt, selv <i>acks=all<\/i>. Dette er kun sandt, hvis <i>min.insync.replicas=1<\/i>.\n<\/li>\n<li>Samtidige fejl p\u00e5 alle noder i partisjonen. Da meddelelser bekr\u00e6ftes fra hukommelsen, kan nogle muligvis endnu ikke v\u00e6re skrevet til disk. Efter genstart af serverne kan nogle meddelelser mangle.<\/li>\n<\/ul>\n<p>\nUrensede lederovergange kan undg\u00e5s ved enten at forbyde dem eller ved at sikre redundans p\u00e5 mindst to. Den mest robuste konfiguration er en kombination af <i>acks=all<\/i> og <i>min.insync.replicas<\/i> mere end 1.<\/p>\n<h1>Direkte sammenligning af p\u00e5lideligheden af RabbitMQ og Kafka<\/h1>\n<p>\nFor at sikre p\u00e5lidelighed og h\u00f8j tilg\u00e6ngelighed implementerer begge platforme et system med prim\u00e6r og sekund\u00e6r replikation. Men RabbitMQ har en Achilles-h\u00e6l. Ved genforbindelse efter en fejl kasserer noderne deres data, og synkroniseringen blokeres. Denne dobbelte udfordring rejser sp\u00f8rgsm\u00e5l om holdbarheden af store k\u00f8er i RabbitMQ. Du bliver n\u00f8dt til at indse, at du enten skal reducere redundansen eller besk\u00e6ftige dig med langvarige blokeringer. At reducere redundansen \u00f8ger risikoen for massivt datatab. Men hvis k\u00f8erne er sm\u00e5, kan man klare sig med korte perioder med utilg\u00e6ngelighed (et par sekunder) ved hj\u00e6lp af genoptagelsesfors\u00f8g.<\/p>\n<p>I Kafka er der ikke et s\u00e5dant problem. Den kasserer kun data fra forskellen mellem lederen og f\u00f8lgere. Alle f\u00e6lles data bevares. Desuden blokerer replikation ikke systemet. Lederen forts\u00e6tter med at modtage indtastninger, mens en ny follower indhenter, s\u00e5 for DevOps bliver tilslutning eller genforening af klyngen en triviel opgave. Der er dog stadig problemer som b\u00e5ndbredde ved replikering. Hvis der samtidig tilf\u00f8jes flere f\u00f8lgere, kan man st\u00f8de p\u00e5 b\u00e5ndbreddebegr\u00e6nsningen.<\/p>\n<p>RabbitMQ overg\u00e5r Kafka i p\u00e5lidelighed ved samtidig svigt af flere servere i klyngen. Som n\u00e6vnt sender RabbitMQ en bekr\u00e6ftelse til publisheren kun efter at have skrevet beskeden til disken p\u00e5 masteren og alle spejle. Men det tilf\u00f8jer en ekstra forsinkelse af to grunde:<\/p>\n<ul>\n<li>fsync hvert par hundrede millisekunder\n<\/li>\n<li>Svigt af et spejl kan kun m\u00e6rkes efter udl\u00f8bet af pakkerne, der tjekker tilg\u00e6ngeligheden af hver node (net tick). Hvis et spejl halter eller er nede, tilf\u00f8jer det forsinkelse.<\/li>\n<\/ul>\n<p>\nKafka satser p\u00e5, at hvis en besked opbevares p\u00e5 flere noder, kan beskeder bekr\u00e6ftes, s\u00e5 snart de er n\u00e5et ind i hukommelsen. Dette medf\u00f8rer en risiko for tab af beskeder af enhver type (selv <i>acks=all<\/i>, <i>min.insync.replicas=2<\/i>) i tilf\u00e6lde af samtidig svigt.<\/p>\n<p>Generelt viser Kafka h\u00f8jere ydeevne, da den oprindeligt er designet til klynger. Antallet af f\u00f8lgere kan \u00f8ges til 11, hvis det er n\u00f8dvendigt for p\u00e5lidelighed. Replikationsforholdet p\u00e5 5 og det minimale antal replikaer i synkroniseret tilstand <i>min.insync.replicas=3<\/i> vil g\u00f8re tab af besked til en meget sj\u00e6lden begivenhed. Hvis din infrastruktur kan sikre et s\u00e5dant replikationsforhold og redundansniveau, kan du v\u00e6lge denne mulighed.<\/p>\n<p>Klyngen af RabbitMQ er god til sm\u00e5 k\u00f8er. Men selv sm\u00e5 k\u00f8er kan hurtigt vokse ved h\u00f8je trafikm\u00e6ngder. S\u00e5 snart k\u00f8erne bliver store, m\u00e5 der tr\u00e6ffes h\u00e5rde valg mellem tilg\u00e6ngelighed og p\u00e5lidelighed. Klyngen af RabbitMQ er bedst egnet til ikke-typiske situationer, hvor fordelene ved fleksibilitet i RabbitMQ opvejer eventuelle ulemper ved dets klyngedannelse.<\/p>\n<p>Et af modgiftene mod s\u00e5rbarheden i RabbitMQ med hensyn til store k\u00f8er er at opdele dem i mange mindre. Hvis der ikke kr\u00e6ves fuld r\u00e6kkef\u00f8lge af hele k\u00f8en, men kun de relevante meddelelser (f.eks. meddelelser fra en bestemt kunde), eller slet ikke noget er i r\u00e6kkef\u00f8lge, s\u00e5 er denne mulighed acceptabel: se mit projekt <noindex><a rel=\"nofollow\" href=\"https:\/\/jack-vanlightly.com\/blog\/2018\/7\/22\/creating-consumer-groups-in-rabbitmq-with-rebalanser-part-1\">Rebalancer<\/a><\/noindex> til opdeling af k\u00f8en (projektet er stadig i de tidlige stadier). <\/p>\n<p>Endelig skal man ikke glemme en r\u00e6kke fejl i kluster- og replikeringsmekanisme b\u00e5de i RabbitMQ og i Kafka. Med tiden er systemerne blevet mere modne og stabile, men ingen meddelelse vil nogensinde v\u00e6re 100% beskyttet mod tab! Derudover sker der storstilede nedbrud i datacentre!<\/p>\n<p>Hvis jeg har overset noget, lavet en fejl, eller hvis du er uenig i nogen af punkterne, s\u00e5 t\u00f8v ikke med at skrive en kommentar eller kontakte mig.<\/p>\n<p>Jeg bliver ofte spurgt: \u00abHvad skal man v\u00e6lge, Kafka eller RabbitMQ?\u00bb, \u00abHvilken platform er bedre?\u00bb. Sandheden er, at det virkelig afh\u00e6nger af din situation, nuv\u00e6rende erfaring osv. Jeg t\u00f8r ikke udtrykke min mening, da det ville v\u00e6re for stort et simplificering at anbefale \u00e9n eneste platform til alle anvendelsesscenarier og mulige begr\u00e6nsninger. Jeg har skrevet denne serie af artikler, s\u00e5 du kan danne din egen mening.<\/p>\n<p>Jeg vil sige, at begge systemer er f\u00f8rende p\u00e5 dette omr\u00e5de. M\u00e5ske er jeg en smule partisk, fordi jeg af erfaring fra mine projekter s\u00e6tter pris p\u00e5 ting som garanteret r\u00e6kkef\u00f8lge af meddelelser og p\u00e5lidelighed. <\/p>\n<p>Jeg ser andre teknologier, som mangler denne p\u00e5lidelighed og garanteret r\u00e6kkef\u00f8lge, og s\u00e5 ser jeg p\u00e5 RabbitMQ og Kafka \u2014 og forst\u00e5r den utrolige v\u00e6rdi af begge disse systemer.<br \/>\n<br \/>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/474984\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e RabbitMQ \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u043f\u043e\u043a\u043e\u043f\u0430\u0435\u043c\u0441\u044f \u0432 Apache Kafka. \u0417\u0434\u0435\u0441\u044c \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0434\u0435\u043b (partition). \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430 \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432. \u0412 \u043a\u0430\u0436\u0434\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0435\u0441\u0442\u044c \u043b\u0438\u0434\u0435\u0440 \u0441 \u0444\u043e\u043b\u043b\u043e\u0432\u0435\u0440\u0430\u043c\u0438 \u0438\u043b\u0438 \u0431\u0435\u0437 \u043d\u0438\u0445. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u043e\u043f\u0438\u043a\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432 \u0438 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438. \u041e\u0431\u044b\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 3, \u044d\u0442\u043e [&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-52541","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=\"\u0412\" \/>\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\" \/>\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 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost\" \/>\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-10T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:17+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 vs. Kafka: fejltolerance og h\u00f8j tilg\u00e6ngelighed | ProHoster","description":"I","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","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 | ProHoster","og:description":"\u0412","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/rabbitmq-protiv-kafka-otkazoustojchivost-i-vysokaya-dostupnost","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-10T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:17+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52541","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:57:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:41:24","updated":"2026-01-24 03:57:22","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\/52541","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=52541"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/52541\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=52541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=52541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=52541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}