{"id":56365,"date":"2020-02-11T00:00:00","date_gmt":"2020-02-10T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike"},"modified":"2020-02-18T14:04:37","modified_gmt":"2020-02-18T11:04:37","slug":"highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","status":"publish","type":"post","link":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","title":{"rendered":"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>De volgende HighLoad++ conferentie vindt plaats op 6 en 7 april 2020 in Sint-Petersburg. <br \/>\nDetails en tickets <noindex><a rel=\"nofollow\" href=\"http:\/\/bit.ly\/2sSxgBx\">via de link<\/a><\/noindex>. HighLoad++ Siberia 2019. Zaal \"Krasnojarsk\". 25 juni, 12:00. Samenvattingen en <noindex><a rel=\"nofollow\" href=\"https:\/\/www.highload.ru\/siberia\/2019\/abstracts\/5253\">presentatie<\/a><\/noindex>.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/cded9c5434d670db7295aadf5da0a9f1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSoms lopen praktische vereisten vooruit op de theorie, waarin belangrijke aspecten voor een commercieel product niet zijn meegenomen. In deze presentatie wordt het proces gepresenteerd van het kiezen en combineren van verschillende benaderingen voor het cre\u00ebren van componenten voor Causal consistency, gebaseerd op academisch onderzoek en de vereisten van commerci\u00eble producten. De luisteraars zullen leren over bestaande theoretische benaderingen van logical clocks, dependency tracking, system security, clock synchronization, en waarom MongoDB bepaalde oplossingen heeft gekozen.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><b>Mikhail Tyulenev (hierna - MT):<\/b> - Ik ga vertellen over Causal consistency \u2013 een functie waar we bij MongoDB aan hebben gewerkt. Ik werk in de groep voor gedistribueerde systemen, we hebben dit ongeveer twee jaar geleden gerealiseerd.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/b8d0a5b64e715f53b033fa8c398e2eb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn het proces moest ik veel academisch onderzoek bestuderen, omdat deze functie goed is bestudeerd. Het bleek dat geen enkele paper volledig voldoet aan wat er nodig is in productie, in een database, gezien de zeer specifieke vereisten die er waarschijnlijk zijn in elke productieapplicatie.<\/p>\n<p>Ik ga vertellen hoe we, als gebruikers van academisch onderzoek, daar iets van bereiden dat we vervolgens aan onze gebruikers kunnen presenteren als een kant-en-klaar gerecht, dat handig en veilig te gebruiken is.<\/p>\n<h3>Causale consistentie (Causal consistency). Laten we de begrippen defini\u00ebren.<\/h3>\n<p>\nOm te beginnen wil ik in het algemeen zeggen wat Causal consistency is. Er zijn twee personages \u2013 Leonard en Penny (serie 'The Big Bang Theory'):<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/ee0835b604ae5d5d6c0fa1bc369e6b18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nStel je voor dat Penny in Europa is, en Leonard een verrassing voor haar wil organiseren. En hij komt niet met iets beters dan haar uit zijn vriendenlijst te gooien, en alle vrienden een update op hun feed te sturen: \"Laten we Penny blij maken!\" (ze is in Europa, terwijl ze slaapt, kan dit allemaal niet zien en kan het niet zien omdat ze er niet is). Op een gegeven moment verwijdert hij deze post, wist het uit de \"feed\" en herstelt de toegang, zodat ze er niets van merkt en er geen rel ontstaat.<br \/>\nDit is allemaal geweldig, maar laten we aannemen dat het systeem gedistribueerd is en de gebeurtenissen niet helemaal zoals verwacht verlopen. Het kan bijvoorbeeld gebeuren dat de access beperking van Penny plaatsvond nadat deze post verschenen is, als de gebeurtenissen niet causaal met elkaar verbonden zijn. Dit is in feite een voorbeeld van wanneer Causal consistency nodig is om een zakelijke functie uit te voeren (in dit geval).<\/p>\n<p>Eigenlijk zijn dit best complexe eigenschappen van databases - heel weinig functies ondersteunen ze. Laten we verder gaan met de modellen.<\/p>\n<h3>Consistentiemodellen<\/h3>\n<p>\nWat is een consistentiemodel in databases eigenlijk? Dit zijn bepaalde garanties die een gedistribueerd systeem biedt over welke gegevens en in welke volgorde een cli\u00ebnt kan ontvangen.<\/p>\n<p>In principe komen alle consistentiemodellen neer op de vraag in hoeverre een gedistribueerd systeem lijkt op een systeem dat bijvoorbeeld op \u00e9\u00e9n node op een laptop draait. En in hoeverre lijkt een systeem dat draait op duizenden geografisch verspreide 'nodes' op een laptop, waarin al deze eigenschappen in principe automatisch worden uitgevoerd.<\/p>\n<p>Daarom zijn consistentiemodellen alleen van toepassing op gedistribueerde systemen. Alle systemen die eerder bestonden en werkten met verticale schaalvergroting hebben dergelijke problemen niet ervaren. Daar was er \u00e9\u00e9n Buffer Cache, en daaruit werd altijd alles gelezen.<\/p>\n<h3>Sterk model<\/h3>\n<p>\nEigenlijk is het eerste model - het Sterke model (of zoals het vaak wordt genoemd, de rise ability lijn). Dit is een consistentiemodel dat garandeert dat elke wijziging, zodra de bevestiging dat deze heeft plaatsgevonden is ontvangen, voor alle gebruikers van het systeem zichtbaar wordt.<\/p>\n<p>Dit cre\u00ebert een wereldwijde volgorde van alle gebeurtenissen in de database. Dit is een zeer sterke eigenschap van consistentie, en het is ook zeer kostbaar. Desondanks wordt het goed ondersteund. Het is gewoon heel duur en langzaam - men maakt er gewoon zelden gebruik van. Dit wordt rise ability genoemd.<\/p>\n<p>Er is nog een andere, sterkere eigenschap die wordt ondersteund in 'Spanner' - dit wordt externe consistentie genoemd. We zullen dit later bespreken.<\/p>\n<h3>Causaal<\/h3>\n<p>\nHet volgende is Causal, precies waar ik het over had. Tussen Strong en Causal zijn er nog een aantal subniveaus waar ik niet over zal spreken, maar deze komen allemaal neer op Causal. Dit is een belangrijk model, omdat het het sterkste is van alle modellen, met de sterkste consistentie in het geval van een netwerk of partities.<\/p>\n<p>Causals zijn eigenlijk de situatie waarin gebeurtenissen causaal met elkaar verbonden zijn. Vaak worden ze gezien als Read your on rights vanuit het perspectief van de klant. Als een klant bepaalde waarden heeft waargenomen, kan hij de waarden van het verleden niet meer zien. Hij begint al prefix readings te zien. Dit komt allemaal op hetzelfde neer.<br \/>\nCausals als model van consistentie \u2013 een gedeeltelijke ordening van gebeurtenissen op de server, waarbij gebeurtenissen van alle klanten in dezelfde volgorde worden waargenomen. In dit geval \u2013 Leonard en Penny.<\/p>\n<h3>Eventual<\/h3>\n<p>\nHet derde model is Eventual Consistency. Dit is wat absoluut alle gedistribueerde systemen ondersteunen, het minimale model dat \u00fcberhaupt zinvol is. Het betekent het volgende: wanneer we bepaalde wijzigingen in de gegevens aanbrengen, worden deze op een gegeven moment consistent.<\/p>\n<p>Op dat moment zegt het niets, anders zou het in External Consistency veranderen \u2013 dat zou een heel ander verhaal zijn. Toch is dit een zeer populair model, het meest voorkomende. Standaard gebruiken alle gebruikers van gedistribueerde systemen inderdaad Eventual Consistency.<\/p>\n<p>Ik wil een paar vergelijkende voorbeelden geven:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/c23e59b30d96de6ec456aaa76c67ad61.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWat betekenen deze pijlen?<\/p>\n<ul>\n<li><b>Latency.<\/b> Bij het vergroten van de kracht van consistentie wordt deze groter om duidelijke redenen: het is nodig om meer bewerkingen uit te voeren, bevestiging te krijgen van alle hosts en nodes die deelnemen aan de cluster, dat de gegevens daar al zijn. Daarom is de snelste respons bij Eventual Consistency, omdat je daar doorgaans zelfs in het geheugen kunt committeren en dat in principe voldoende zal zijn.<\/li>\n<li><b>Availability.<\/b> Als we dit begrijpen als de mogelijkheid van het systeem om te reageren bij netwerkonderbrekingen, partities of bepaalde storingen \u2013 neemt de fault tolerance toe bij vermindering van het model van consistentie, omdat we genoeg hebben dat \u00e9\u00e9n host actief blijft en enkele gegevens biedt. Eventual Consistency garandeert helemaal niets over de gegevens \u2013 het kan van alles zijn.<\/li>\n<li><b>Anomalie\u00ebn.<\/b> Natuurlijk neemt het aantal anomalie\u00ebn toe. Bij Strong Consistency zouden ze er eigenlijk bijna niet moeten zijn, terwijl ze bij Eventual Consistency van alles kunnen zijn. De vraag rijst: waarom kiezen mensen voor Eventual Consistency, als het anomalie\u00ebn bevat? Het antwoord is dat de modellen voor Eventual Consistency toepasbaar zijn en dat anomalie\u00ebn bijvoorbeeld maar voor een korte tijd bestaan; er is de mogelijkheid om een master te gebruiken voor het lezen en meer of minder consistente gegevens te lezen; er is vaak ook de mogelijkheid om sterke consistentiemodellen te gebruiken. In de praktijk werkt dit en vaak is het aantal anomalie\u00ebn tijdgebonden.<\/li>\n<\/ul>\n<p><\/p>\n<h3>CAP-theorema<\/h3>\n<p>\nWanneer je de woorden consistentie en beschikbaarheid ziet, wat komt dan in je op? Juist - het CAP-theorema! Ik wil nu een mythe ontkrachten\u2026 Het is niet ik \u2013 het is Martin Kleppmann die een prachtig artikel en een prachtig boek heeft geschreven.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/02a9b84585218c4e85afd65f7e88aa26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHet CAP-theorema is een principe dat in de jaren 2000 is geformuleerd, dat stelt dat Consistentie, Beschikbaarheid, Partities: neem er twee, en je kunt er geen drie kiezen. Dit was een bepaald principe. Het is enkele jaren later bewezen als een theorema, dat deden Gilbert en Lynch. Vervolgens begon het als een mantra gebruikt te worden - systemen werden onderverdeeld in CA, CP, AP, enzovoort.<\/p>\n<p>Dit theorema is eigenlijk bewezen voor bepaalde gevallen... Ten eerste werd Beschikbaarheid niet bekeken als een continue waarde van nul tot honderd (0 \u2013 systeem is 'dood', 100 \u2013 reageert snel; dat zijn we gewend te bekijken), maar als een eigenschap van een algoritme dat garandeert dat het bij al zijn uitvoeringen gegevens retourneert.<\/p>\n<p>Er staat helemaal niets over de responstijd! Er is een algoritme dat gegevens na 100 jaar retourneert \u2013 een volkomen prachtig beschikbaar algoritme, dat een onderdeel is van het CAP-theorema.<br \/>\nTen tweede werd het theorema bewezen voor wijzigingen in de waarden van dezelfde sleutel, terwijl deze wijzigingen \u2013 een resizebare lijn zijn. Dit betekent dat ze in werkelijkheid nauwelijks worden gebruikt, omdat andere modellen zoals Eventual Consistency, Strong Consistency (misschien) bestaan.<\/p>\n<p>Waar gaat dit allemaal over? Het CAP-theorema in de vorm waarin het is bewezen, is in de praktijk bijna niet toepasbaar en wordt zelden gebruikt. In theoretische vorm beperkt het op een bepaalde manier alles. Er ontstaat een bepaalde principe dat intu\u00eftief waar is, maar in feite niet echt bewezen.<\/p>\n<h3>Causale consistentie \u2013 het sterkste model<\/h3>\n<p>\nWat er nu gebeurt, is dat je alle drie dingen kunt krijgen: Consistentie, Beschikbaarheid kunt krijgen met behulp van Partities. In het bijzonder is Causale consistentie het sterkste model van consistentie, dat zelfs bij Partities (onderbrekingen in netwerken) blijft functioneren. Daarom is het zo interessant en daarom zijn we ermee begonnen.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/c4320294320261858a6d22faa97b9e23.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTen eerste, het vereenvoudigt het werk van applicatieontwikkelaars. In het bijzonder is er grote serverondersteuning: als alle gegevens die binnen \u00e9\u00e9n klant plaatsvinden, gegarandeerd in dezelfde volgorde bij een andere klant aankomen. Ten tweede, het weerstaat partities.<\/p>\n<h3>De interne werking van MongoDB<\/h3>\n<p>\nBedenkend dat het lunchtijd is, verplaatsen we ons naar de keuken. Ik zal het hebben over het systeemmodel en wat MongoDB is voor degenen die voor het eerst over deze database horen.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/a1784442ff1c44403b5347f4f43a1197.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/a1f9bcb4daebb43e4fc848a5f5f07c60.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMongoDB (hierna 'MongoDB') is een gedistribueerd systeem dat horizontale schaalbaarheid ondersteunt, dat wil zeggen sharding; en binnen elke shard ondersteunt het ook gegevensredundantie, dat wil zeggen replicatie.<\/p>\n<p>Sharding in 'MongoDB' (geen relationele DB) voert automatische belastingredistributie uit, dat wil zeggen dat elke documentcollectie (of 'tabel' in relationele termen) in stukjes wordt verdeeld, en de server verplaatst ze automatisch tussen shards.<\/p>\n<p>De Query Router, die de verzoeken distribueert, is voor de cli\u00ebnt een soort klant waar hij mee werkt. Hij weet al waar en welke gegevens zich bevinden en stuurt alle verzoeken naar de juiste shard.<\/p>\n<p>Een ander belangrijk punt: MongoDB is een single master. Er is \u00e9\u00e9n Primary \u2013 hij kan records bijhouden die de sleutels ondersteunen die hij in zich heeft. Multi-master schrijven is niet mogelijk.<\/p>\n<p>We hebben release 4.2 gedaan \u2013 daar zijn nieuwe interessante dingen gekomen. In het bijzonder hebben we Lucene toegevoegd \u2013zoeken \u2013 namelijk uitvoerbare java direct in 'Mongo', en het is nu mogelijk om te zoeken via Lucene, net als in 'Elasticsearch'.<\/p>\n<p>En we hebben een nieuw product gemaakt \u2013 Charts, dat ook beschikbaar is op 'Atlas' (de eigen Cloud van 'Mongo'). Ze hebben een Free Tier \u2013 je kunt hier mee experimenteren. Charts vond ik heel leuk \u2013 gegevensvisualisatie, heel intu\u00eftief.<\/p>\n<h3>Ingredienten van Causale consistentie<\/h3>\n<p>\nIk heb ongeveer 230 artikelen geteld die over dit onderwerp zijn gepubliceerd \u2013 van Leslie Lampert. Nu zal ik enkele delen van deze materialen naar je overbrengen vanuit mijn geheugen.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/e88b34b7a724e94837b944a4ddd21a04.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAlles begon met een artikel van Leslie Lampert, geschreven in de jaren zeventig. Zoals je ziet, zijn er tot op heden nog steeds onderzoeken naar dit onderwerp gaande. Momenteel is er interesse in Causal consistency, vooral door de ontwikkeling van gedistribueerde systemen.<\/p>\n<h3>Beperkingen<\/h3>\n<p>\nWat zijn de beperkingen? Dit is eigenlijk een van de belangrijkste punten, want de beperkingen die productieomgevingen met zich meebrengen, verschillen sterk van de beperkingen die in academische artikelen worden gepresenteerd. Vaak zijn ze behoorlijk kunstmatig.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/9583ba9ff870e4ddc7aad4ba4c59ecc1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Ten eerste, 'MongoDB' is single master, zoals ik al zei (dat vereenvoudigt het enorm).<\/li>\n<li>Wij geloven dat het systeem ongeveer 10.000 shards moet ondersteunen. We kunnen geen architectonische beslissingen nemen die deze waarde expliciet zouden beperken.<\/li>\n<li>We hebben wel een cloud, maar we veronderstellen dat een persoon de mogelijkheid moet hebben om, wanneer hij de binary downloadt en deze op zijn laptop uitvoert, alles perfect moet werken.<\/li>\n<li>We veronderstellen dat in onderzoek zelden het geval is: externe klanten kunnen doen wat ze maar willen. 'MongoDB' is open-source. Dienovereenkomstig kunnen de klanten slim en kwaadwillig zijn \u2013 ze kunnen alles willen verpesten. We veronderstellen dat Byzantijnse failures kunnen optreden.<\/li>\n<li>Voor externe klanten die zich buiten de perimeter bevinden, is er een belangrijke beperking: als deze functie is uitgeschakeld, mag er geen prestatieverlies waarneembaar zijn.<\/li>\n<li>Een ander punt \u2013 eigenlijk anti-academisch: compatibiliteit van eerdere versies met toekomstige. Oude drivers moeten nieuwe updates ondersteunen, en de database moet oude drivers ondersteunen.<\/li>\n<\/ul>\n<p>\nOver het algemeen legt dit allemaal beperkingen op.<\/p>\n<h3>Componenten van Causal consistency<\/h3>\n<p>\nIk ga nu vertellen over enkele componenten. Als we Causal consistency in het algemeen beschouwen, kunnen we blokken onderscheiden. We hebben geselecteerd uit werken die tot een bepaald blok behoren: Dependency Tracking, de keuze van klokken, hoe deze klokken met elkaar kunnen worden gesynchroniseerd, en hoe we veiligheid waarborgen \u2013 dat is een globaal overzicht van waarover ik ga praten:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/10c2631d6e61a280139b448628db763e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Volledige afhankelijkheidsoTracking (Full Dependency Tracking)<\/h3>\n<p>\nWaarom is het nodig? Wanneer gegevens worden gerepliceerd, bevat elke record, elke wijziging informatie over welke wijzigingen eraan ten grondslag liggen. De eerste en meest eenvoudige wijziging is dat elke boodschap die een record bevat, informatie bevat over de vorige berichten:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/fa5d0086c3c77e33631d8a2cd5c217fa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn dit voorbeeld is het nummer tussen accolades het recordnummer. Soms worden deze records met waarden zelfs volledig doorgegeven, soms worden bepaalde versies doorgegeven. De essentie is dat elke wijziging informatie bevat over de voorgaande (dit wordt duidelijk ingebouwd).<\/p>\n<p>Waarom hebben we besloten om deze aanpak (volledige tracking) niet te gebruiken? Het is duidelijk dat deze aanpak onpraktisch is: elke wijziging in een sociaal netwerk hangt af van alle voorgaande wijzigingen in dat sociale netwerk, en zou bijvoorbeeld 'Facebook' of 'VKontakte' in elke update moeten doorgeven. Toch zijn er veel onderzoeken naar Full Dependency Tracking \u2013 dit zijn pre-sociale netwerken, en voor bepaalde situaties werkt dit echt.<\/p>\n<h3>Expliciete afhankelijkheids tracking (Explicit Dependency Tracking)<\/h3>\n<p>\nDe volgende is beperkter. Hier wordt ook gekeken naar het doorgeven van informatie, maar alleen die informatie die expliciet afhankelijk is. Wat van wat afhankelijk is, wordt meestal bepaald door de applicatie. Wanneer gegevens worden gerepliceerd, worden alleen de antwoorden gegeven wanneer aan de vorige afhankelijkheden is voldaan, dat wil zeggen, deze zijn weergegeven. Dit is de essentie van hoe Causal consistency werkt.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/7fe101b998c1a0c922788d8d36a5243f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHet ziet dat record 5 afhankelijk is van records 1, 2, 3 en 4 \u2013 daarom wacht het voordat de klant toegang krijgt tot de wijzigingen die zijn aangebracht op verzoek van Penny, wanneer alle voorgaande wijzigingen al in de database zijn doorgevoerd.<\/p>\n<p>Dit is ook niet acceptabel voor ons, want er is nog steeds te veel informatie, en dit zou vertraging veroorzaken. Er is een andere aanpak...<\/p>\n<h3>Lamport Klok (Lamport Clock)<\/h3>\n<p>\nZe zijn erg oud. De Lamport Klok houdt in dat deze afhankelijkheden worden samengevoegd in een scalair functie, die de Lamport Klok wordt genoemd.<\/p>\n<p>Een scalair functie is een abstract getal. Het wordt vaak logische tijd genoemd. Bij elke gebeurtenis wordt deze counter verhoogd. De counter die momenteel bekend is bij het proces, verzendt elk bericht. Het is duidelijk dat processen niet gesynchroniseerd kunnen zijn; ze kunnen volkomen verschillende tijden hebben. Toch balanceert het systeem de klokken op een bepaalde manier door dit berichtenverkeer. Wat gebeurt er in dit geval?<\/p>\n<p>Ik heb die grote shard in twee\u00ebn verdeeld, zodat het duidelijk is: Friends kunnen in dezelfde node leven die een deel van de collectie bevat, terwijl Feed geheel in een andere node kan staan, waar ook een deel van die collectie zich bevindt. Is het duidelijk hoe ze niet in de wachtrij kunnen komen? Eerst zal Feed zeggen: \"Gerepliceerd\", en daarna \u2013 Friends. Als het systeem geen garanties biedt dat Feed niet getoond wordt totdat de afhankelijkheden van Friends in de collectie van Friends ook geleverd zijn, ontstaat precies de situatie die ik noemde.<\/p>\n<p>Je ziet hoe de logische tijd van de counter op de Feed toeneemt:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/bae152d1890b53804f2cb28122983df6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDientengevolge is de belangrijkste eigenschap van deze Lamport-klok en causale consistentie (verklaard door middel van de Lamport-klok) als volgt: als we gebeurtenissen A en B hebben, en gebeurtenis B afhankelijk is van gebeurtenis A *, dan volgt hieruit dat de LogicalTime van Event A kleiner is dan de LogicalTime van Event B.<\/p>\n<p><i>* Soms zegt men ook dat A gebeurde voor B, wat betekent dat A eerder plaatsvond dan B \u2013 dit is een bepaalde relatie die een gedeeltelijke ordening aanbrengt in de verzameling gebeurtenissen die ooit hebben plaatsgevonden.<\/i><\/p>\n<p>Omgekeerd is het niet waar. Dit is in feite een van de belangrijkste nadelen van de Lamport-klok \u2013 gedeeltelijke volgorde. Er is het begrip van gelijktijdige gebeurtenissen, dat wil zeggen gebeurtenissen, waarbij noch (A happened before B), noch (A happened before B) het geval is. Een voorbeeld zou parallelle bijvoeging van Leonard aan iemand anders zijn (zelfs niet Leonard, maar Sheldon, bijvoorbeeld).<br \/>\nDit is de eigenschap die vaak wordt gebruikt bij het werken met Lamport-klokken: men kijkt naar de functie en daaruit komt de conclusie voort \u2013 misschien zijn deze gebeurtenissen afhankelijk. Want in \u00e9\u00e9n richting is het waar: als LogicalTime A kleiner is dan LogicalTime B, kan B niet eerder zijn gebeurd dan A; maar als het groter is, kan dat wel.<\/p>\n<h3>Vector klokken (Vector Clock)<\/h3>\n<p>\nDe logische ontwikkeling van Lamport-klokken is de Vector klok. Ze verschillen doordat elke node die hier aanwezig is, zijn eigen, aparte klokken bevat, die als een vector worden doorgegeven.<br \/>\nIn dit geval zie je dat de nulindex van de vector staat voor Feed, en de eerste index van de vector staat voor Friends (elk van deze nodes). En nu zullen ze in grootte toenemen: de nulindex \"Feed\" neemt toe met de waarden \u2013 1, 2, 3:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/d89292686ed8dd41aef06090f16db1c0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWaarom zijn Vector Clocks beter? Omdat ze helpen te begrijpen welke gebeurtenissen gelijktijdig zijn en wanneer ze plaatsvinden op verschillende nodes. Dit is erg belangrijk voor het sharding systeem, zoals \"MongoDB\". We hebben het echter niet gekozen, hoewel het een geweldig systeem is dat prima werkt en waarschijnlijk ook voor ons zou werken...<\/p>\n<p>Als we 10.000 shards hebben, kunnen we geen 10.000 componenten doorgeven, zelfs niet als we compressie toepassen of andere idee\u00ebn bedenken \u2013 de nuttige lading zal nog steeds veel kleiner zijn dan het volume van deze vector. Daarom hebben we, met tegenzin, deze benadering verlaten en zijn we overgestapt naar een andere.<\/p>\n<h3>Spanner TrueTime. Atomuurlijke klokken.<\/h3>\n<p>\nIk zei dat er een verhaal zou zijn over \"Spanner\". Het is een geweldig systeem, echt een product van de 21e eeuw: atomische klokken, GPS-synchronisatie.<\/p>\n<p>Wat is het idee? \"Spanner\" is een systeem van Google dat recentelijk toegankelijk is geworden voor mensen (ze hebben er SQL aan toegevoegd). Elke transactie heeft een bepaalde tijdstempel. Omdat de tijd gesynchroniseerd is*, kan aan elk evenement een specifieke tijd worden toegewezen \u2013 atomische klokken hebben een wachttijd waarna gegarandeerd \"een ander tijdstip\" plaatsvindt.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/707b5998fbb500d201aafffccc666f0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOp deze manier, door gewoon in de database te schrijven en een bepaalde tijd te wachten, wordt automatisch de serialiseerbaarheid van het evenement gegarandeerd. Ze hebben het sterkste consistentiemodel dat je je kunt voorstellen \u2013 het is externe consistentie.<\/p>\n<p>* Dit is het belangrijkste probleem van Lamport's klokken \u2013 ze zijn nooit gesynchroniseerd in gedistribueerde systemen. Ze kunnen uit elkaar lopen, zelfs met NTP werken ze nog steeds niet zo goed. \"Spanner\" heeft atomische klokken en synchronisatie die op microseconden lijkt.<\/p>\n<p>Waarom hebben we het niet gekozen? We gaan ervan uit dat onze gebruikers geen ingebouwde atomische klokken hebben. Wanneer ze ingebouwd in elke laptop verschijnen, zal er een supergoede GPS-synchronisatie zijn \u2013 dan ja... Maar op dit moment is het beste wat mogelijk is, \"Amazon\", basisstations \u2013 voor de fanaten... Daarom hebben we andere klokken gebruikt.<\/p>\n<h3>Hybride klokken (Hybrid Clock)<\/h3>\n<p>\nDit is feitelijk wat tikt in \"MongoDB\" bij het waarborgen van causale consistentie. Hybridisch, waar zijn ze hybride in? Een hybride is een scalaar waarde, maar het bestaat uit twee componenten:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/dab03a87d9f6ee2e716f75baff1736bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>De eerste is de Unix-epoch (hoeveel seconden zijn verstreken sinds \"het begin van de computerwereld\").<\/li>\n<li>De tweede is een bepaalde increment, ook een 32-bits unsigned int.<\/li>\n<\/ul>\n<p>\nDat is het eigenlijk. Er is een benadering: het deel dat verantwoordelijk is voor de tijd, synchroniseert continu met de klok; elke keer wanneer er een update plaatsvindt, wordt dit deel gesynchroniseerd met de klok, waardoor de tijd altijd meer of minder correct is, terwijl de increment het mogelijk maakt om gebeurtenissen te onderscheiden die op hetzelfde moment zijn gebeurd.<\/p>\n<p>Waarom is dit belangrijk voor \"MongoDB\"? Omdat het mogelijk maakt om bepaalde back-up hersteloperaties op een specifiek tijdstip uit te voeren, wat betekent dat een gebeurtenis wordt ge\u00efndexeerd op tijd. Dit is belangrijk wanneer specifieke gebeurtenissen nodig zijn; voor databases zijn gebeurtenissen de wijzigingen in de database die zich op specifieke tijdstippen hebben voorgedaan.<\/p>\n<p>De belangrijkste reden vertel ik alleen aan jou (alsjeblieft, vertel het aan niemand)! We hebben het zo gedaan omdat dit is hoe geordende, ge\u00efndexeerde gegevens in de MongoDB OpLog eruitzien. OpLog is een datastructuur die alle wijzigingen in de database bevat: ze komen eerst in de OpLog terecht en worden daarna daadwerkelijk toegepast op de opslag, wanneer het gaat om gerepliceerde gegevens of shards.<\/p>\n<p>Dit was de belangrijkste reden. Er zijn ook praktische vereisten voor de ontwikkeling van de database, wat betekent dat het eenvoudig moet zijn \u2013 weinig code, zo min mogelijk gebroken dingen die herschreven en getest moeten worden. Het feit dat onze oplogs ge\u00efndexeerd zijn met hybride klokken, heeft enorm geholpen en maakte de juiste keuze mogelijk. Het heeft zich echt bewezen en werkte eigenlijk als magie, bij de eerste prototype. Het was echt geweldig!<\/p>\n<h3>Synchronisatie van klokken<\/h3>\n<p>\nEr zijn verschillende methoden voor synchronisatie beschreven in de wetenschappelijke literatuur. Ik heb het over synchronisatie wanneer we twee verschillende shards hebben. Als er een replica-set is, is er geen synchronisatie nodig: dit is een 'single-master'; we hebben een OpLog waarin alle wijzigingen worden opgeslagen - in dit geval zijn alle wijzigingen al sequentially ordered in de 'OpLog'. Maar als we twee verschillende shards hebben, is tijdsynchronisatie belangrijk. Hier hebben vector clocks meer geholpen! Maar we hebben ze niet.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/7d3306747490ac044b7f8130defea0c9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDe tweede optie is de 'Heartbeats'. Je kunt signalen uitwisselen die elke tijdseenheid plaatsvinden. Maar 'Heartbeats' zijn te traag; we kunnen de latency niet waarborgen voor onze klant.<\/p>\n<p>True time is natuurlijk een prachtig iets. Maar, wederom, dat is waarschijnlijk de toekomst\u2026 Hoewel in 'Atlas' het al mogelijk is, zijn er al snelle 'Amazon' tijdssynchronisatoren. Maar dit zal niet voor iedereen beschikbaar zijn.<\/p>\n<p>Gossiping is wanneer alle berichten tijd bevatten. Dit is ongeveer wat wij gebruiken. Elk bericht tussen nodes, drivers, router data-nodes, absoluut alles voor 'MongoDB' \u2013 dit zijn elementen, componenten van de database die tijd bevatten. Overal hebben ze een hybride tijdwaarde die wordt doorgegeven. 64 bits? Dat kan.<\/p>\n<h3>Hoe werkt dit allemaal samen?<\/h3>\n<p>\nHier bekijk ik \u00e9\u00e9n replica-set om het iets eenvoudiger te maken. Er is een Primary en een Secondary. De Secondary voert replicatie uit en is niet altijd volledig gesynchroniseerd met de Primary.<\/p>\n<p>Er vindt een insert plaats in de 'Primary' met een bepaalde tijdwaarde. Deze insert verhoogt de interne teller met 11, als dit maximaal is. Of het controleert de tijdwaarden en synchroniseert op basis van de tijd, als de tijdwaarden hoger zijn. Dit stelt ons in staat om chronologisch te ordenen.<\/p>\n<p>Nadat hij de schrijfactie uitvoert, vindt er een belangrijk moment plaats. De klokken in 'MongoDB' worden alleen verhoogd bij een schrijfactie in de 'OpLog'. Dit is het evenement dat de status van het systeem verandert. In al de klassieke artikelen wordt een gebeurtenis beschouwd als het bericht dat de node bereikt: als het bericht is ontvangen, betekent dit dat het systeem zijn status heeft veranderd.<\/p>\n<p>Dit heeft te maken met het feit dat het moeilijk te begrijpen is hoe dit bericht zal worden ge\u00efnterpreteerd tijdens het onderzoek. We weten precies dat als het niet in de 'oplog' wordt weergegeven, het helemaal niet zal worden ge\u00efnterpreteerd, en de enige systeemstatuswijziging is een vermelding in de 'oplog'. Dit vereenvoudigt ons alles: het vereenvoudigt het model en stelt ons in staat om ordening te houden binnen \u00e9\u00e9n replica-set, en nog veel meer nuttigs.<\/p>\n<p>De waarde die al in de 'oplog' is opgeslagen, wordt teruggegeven \u2013 we weten dat deze waarde in de 'oplog' ligt, en de tijd is 12. Laten we zeggen dat er nu wordt gelezen vanaf een andere node (Secondary), en deze geeft al de afterClusterTime in het bericht door. Hij zegt: 'Ik heb alles nodig wat er minimaal na 12 of op het moment van twaalf is gebeurd' (zie bovenstaande afbeelding).<\/p>\n<p>Dit wordt Causal a consistent (CAT) genoemd. Er is een concept in de theorie dat dit een soort tijdslice is die consistent op zichzelf is. In dit geval kan je zeggen dat dit de systeemstatus is die was waargenomen op het tijdstip 12.<\/p>\n<p>Op dit moment is hier nog niets, omdat dit een situatie simuleert waarin de Secondary gegevens van de Primary moet repliceren. Hij wacht... En hier zijn de gegevens \u2013 deze waarden worden teruggestuurd.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/54d9de3e2696c1e5d19f4da206be090b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZo werkt het ongeveer. Bijna.<\/p>\n<p>Wat betekent 'bijna'? Laten we aannemen dat er een persoon is die heeft gelezen en begrepen hoe dit allemaal werkt. Hij begreep dat elke keer ClusterTime gebeurt, de interne logische klokken worden bijgewerkt, en dan verhoogt de volgende vermelding met \u00e9\u00e9n. Deze functie neemt 20 regels in beslag. Stel dat deze persoon het grootste mogelijke 64-bits getal, min \u00e9\u00e9n, doorgeeft.<\/p>\n<p>Waarom 'min \u00e9\u00e9n'? Omdat de interne klokken in deze waarde worden geplaatst (dit is blijkbaar het grootste mogelijke getal en groter dan de huidige tijd), dan zal er een vermelding in de 'oplog' plaatsvinden, en de klokken worden nog eens met \u00e9\u00e9n verhoogd \u2013 en dan zal er eigenlijk de maximale waarde zijn (daar zijn gewoon allemaal enen, verder is er niets meer, unsaint int's).<\/p>\n<p>Het is duidelijk dat het systeem daarna absoluut niet meer toegankelijk is voor iets. Je kunt het alleen maar ontladen, schoonmaken \u2013 veel handwerk. Volledige beschikbaarheid:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/634b25fe0ef1e0af39181cd59c7b522f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAls dit ergens anders wordt gerepliceerd, valt de hele cluster gewoon uit. Een absoluut onaanvaardbare situatie, die iedereen heel snel en eenvoudig kan veroorzaken! Daarom beschouwden we dit aspect als een van de belangrijkste. Hoe kunnen we dit voorkomen?<\/p>\n<h3>Onze aanpak is om clusterTime te ondertekenen.<\/h3>\n<p>\nZo wordt het doorgegeven in het bericht (tot de blauwe tekst). Maar we zijn ook handtekeningen gaan genereren (blauwe tekst):<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/c16e985f9610e01a61293e0d6dde459b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDe handtekening wordt gegenereerd met een sleutel die zich binnen de database bevindt, binnen een beveiligd perimeter; deze wordt automatisch gegenereerd en bijgewerkt (gebruikers zien hier niets van). Een hash wordt gegenereerd en elk bericht wordt bij creatie ondertekend en bij ontvangst gevalideerd.<br \/>\nMensen vragen zich misschien af: \"Hoeveel vertraagt dit alles?\" Ik heb gezegd dat het snel moet werken, vooral in de afwezigheid van deze functie.<\/p>\n<p>Wat betekent het om Causal consistency in dit geval te gebruiken? Dit toont de afterClusterTime-parameter. Zonder dit wordt waarde gewoon in elk geval doorgestuurd. Gossiping werkt altijd sinds versie 3.6.<\/p>\n<p>Als we constante generatie van handtekeningen toestaan, zal dit de systemen vertragen, zelfs zonder de functie, wat niet overeenkomt met onze principes en vereisten. Wat hebben we gedaan?<\/p>\n<h3>Doe het snel!<\/h3>\n<p>\nEen vrij eenvoudige zaak, maar een interessante truc \u2013 ik deel het, misschien is het interessant voor iemand.<br \/>\nWe hebben een hash waarin ondertekende gegevens zijn opgeslagen. Alle gegevens gaan door een cache. De cache ondertekent niet specifiek de tijd, maar een Range. Wanneer een bepaalde waarde binnenkomt, genereren we een Range, maskeren de laatste 16 bits, en deze waarde ondertekenen we:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/f4810456f08ba1cc69730ac0079d4206.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMet zo'n handtekening versnellen we het systeem (in feite) met 65 duizend keer. Het werkt geweldig: toen we experimenten uitvoerden, werd de tijd voor een opeenvolgende update echt met 10.000 keer verminderd. Het is duidelijk dat dit niet mogelijk is wanneer ze in wanorde zijn. Maar in de meeste praktische gevallen werkt het. De combinatie van de Range-handtekening met de handtekening hielp het veiligheidsprobleem op te lossen.<\/p>\n<h3>Wat hebben we geleerd?<\/h3>\n<p>\nLessen die we hieruit hebben getrokken:<\/p>\n<ul>\n<li>Je moet materialen, verhalen en artikelen lezen, omdat we veel interessante dingen te delen hebben. Wanneer we aan een functie werken (vooral nu, toen we transacties hebben gedaan, enz.), is het nodig om te lezen en te begrijpen. Dit kost tijd, maar het is eigenlijk erg nuttig, omdat het duidelijk maakt waar we staan. We hebben niet echt iets nieuws uitgevonden - we hebben gewoon de ingredi\u00ebnten genomen.\n<p>Er is een zekere verschillen in denken wanneer er een academische conferentie plaatsvindt (zoals 'Sigmon', bijvoorbeeld) - daar focussen mensen zich op nieuwe idee\u00ebn. Wat is de innovatie van ons algoritme? Hier is er eigenlijk niet veel nieuws. De nieuwigheid ligt eerder in hoe we bestaande benaderingen samen hebben gemengd. Daarom is het eerste wat moet worden gedaan, het lezen van de klassiekers, beginnend met Lamport.<\/li>\n<li>In productie zijn de eisen helemaal anders. Ik ben er zeker van dat velen van jullie niet te maken hebben met 'sferische' databases in een abstracte vacuum, maar met normale, realistische zaken, die problemen hebben met beschikbaarheid, latentie en fouttolerantie.<\/li>\n<li>Het laatste is dat we verschillende idee\u00ebn hebben moeten overwegen en verschillende artikelen hebben gecombineerd tot \u00e9\u00e9n benadering. Het idee van ondertekenen, bijvoorbeeld, kwam eigenlijk uit een artikel dat het Paxos-protocol behandelde, wat voor niet-bizantijnse falers binnen het autorisatieprotocol is, en voor bizantijnse - buiten het autorisatieprotocol... Over het algemeen, dat is precies wat we uiteindelijk hebben gedaan.\n<p>Er is absoluut niets nieuws aan! Maar zodra we alles samen hebben gemengd... Het is alsof je zegt dat het recept voor Olivier-salade onzin is, omdat eieren, mayo en komkommers al bestaan... Dit is ongeveer hetzelfde verhaal.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/2f9e5cb77079f9a0f7bdf76430c3386e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIk zal hierbij afsluiten. Bedankt!<\/p>\n<h3>Vragen<\/h3>\n<p>\n<b>Vraag uit de zaal (verder \u2013 V):<\/b> \u2013 Dank je, Michail, voor de presentatie! Het onderwerp over tijd is interessant. Je gebruikt Gossiping. Je zei dat iedereen zijn eigen tijd heeft, iedereen kent zijn lokale tijd. Ik begreep dat we een driver hebben - er kunnen veel klanten met drivers zijn, er zijn ook veel query-planners, er zijn ook veel shards... Wat gebeurt er met het systeem als er plotseling een discrepantie optreedt: iemand denkt dat hij een minuut voorloopt, iemand denkt dat hij een minuut achterloopt? Waar komen we dan uit?<\/p>\n<p><b>MT:<\/b> \u2013 Dat is eigenlijk een uitstekende vraag! Ik wilde net iets zeggen over shards. Als ik de vraag goed begrijp, hebben we de situatie: er is shard 1 en shard 2, en de leesoperaties vinden plaats vanaf deze twee shards \u2013 ze divergeren, ze communiceren niet met elkaar, omdat de tijd die ze kennen \u2013 verschillend is, vooral de tijd die ze hebben in de oplogs.<br \/>\nStel dat shard 1 een miljoen records heeft gemaakt, terwijl shard 2 \u2013 helemaal niets, en er komt een verzoek naar de twee shards. En de eerste heeft afterClusterTime van meer dan een miljoen. In zo'n situatie, zoals ik heb uitgelegd, zal shard 2 nooit reageren.<\/p>\n<p><b>V:<\/b> \u2013 Ik wilde weten hoe ze synchroniseren en \u00e9\u00e9n logische tijd selecteren?<\/p>\n<p><b>MT:<\/b> \u2013 Ze synchroniseren heel eenvoudig. Shard, wanneer het afterClusterTime ontvangt en geen tijd vindt in de \u2018Oplog\u2019 \u2013 initieert no approved. Dat betekent dat hij zelf zijn tijd verhoogt tot deze waarde. Dit betekent dat er geen gebeurtenissen zijn die aan dit verzoek voldoen. Hij cre\u00ebert deze gebeurtenis kunstmatig en wordt zo Causal Consistent.<\/p>\n<p><b>V:<\/b> \u2013 En als er daarna nog evenementen komen die ergens in het netwerk zijn verloren?<\/p>\n<p><b>MT:<\/b> \u2013 Shards zijn zo ontworpen dat deze evenementen niet meer zullen komen, omdat het een single master is. Zodra hij heeft geschreven, komen ze niet meer aan, maar zullen ze later komen. Het kan niet zo zijn dat ergens iets vastzit, dan doet hij no write, en vervolgens komen deze gebeurtenissen aan \u2013 en wordt de Causal consistency verstoord. Wanneer hij no write doet, moeten ze allemaal daarna arriveren (hij zal op hen wachten).<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/dbbc7c5c653f0c9fa449cceb88ed62ef.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>V:<\/b> \u2013 Ik heb een paar vragen over queues. Causal consistency gaat ervan uit dat er een bepaalde wachtrij van acties is die moeten worden uitgevoerd. Wat gebeurt er als een pakket verloren gaat? Dus de 10e, 11e\u2026 de 12e is verloren, terwijl alle andere wachten tot deze is uitgevoerd. En ineens gaat de machine kapot, we kunnen niets doen. Is er een maximale lengte van de wachtrij die zich ophoopt voordat deze wordt uitgevoerd? Wat voor fatale fout treedt er op bij het verlies van een bepaalde toestand? Bovendien, als we opschrijven dat er een bepaalde vorige toestand is, dan moeten we daar toch vanuit gaan? Maar dat deden we niet!<\/p>\n<p><b>MT:<\/b> \u2013 Ook dat is een prachtige vraag! Wat doen we? In MongoDB is er het concept van quorum records, quorum reading. In welke gevallen kan een bericht verloren gaan? Wanneer de opname niet quorum is of wanneer de leesoperatie niet quorum is (ook kan er wat garbage binnenkomen).<br \/>\nMet betrekking tot Causal consistency hebben we uitgebreide experimenten uitgevoerd, waarvan het resultaat was dat, wanneer de schrijf- en leesoperaties niet quorum zijn, er schendingen van Causal consistency optreden. Precies wat u zegt!<\/p>\n<p>Ons advies: gebruik ten minste quorum-lezen bij het gebruik van Causal consistency. In dit geval zal er niets verloren gaan, zelfs niet als de quorum-schrijven verloren gaat... Dit is een orthogonale situatie: als de gebruiker niet wil dat gegevens verloren gaan, moet hij quorum-schrijven gebruiken. Causal consistency biedt geen garantie voor duurzaamheid. De garantie voor duurzaamheid biedt replicatie en de bijbehorende infrastructuur.<\/p>\n<p><b>V:<\/b> \u2013 Wanneer we een instance aanmaken die is geconfigureerd voor sharding (niet master, maar slave), steunt deze dan op de unix-tijd van zijn eigen machine of op de tijd van de 'master'; wordt dit \u00e9\u00e9n keer gesynchroniseerd of periodiek?<\/p>\n<p><b>MT:<\/b> \u2013 Laat het me verduidelijken. Een shard (dat wil zeggen, een horizontale partitie) heeft altijd een Primary. En binnen een shard kan er een 'master' zijn en kunnen er replicas zijn. Maar een shard ondersteunt altijd schrijven, omdat het een bepaald domein moet ondersteunen (er is een Primary in de shard).<\/p>\n<p><b>V:<\/b> \u2013 Dus alles hangt volledig af van de 'master'? Wordt er altijd 'master'-tijd gebruikt?<\/p>\n<p><b>MT:<\/b> \u2013 Ja. Je kunt het zo zeggen: de klokken tikken wanneer er een schrijfoperatie plaatsvindt in de 'master', in de 'Oplog'.<\/p>\n<p><b>V:<\/b> \u2013 We hebben een klant die zich verbindt, en hij hoeft niets te weten over tijd?<\/p>\n<p><b>MT:<\/b> \u2013 Helemaal niets! Als we het hebben over hoe dit werkt aan de klantzijde: de klant, wanneer hij gebruik wil maken van Causal consistency, moet een sessie openen. In deze sessie staan alle transacties en de rechten\u2026 Een sessie is een ordening van logische gebeurtenissen die plaatsvinden met de klant.<\/p>\n<p>Als hij deze sessie opent en daarin aangeeft dat hij Causal consistency wil (als de sessie standaard Causal consistency ondersteunt), werkt alles automatisch. De driver onthoudt deze tijd en verhoogt deze wanneer er een nieuw bericht binnenkomt. Hij onthoudt welk antwoord de vorige keer van de server is teruggestuurd die de gegevens heeft geleverd. De volgende aanvraag bevat afterCluster ('tijd groter dan deze').<\/p>\n<p>De klant hoeft echt helemaal niets te weten! Dit is totaal ondoorzichtig voor hem. Wat kunnen mensen met deze functies doen? Ten eerste, je kunt veilig lezen van secundaire databasetypes: je kunt schrijven naar de primaire database en lezen van geografisch gerepliceerde secundaires, en er zeker van zijn dat het werkt. Bovendien kunnen de sessies die op de primaire database zijn geschreven, zelfs naar de secundaire database worden overgedragen, dat wil zeggen dat je niet \u00e9\u00e9n sessie, maar meerdere kunt gebruiken.<\/p>\n<p><b>V:<\/b> \u2013 Het concept van Eventual consistency is nauw verbonden met een nieuw niveau van computerwetenschappen \u2013 de datatypes CRDT (Conflict-free Replicated Data Types). Hebben jullie de integratie van deze datatypes in de database overwogen en wat kunnen jullie daarover zeggen?<\/p>\n<p><b>MT:<\/b> \u2013 Goede vraag! CRDT is zinvol bij conflicten tijdens schrijven: in MongoDB \u2013 single master.<\/p>\n<p><b>V:<\/b> \u2013 Ik heb een vraag van de DevOps. In de huidige wereld komen er weleens van die jezu\u00efetachtige situaties voor waarbij een Byzantijnse failure zich voordoet, en kwaadaardige mensen binnen de beveiligde perimeter beginnen muggen te steken in het protocol, door speciaal gemaakte pakketten te sturen?<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/99a521d04b416e6978aa68ce7c4a4c46.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>MT:<\/b> \u2013 Kwaadaardige mensen binnen de perimeter zijn net als een Trojan horse! Ze kunnen veel slechte dingen doen.<\/p>\n<p><b>V:<\/b> \u2013 Het is vanzelfsprekend dat je geen gaten in de server moet laten waardoor je een olifantenkudde kunt laten passeren en de hele cluster voor altijd kunt laten instorten\u2026 Herstel zal tijd kosten... Dit is zacht uitgedrukt, onjuist. Aan de andere kant is het interessant om te vragen: komen er in de echte wereld situaties voor waarin soortgelijke interne aanvallen plaatsvinden?<\/p>\n<p><b>MT:<\/b> \u2013 Aangezien ik niet vaak geconfronteerd word met beveiligingslekken in het echte leven, kan ik het niet zeggen \u2013 misschien komen ze wel voor. Maar als we het hebben over ontwikkelingsfilosofie, dan beschouwen we het zo: we hebben een perimeter die de jongens die security doen beschermt \u2013 dat is het slot, de muur; en binnen de perimeter kun je doen wat je wilt. Het is duidelijk dat er gebruikers zijn die alleen kunnen kijken, en er zijn gebruikers die de catalogus kunnen wissen.<\/p>\n<p>Afhankelijk van de rechten kan de schade die gebruikers kunnen aanrichten vari\u00ebren van een muis tot een olifant. Uiteraard kan een gebruiker met volledige rechten alles doen wat hij wil. Een gebruiker met beperkte rechten kan aanzienlijk minder schade aanrichten. Hij kan in het bijzonder het systeem niet breken.<\/p>\n<p><b>V:<\/b> \u2013 Binnen de beveiligde perimeter zijn er mensen die onverwachte protocollen voor de server proberen te cre\u00ebren, om de server vast te zetten, en als je geluk hebt, misschien zelfs de hele cluster... Is dat echt zo \"goed\"?<\/p>\n<p><b>MT:<\/b> \u2013 Ik heb nog nooit van zulke dingen gehoord. Het is geen geheim dat je op deze manier een server kunt uitvallen. Het is niet mogelijk om dit intern te doen, terwijl je geverifieerd bent als gebruiker die iets in een bericht kan schrijven... In werkelijkheid kan dat niet, want het moet nog steeds worden geverifieerd. Er is een mogelijkheid om deze authenticatie uit te schakelen voor gebruikers die dat niet willen - dat is dan hun probleem; ze hebben, grof gezegd, zelf de muren verwoest en je kunt er een olifant in proppen die alles verplettert... Maar in feite kun je je als monteur verkleden, komen en het eruit trekken!<\/p>\n<p><b>V:<\/b> \u2013 Bedankt voor de presentatie. Sergey (\"Yandex\"). In \"Mongo\" is er een constante die het aantal stemgerechtigde leden in de Replica Set limiteert, en deze constante is gelijk aan 7 (zeven). Waarom is dit een constante? Waarom is dit geen parameter of zoiets?<\/p>\n<p><b>MT:<\/b> \u2013 In een Replica Set kunnen we ook wel niet-stemgerechtigde leden draaien, maar stemgerechtigden \u2013 maximaal 7. Hoe ga je in dit geval om met een uitval, als onze Replica Set verspreid is over 3 datacentra? E\u00e9n datacentrum kan makkelijk uitvallen, en nog een andere machine kan eruit vallen.<\/p>\n<p><b>V:<\/b> \u2013 Dit valt al een beetje buiten de presentatie. Dit is een algemene vraag. Misschien kan ik het later uitleggen.<\/p>\n<p><b>MT:<\/b> De volgende HighLoad++ conferentie vindt plaats op 6 en 7 april 2020 in St. Petersburg. Details en tickets via de link.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Causale consistentie: van theorie naar praktijk\" src=\"\/wp-content\/uploads\/2020\/02\/161966c7e77704dc619674ff0302ff57.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<center><div class=\"youtube-placeholder\" data-id=\"UnAprFMX1d4\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/UnAprFMX1d4\/hqdefault.jpg\" alt=\"Video afspelen\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<h3>Een beetje reclame \ud83d\ude42<\/h3>\n<p>\nBedankt dat je bij ons blijft. Houd je van onze artikelen? Wil je meer interessante inhoud zien? Ondersteun ons door een bestelling te plaatsen of ons aan vrienden aan te bevelen, <noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/cloudvps\/nl\">cloud VPS voor ontwikkelaars vanaf $4,99<\/a><\/noindex>, <b>een unieke variant van entry-level servers, die we voor jou hebben bedacht:<\/b> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/347386\/\">De waarheid over VPS (KVM) E5-2697 v3 (6 Kernen) 10GB DDR4 480GB SSD 1Gbps vanaf $19 of hoe deel je een server correct?<\/a><\/noindex> (opties beschikbaar met RAID1 en RAID10, tot 24 cores en tot 40GB DDR4).<\/p>\n<p><b>Dell R730xd is 2 keer goedkoper in datacenter Equinix Tier IV in Amsterdam?<\/b> Alleen bij ons <b><noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/serversnl\">2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100TB vanaf $199<\/a><\/noindex> in Nederland! <b>Dell R420 \u2014 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB \u2014 vanaf $99!<\/b><\/b> Lees over hoe <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/329618\/\">je een infrastructuur van bedrijfsniveau kunt opbouwen met Dell R730xd E5-2650 v4 servers die wel \u20ac9000 kosten voor een prikkie?<\/a><\/noindex><br \/>\n<br \/>Bron: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ua-hosting\/blog\/487638\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435. HighLoad++ Siberia 2019. \u0417\u0430\u043b \u00ab\u041a\u0440\u0430\u0441\u043d\u043e\u044f\u0440\u0441\u043a\u00bb. 25 \u0438\u044e\u043d\u044f, 12:00. \u0422\u0435\u0437\u0438\u0441\u044b \u0438 \u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f. \u0411\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0443\u044e\u0442 \u0441 \u0442\u0435\u043e\u0440\u0438\u0435\u0439, \u0433\u0434\u0435 \u043d\u0435 \u0443\u0447\u0442\u0435\u043d\u044b \u0432\u0430\u0436\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0430\u0441\u043f\u0435\u043a\u0442\u044b. \u0412 \u044d\u0442\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e [&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-56365","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=\"\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.\" \/>\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\/nl\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\udd47HighLoad++, \u041c\u0438\u0445\u0430\u0438\u043b \u0422\u044e\u043b\u0435\u043d\u0435\u0432 (MongoDB): Causal consistency: \u043e\u0442 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike\" \/>\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=\"2020-02-10T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:04:37+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\udd47HighLoad++, Mikhail Tyulenyev (MongoDB): Causale consistentie: van theorie naar praktijk | ProHoster","description":"\ud83e\udd47HighLoad++, Mikhail Tyulenyev (MongoDB): Causale consistentie: van theorie naar praktijk | ProHoster","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","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\udd47HighLoad++, \u041c\u0438\u0445\u0430\u0438\u043b \u0422\u044e\u043b\u0435\u043d\u0435\u0432 (MongoDB): Causal consistency: \u043e\u0442 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 | ProHoster","og:description":"\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.","og:url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","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":"2020-02-10T21:00:00+00:00","article:modified_time":"2020-02-18T11:04:37+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"56365","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:26:38","updated":"2022-09-29 16:36:31","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/56365","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=56365"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/56365\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=56365"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=56365"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=56365"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}