{"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\/de\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","title":{"rendered":"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Die n\u00e4chste Konferenz HighLoad++ findet am 6. und 7. April 2020 in Sankt Petersburg statt. <br \/>\nDetails und Tickets <noindex><a rel=\"nofollow\" href=\"http:\/\/bit.ly\/2sSxgBx\">unter diesem Link<\/a><\/noindex>. HighLoad++ Sibirien 2019. Saal \u201eKrasnojarsk\u201c. 25. Juni, 12:00. Thesen und <noindex><a rel=\"nofollow\" href=\"https:\/\/www.highload.ru\/siberia\/2019\/abstracts\/5253\">Pr\u00e4sentation<\/a><\/noindex>.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/cded9c5434d670db7295aadf5da0a9f1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEs kommt vor, dass praktische Anforderungen mit der Theorie in Konflikt stehen, in der wichtige Aspekte f\u00fcr ein kommerzielles Produkt nicht ber\u00fccksichtigt werden. In diesem Vortrag wird der Prozess der Auswahl und Kombination verschiedener Ans\u00e4tze zur Erstellung von Komponenten f\u00fcr die kausale Konsistenz basierend auf akademischen Forschungsergebnissen beschrieben, die aus den Anforderungen eines kommerziellen Produkts abgeleitet sind. Die Zuh\u00f6rer erfahren von bestehenden theoretischen Ans\u00e4tzen zu logischen Uhren, Abh\u00e4ngigkeitsverfolgung, Systemsicherheit, Zeitsynchronisation und warum MongoDB sich f\u00fcr bestimmte L\u00f6sungen entschieden hat.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><b>Mikhail Tyulenev (im Folgenden \u2013 MT):<\/b> \u2013 Ich werde \u00fcber kausale Konsistenz sprechen \u2013 eine Funktion, an der wir bei MongoDB gearbeitet haben. Ich arbeite in der Gruppe f\u00fcr verteilte Systeme, wir haben sie vor etwa zwei Jahren entwickelt.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/b8d0a5b64e715f53b033fa8c398e2eb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIm Verlauf musste ich mich mit einer Vielzahl akademischer Forschung auseinandersetzen, weil diese Funktion recht gut untersucht ist. Es stellte sich heraus, dass keine der Ver\u00f6ffentlichungen den Anforderungen im Produktionsumfeld entspricht, da die spezifischen Anforderungen, die in jeder Produktionsanwendung vorhanden sind, ber\u00fccksichtigt werden m\u00fcssen.<\/p>\n<p>Ich werde dar\u00fcber sprechen, wie wir, als Verbraucher akademischer Forschung, daraus etwas erstellen, das wir unseren Nutzern als fertiges Produkt anbieten k\u00f6nnen, das einfach und sicher zu verwenden ist.<\/p>\n<h3>Kausale Konsistenz. Lassen Sie uns die Begriffe kl\u00e4ren<\/h3>\n<p>\nZun\u00e4chst m\u00f6chte ich in groben Z\u00fcgen erl\u00e4utern, was kausale Konsistenz ist. Es gibt zwei Charaktere \u2013 Leonard und Penny (aus der Serie \u201eThe Big Bang Theory\u201c):<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/ee0835b604ae5d5d6c0fa1bc369e6b18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAngenommen, Penny ist in Europa und Leonard m\u00f6chte ihr eine \u00dcberraschung, eine Party, machen. Und er denkt sich nichts Besseres aus, als sie aus seiner Freundesliste zu entfernen und allen Freunden ein Update im Feed zu schicken: \u201eLasst uns Penny erfreuen!\u201c (sie ist in Europa, w\u00e4hrend sie schl\u00e4ft, sieht sie das alles nicht und kann es nicht sehen, weil sie nicht dort ist). Schlie\u00dflich l\u00f6scht er diesen Beitrag, entfernt ihn aus dem Feed und stellt den Zugang wieder her, sodass sie nichts bemerkt und es keinen Skandal gibt.<br \/>\nDas ist alles wunderbar, aber nehmen wir an, das System ist verteilt und die Ereignisse laufen nicht ganz so ab. Es k\u00f6nnte zum Beispiel passieren, dass die Zugriffsbeschr\u00e4nkung von Penny eintrat, nachdem dieser Beitrag erschienen ist, wenn die Ereignisse nicht durch kausale Zusammenh\u00e4nge verbunden sind. Das ist ein Beispiel daf\u00fcr, wann kausale Konsistenz erforderlich ist, um eine Gesch\u00e4ftsanforderung zu erf\u00fcllen (in diesem Fall).<\/p>\n<p>Tats\u00e4chlich sind dies ziemlich nicht-triviale Eigenschaften von Datenbanken \u2013 nur sehr wenige unterst\u00fctzen sie. Lassen Sie uns zu den Modellen \u00fcbergehen.<\/p>\n<h3>Konsistenzmodelle<\/h3>\n<p>\nWas ist \u00fcberhaupt ein Konsistenzmodell in Datenbanken? Es sind bestimmte Garantien, die ein verteiltes System bez\u00fcglich der Daten und der Reihenfolge, in der der Kunde sie erhalten kann, gibt.<\/p>\n<p>Im Grunde h\u00e4ngen alle Konsistenzmodelle davon ab, wie sehr ein verteiltes System einer solchen Architektur \u00e4hnelt, die beispielsweise auf einem einzigen Node auf einem Laptop l\u00e4uft. Und wie sehr sich ein System, das auf Tausenden von geografisch verteilten Nodes arbeitet, von einem Laptop unterscheidet, in dem all diese Eigenschaften prinzipiell automatisch erf\u00fcllt sind.<\/p>\n<p>Deshalb gelten Konsistenzmodelle nur f\u00fcr verteilte Systeme. Alle Systeme, die fr\u00fcher existierten und auf vertikaler Skalierung basierten, hatten solche Probleme nicht. Dort gab es einen Buffer Cache, aus dem alles stets abgerufen wurde.<\/p>\n<h3>Starke Modell<\/h3>\n<p>\nDie tats\u00e4chlich erste Modell ist das Starke (oder auch Riseability, wie es oft genannt wird). Es handelt sich um ein Konsistenzmodell, das garantiert, dass jede \u00c4nderung, sobald die Best\u00e4tigung vorliegt, dass sie erfolgt ist, von allen Nutzern des Systems gesehen werden kann.<\/p>\n<p>Das schafft eine globale Reihenfolge aller Ereignisse in der Datenbank. Dies ist eine sehr starke Konsistenzeigenschaft und sie ist insgesamt sehr kostenintensiv. Dennoch wird sie sehr gut unterst\u00fctzt. Sie ist einfach sehr teuer und langsam \u2013 daher wird sie selten genutzt. Das nennt man Riseability.<\/p>\n<p>Es gibt eine weitere, st\u00e4rkere Eigenschaft, die im Spanner unterst\u00fctzt wird \u2013 sie wird externe Konsistenz genannt. Dar\u00fcber werden wir sp\u00e4ter sprechen.<\/p>\n<h3>Kausal<\/h3>\n<p>\nDas N\u00e4chste ist Causal, genau das, wor\u00fcber ich gesprochen habe. Zwischen Strong und Causal gibt es noch einige Unterebenen, \u00fcber die ich nicht sprechen werde, aber sie alle reduzieren sich auf Causal. Dieses Modell ist wichtig, weil es das st\u00e4rkste von allen Modellen ist, die st\u00e4rkste Konsistenz bei Vorhandensein von Netzwerken oder Partitionen.<\/p>\n<p>Causals sind die Situation, in der Ereignisse durch eine kausale Beziehung verbunden sind. Sehr oft werden sie aus der Perspektive des Kunden als Read your own rights wahrgenommen. Wenn der Kunde bestimmte Werte beobachtet hat, kann er die Werte, die in der Vergangenheit waren, nicht sehen. Er beginnt bereits, pr\u00e4fixartige Lesevorg\u00e4nge zu sehen. Das alles l\u00e4uft auf dasselbe hinaus.<br \/>\nCausals als Konsistenzmodell bedeutet eine partielle Ordnung von Ereignissen auf dem Server, bei der die Ereignisse von allen Clients in derselben Reihenfolge beobachtet werden. In diesem Fall - Leonard und Penny.<\/p>\n<h3>Eventual<\/h3>\n<p>\nDas dritte Modell ist die Eventual Consistency. Das ist das, was alle verteilten Systeme unterst\u00fctzen, das Mindestmodell, das \u00fcberhaupt sinnvoll ist. Es bedeutet Folgendes: Wenn wir \u00c4nderungen an den Daten vornehmen, werden sie irgendwann konsistent.<\/p>\n<p>In diesem Moment sagt es nichts, sonst w\u00fcrde es zur External Consistency werden - das w\u00e4re eine ganz andere Geschichte. Dennoch ist dies ein sehr beliebtes Modell, das am weitesten verbreitet ist. Standardm\u00e4\u00dfig verwenden alle Benutzer verteilter Systeme tats\u00e4chlich die Eventual Consistency.<\/p>\n<p>Ich m\u00f6chte einige vergleichende Beispiele anf\u00fchren:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/c23e59b30d96de6ec456aaa76c67ad61.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWas bedeuten diese Pfeile?<\/p>\n<ul>\n<li><b>Latenz.<\/b> Bei zunehmender St\u00e4rke der Konsistenz wird sie aus offensichtlichen Gr\u00fcnden gr\u00f6\u00dfer: Es m\u00fcssen mehr Aufzeichnungen gemacht, Best\u00e4tigungen von allen Hosts und Knoten im Cluster eingeholt werden, dass die Daten dort bereits vorhanden sind. Dementsprechend ist die Eventual Consistency die schnellste Antwort, weil man dort in der Regel sogar im Speicher committieren kann und das grunds\u00e4tzlich ausreicht.<\/li>\n<li><b>Verf\u00fcgbarkeit.<\/b> Wenn man dies als die M\u00f6glichkeit versteht, dass das System bei Vorhandensein von Netzwerkunterbrechungen, Partitionen oder einigen Ausf\u00e4llen antworten kann - die Fehlertoleranz steigt bei abnehmendem Konsistenzmodell, da es ausreicht, dass ein Host erreichbar ist und dabei einige Daten liefert. Eventual Consistency garantiert im \u00dcbrigen nichts \u00fcber die Daten - es kann alles M\u00f6gliche sein.<\/li>\n<li><b>Anomalien.<\/b> Dabei steigt nat\u00fcrlich die Anzahl der Anomalien. Bei Strong Consistency sollten diese eigentlich kaum vorkommen, w\u00e4hrend sie bei Eventual Consistency beliebig h\u00e4ufig sein k\u00f6nnen. Die Frage stellt sich: Warum w\u00e4hlen die Menschen Eventual Consistency, wenn sie Anomalien enth\u00e4lt? Die Antwort liegt darin, dass Eventual Consistency-Modelle anwendbar sind und Anomalien zum Beispiel nur f\u00fcr einen kurzen Zeitraum bestehen; es gibt die M\u00f6glichkeit, einen Master zum Lesen zu nutzen und mehr oder weniger konsistente Daten zu lesen; oft gibt es die M\u00f6glichkeit, starke Konsistenzmodelle zu verwenden. Praktisch funktioniert das und h\u00e4ufig ist die Anzahl der Anomalien zeitlich begrenzt.<\/li>\n<\/ul>\n<p><\/p>\n<h3>CAP-Theorem<\/h3>\n<p>\nWenn Sie die Begriffe Consistency und Availability sehen, was kommt Ihnen in den Sinn? Richtig \u2013 das CAP-Theorem! Ich m\u00f6chte jetzt einen Mythos aufkl\u00e4ren\u2026 Das bin nicht ich \u2013 es ist Martin Kleppmann, der einen gro\u00dfartigen Artikel und ein hervorragendes Buch geschrieben hat.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/02a9b84585218c4e85afd65f7e88aa26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas CAP-Theorem ist ein Prinzip, das in den 2000er Jahren formuliert wurde, wonach Consistency, Availability und Partitions: W\u00e4hlen Sie beliebig zwei, und die dritte kann nicht gew\u00e4hlt werden. Das war ein gewisses Prinzip. Es wurde einige Jahre sp\u00e4ter als Theorem bewiesen, das taten Gilbert und Lynch. Danach wurde es wie ein Mantra verwendet \u2013 Systeme wurden in CA, CP, AP und so weiter unterteilt.<\/p>\n<p>Dieses Theorem wurde tats\u00e4chlich f\u00fcr folgende F\u00e4lle bewiesen... Erstens wurde Availability nicht als kontinuierlicher Wert von null bis hundert betrachtet (0 \u2013 System 'tot', 100 \u2013 antwortet schnell; so haben wir es uns angew\u00f6hnt zu betrachten), sondern als eine Eigenschaft eines Algorithmus, die garantiert, dass er bei allen seinen Ausf\u00fchrungen Daten zur\u00fcckgibt.<\/p>\n<p>\u00dcber die Antwortzeit steht dort kein Wort! Es gibt einen Algorithmus, der Daten nach 100 Jahren zur\u00fcckgibt \u2013 ein v\u00f6llig hervorragender verf\u00fcgbarer Algorithmus, der Teil des CAP-Theorems ist.<br \/>\nZweitens: Das Theorem wurde f\u00fcr \u00c4nderungen der Werte desselben Schl\u00fcssels bewiesen, wobei diese \u00c4nderungen eine resizable Linie darstellen. Das bedeutet, dass sie in der Praxis kaum verwendet werden, weil es andere Modelle wie Eventual Consistency, Strong Consistency (vielleicht) gibt.<\/p>\n<p>Worauf will ich hinaus? Auf das, dass das CAP-Theorem in der Form, wie es bewiesen wurde, praktisch nicht anwendbar ist und selten verwendet wird. In der theoretischen Form schr\u00e4nkt es auf eine gewisse Weise alles ein. Es ergibt sich ein gewisses Prinzip, das intuitiv korrekt ist, aber insgesamt nicht wirklich bewiesen ist.<\/p>\n<h3>Causal Consistency ist das st\u00e4rkste Modell<\/h3>\n<p>\nWas jetzt passiert, ist, dass man alle drei Dinge erhalten kann: Konsistenz, Verf\u00fcgbarkeit kann durch Partitionen erreicht werden. Insbesondere die kausale Konsistenz \u2013 das ist das st\u00e4rkste Konsistenzmodell, das auch bei Partitions (Netzwerkausf\u00e4llen) funktioniert. Deshalb ist es so interessant, daher haben wir uns damit besch\u00e4ftigt.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/c4320294320261858a6d22faa97b9e23.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nErstens vereinfacht es die Arbeit der Anwendungsentwickler. Insbesondere gibt es eine starke Unterst\u00fctzung vom Server: Wenn alle Aufzeichnungen, die innerhalb eines Clients erfolgen, garantiert in dieser Reihenfolge auf einem anderen Client ankommen. Zweitens h\u00e4lt sie Partitionen stand.<\/p>\n<h3>Die interne K\u00fcche von MongoDB<\/h3>\n<p>\nIm Gedenken an das Mittagessen bewegen wir uns in die K\u00fcche. Ich werde \u00fcber das Systemmodell erz\u00e4hlen, insbesondere \u2013 was MongoDB f\u00fcr diejenigen ist, die zum ersten Mal von dieser Datenbank h\u00f6ren.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" 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): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/a1f9bcb4daebb43e4fc848a5f5f07c60.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMongoDB (im Folgenden \u201eMongoDB\u201c) ist ein verteiltes System, das horizontale Skalierung unterst\u00fctzt, also Sharding; und innerhalb jedes Shards unterst\u00fctzt es auch Datenredundanz, also Replikation.<\/p>\n<p>Sharding in \u201eMongoDB\u201c (kein relationales DBMS) f\u00fchrt eine automatische Balancierung durch, das hei\u00dft, jede Dokumentensammlung (oder \u201eTabelle\u201c in relationalen Daten) wird in St\u00fccke zerlegt, und der Server bewegt sie automatisch zwischen den Shards.<\/p>\n<p>Der Query Router, der die Anfragen verteilt, ist f\u00fcr den Client eine Art von Client, \u00fcber den er arbeitet. Er wei\u00df bereits, wo sich welche Daten befinden und leitet alle Anfragen an den richtigen Shard weiter.<\/p>\n<p>Ein weiterer wichtiger Punkt: MongoDB ist ein Single Master. Es gibt einen Primary \u2013 dieser kann Aufzeichnungen \u00fcbernehmen, die die Schl\u00fcssel unterst\u00fctzen, die er enth\u00e4lt. Multi-Master-Schreibvorg\u00e4nge sind nicht m\u00f6glich.<\/p>\n<p>Wir haben das Release 4.2 gemacht \u2013 es sind neue interessante Dinge hinzugekommen. Insbesondere haben wir Lucene eingef\u00fchrt \u2013 die Suche \u2013 also ausf\u00fchrbares Java direkt in \u201eMongo\u201c, und jetzt ist es m\u00f6glich, die Suche \u00fcber Lucene durchzuf\u00fchren, genauso wie in \u201eElasticsearch\u201c.<\/p>\n<p>Und wir haben ein neues Produkt geschaffen \u2013 Charts, das ebenfalls auf \u201eAtlas\u201c (der eigene Cloud von \u201eMongo\u201c) verf\u00fcgbar ist. Sie haben ein Free Tier \u2013 man kann damit experimentieren. Charts hat mir sehr gefallen \u2013 Datenvisualisierung, sehr intuitiv.<\/p>\n<h3>Zutaten der kausalen Konsistenz<\/h3>\n<p>\nIch habe ungef\u00e4hr 230 Artikel gez\u00e4hlt, die zu diesem Thema ver\u00f6ffentlicht wurden \u2013 von Leslie Lamport. Ich werde Ihnen jetzt aus meinem Ged\u00e4chtnis einige Teile dieser Materialien \u00fcbermitteln.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/e88b34b7a724e94837b944a4ddd21a04.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAlles begann mit dem Artikel von Leslie Lampert, der in den 1970er Jahren geschrieben wurde. Wie Sie sehen, gibt es bis heute weiterhin Forschungsarbeiten zu diesem Thema. Derzeit erlebt die kausale Konsistenz ein Interesse im Zusammenhang mit der Entwicklung von verteilten Systemen.<\/p>\n<h3>Einschr\u00e4nkungen<\/h3>\n<p>\nWelche Einschr\u00e4nkungen gibt es? Das ist tats\u00e4chlich einer der Hauptpunkte, denn die Einschr\u00e4nkungen, die Produktionssysteme aufweisen, unterscheiden sich erheblich von den Einschr\u00e4nkungen, die in akademischen Artikeln existieren. Oft sind sie recht k\u00fcnstlich.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/9583ba9ff870e4ddc7aad4ba4c59ecc1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Erstens, \u201eMongoDB\u201c ist ein Single-Master, wie ich bereits gesagt habe (das vereinfacht vieles).<\/li>\n<li>Wir gehen davon aus, dass das System etwa 10.000 Shards unterst\u00fctzen sollte. Wir k\u00f6nnen keine architektonischen Entscheidungen treffen, die diesen Wert eindeutig einschr\u00e4nken.<\/li>\n<li>Wir haben eine Cloud, aber wir gehen davon aus, dass der Benutzer die M\u00f6glichkeit haben sollte, wenn er das Binary herunterl\u00e4dt, es auf seinem Laptop ausf\u00fchrt und alles perfekt funktioniert.<\/li>\n<li>Wir gehen davon aus, dass das in der Forschung selten genutzt wird: externe Clients k\u00f6nnen tun, was sie wollen. \u201eMongoDB\u201c ist Open Source. Entsprechend k\u00f6nnen Clients sehr clever oder b\u00f6sartig sein \u2013 sie k\u00f6nnen alles kaputtmachen wollen. Wir gehen davon aus, dass byzantinische Fehler auftreten k\u00f6nnen.<\/li>\n<li>F\u00fcr externe Clients, die au\u00dferhalb des Perimeters sind \u2013 eine wichtige Einschr\u00e4nkung: Wenn diese Funktion deaktiviert ist, sollten keine Leistungsverschlechterungen beobachtet werden.<\/li>\n<li>Ein weiterer Punkt \u2013 ganz anti-akademisch: die Kompatibilit\u00e4t zwischen fr\u00fcheren und zuk\u00fcnftigen Versionen. Alte Treiber m\u00fcssen neue Updates unterst\u00fctzen, und die Datenbank muss alte Treiber unterst\u00fctzen.<\/li>\n<\/ul>\n<p>\nInsgesamt stellen all dies Einschr\u00e4nkungen dar.<\/p>\n<h3>Komponenten der kausalen Konsistenz<\/h3>\n<p>\nIch werde jetzt einige Komponenten vorstellen. Wenn man die kausale Konsistenz betrachtet, lassen sich verschiedene Bl\u00f6cke unterscheiden. Wir haben aus Arbeiten ausgew\u00e4hlt, die zu einem bestimmten Block geh\u00f6ren: Abh\u00e4ngigkeitsverfolgung, die Auswahl von Uhren, wie diese Uhren untereinander synchronisiert werden k\u00f6nnen, und wie wir Sicherheit gew\u00e4hrleisten \u2013 das ist ein grober \u00dcberblick \u00fcber das, wor\u00fcber ich sprechen werde:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/10c2631d6e61a280139b448628db763e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Vollst\u00e4ndige Abh\u00e4ngigkeitsverfolgung (Full Dependency Tracking)<\/h3>\n<p>\nWarum ist das n\u00f6tig? Damit, wenn Daten repliziert werden \u2013 jeder Eintrag, jede \u00c4nderung der Daten enth\u00e4lt Informationen dar\u00fcber, von welchen \u00c4nderungen sie abh\u00e4ngt. Die allererste und naivste \u00c4nderung ist die, dass jede Nachricht, die einen Eintrag enth\u00e4lt, Informationen \u00fcber die vorherigen Nachrichten enth\u00e4lt:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/fa5d0086c3c77e33631d8a2cd5c217fa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn diesem Beispiel sind die Nummern in geschweiften Klammern die Eintragsnummern. Manchmal werden diese Eintr\u00e4ge mit den Werten sogar ganz \u00fcbergeben, manchmal werden irgendwelche Versionen \u00fcbergeben. Der Kern der Sache ist, dass jede \u00c4nderung Informationen \u00fcber die vorherige enth\u00e4lt (sie tr\u00e4gt all dies klar in sich).<\/p>\n<p>Warum haben wir uns entschieden, einen solchen Ansatz (vollst\u00e4ndiges Tracking) nicht zu verwenden? Offensichtlich, weil dieser Ansatz unpraktisch ist: Jede \u00c4nderung in einem sozialen Netzwerk h\u00e4ngt von allen vorherigen \u00c4nderungen in diesem sozialen Netzwerk ab, was zum Beispiel \u201eFacebook\u201c oder \u201eVKontakte\u201c in jedem Update \u00fcbertr\u00e4gt. Dennoch gibt es viele Studien \u00fcber genau das Full Dependency Tracking \u2013 das sind pr\u00e4-soziale Netzwerke, in einigen Situationen funktioniert das tats\u00e4chlich.<\/p>\n<h3>Explizites Abh\u00e4ngigkeits-Tracking (Explicit Dependency Tracking)<\/h3>\n<p>\nDer n\u00e4chste ist eingeschr\u00e4nkter. Hier wird ebenfalls die \u00dcbertragung von Informationen betrachtet, aber nur von der, die offensichtlich abh\u00e4ngt. Was von was abh\u00e4ngt, bestimmt in der Regel bereits die Anwendung. Wenn Daten repliziert werden, werden bei einer Anfrage nur die Antworten zur\u00fcckgegeben, wenn die vorherigen Abh\u00e4ngigkeiten erf\u00fcllt sind, das hei\u00dft, angezeigt werden. Darin liegt der Kern, wie kausale Konsistenz funktioniert.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/7fe101b998c1a0c922788d8d36a5243f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSie sieht, dass Eintrag 5 von den Eintr\u00e4gen 1, 2, 3, 4 abh\u00e4ngt \u2013 entsprechend wartet sie, bevor der Kunde Zugriff auf die \u00c4nderungen erh\u00e4lt, die durch das Zugriffsrecht von Penny vorgenommen wurden, wenn alle vorherigen \u00c4nderungen bereits in die Datenbank eingegangen sind.<\/p>\n<p>Das befriedigt uns auch nicht, weil es trotzdem zu viele Informationen gibt, und das wird langsam machen. Es gibt einen anderen Ansatz\u2026<\/p>\n<h3>Lamport-Uhr (Lamport Clock)<\/h3>\n<p>\nSie sind sehr alt. Die Lamport-Uhr impliziert, dass diese Abh\u00e4ngigkeiten in eine skalare Funktion zusammengefasst werden, die Lamport-Uhr genannt wird.<\/p>\n<p>Eine skalare Funktion ist eine abstrakte Zahl. Oft wird sie als logische Zeit bezeichnet. Bei jedem Ereignis erh\u00f6ht sich dieser Z\u00e4hler. Der Z\u00e4hler, der derzeit dem Prozess bekannt ist, sendet jede Nachricht. Es ist klar, dass Prozesse desynchronisiert sein k\u00f6nnen und unterschiedliche Zeiten haben k\u00f6nnen. Dennoch gleicht das System durch diesen Nachrichtenaustausch die Uhren irgendwie aus. Was passiert in diesem Fall?<\/p>\n<p>Ich habe den gro\u00dfen Shard halbiert, um es verst\u00e4ndlich zu machen: Friends k\u00f6nnen in einem Knoten leben, der ein St\u00fcck der Sammlung enth\u00e4lt, w\u00e4hrend Feed in einem v\u00f6llig anderen Knoten leben kann, der ein St\u00fcck dieser Sammlung enth\u00e4lt. Ist klar, wie sie nicht in der Warteschlange landen k\u00f6nnen? Zuerst sagt Feed: \"Repliziert\", und dann - Friends. Wenn das System keine Garantien bietet, dass Feed nicht angezeigt wird, solange die Abh\u00e4ngigkeiten von Friends in der Sammlung Friends auch nicht geliefert werden, haben wir genau die Situation, die ich erw\u00e4hnt habe.<\/p>\n<p>Sie sehen, wie sich die logische Zeit des Counters auf dem Feed erh\u00f6ht:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/bae152d1890b53804f2cb28122983df6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDaher ist die Hauptsache, die diese Lamport-Uhr und die kausale Konsistenz (erkl\u00e4rt durch die Lamport-Uhr) zusammenh\u00e4lt: Wenn wir Ereignisse A und B haben und Ereignis B von Ereignis A abh\u00e4ngt *, dann folgt daraus, dass die Logische Zeit von Ereignis A kleiner ist als die Logische Zeit von Ereignis B.<\/p>\n<p><i>* Manchmal wird auch gesagt, dass A vor B passiert ist, das hei\u00dft, A geschah vor B \u2013 das ist eine Art Relation, die die Gesamtheit der Ereignisse, die \u00fcberhaupt stattgefunden haben, teilweise ordnet.<\/i><\/p>\n<p>Umgekehrt gilt das nicht. Das ist tats\u00e4chlich einer der Hauptnachteile der Lamport-Uhr \u2013 die partielle Ordnung. Es gibt das Konzept von gleichzeitigen Ereignissen, das hei\u00dft Ereignisse, bei denen weder (A passiert vor B) noch (A passiert vor B) gilt. Ein Beispiel k\u00f6nnte das gleichzeitige Hinzuf\u00fcgen von Leonard zu den Freunden einer anderen Person sein (nicht einmal von Leonard, sondern von Sheldon, zum Beispiel).<br \/>\nDas ist die Eigenschaft, die oft bei der Arbeit mit Lamport-Uhren genutzt wird: Man schaut sich genau die Funktion an und zieht daraus den Schluss \u2013 vielleicht sind diese Ereignisse abh\u00e4ngig. Denn in eine Richtung ist es wahr: Wenn die Logische Zeit A kleiner ist als die Logische Zeit B, dann kann B nicht vor A passieren; ist sie gr\u00f6\u00dfer, dann kann es sein.<\/p>\n<h3>Vektor-Uhren (Vector Clock)<\/h3>\n<p>\nDie logische Entwicklung der Lamport-Uhren sind die Vektor-Uhren. Sie unterscheiden sich dadurch, dass jeder Knoten, der hier vorhanden ist, seine eigenen, separaten Uhren enth\u00e4lt, und diese werden als Vektor \u00fcbermittelt.<br \/>\nIn diesem Fall sehen Sie, dass der Nullindex des Vektors f\u00fcr den Feed und der erste Index des Vektors f\u00fcr die Freunde verantwortlich ist (jede dieser Knoten). Und jetzt werden sie zunehmen: Der Nullindex des \"Feeds\" erh\u00f6ht sich bei der Aufzeichnung \u2013 1, 2, 3:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/d89292686ed8dd41aef06090f16db1c0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWas sind die Vorteile von Vektoruhren? Sie erm\u00f6glichen es, welche Ereignisse simultan sind und wann sie an verschiedenen Knoten stattfinden. Das ist f\u00fcr das Sharding-System wie \"MongoDB\" sehr wichtig. Wir haben uns jedoch nicht daf\u00fcr entschieden, obwohl es ein gro\u00dfartiges Tool ist, das wunderbar funktioniert und uns wahrscheinlich gepasst h\u00e4tte...<\/p>\n<p>Wenn wir 10.000 Shards haben, k\u00f6nnen wir keine 10.000 Komponenten \u00fcbermitteln, selbst wenn wir komprimieren oder etwas anderes einfallen lassen \u2013 die Nuttungsrate wird immer viel geringer sein als das Volumen des gesamten Vektors. Daher, mit schwerem Herzen, haben wir darauf verzichtet und sind zu einer anderen L\u00f6sung \u00fcbergegangen.<\/p>\n<h3>Spanner TrueTime. Atomuhren<\/h3>\n<p>\nIch habe gesagt, dass es um den \"Spanner\" geht. Das ist ein cooles Ding, direkt aus dem 21. Jahrhundert: Atomuhren, GPS-Synchronisation.<\/p>\n<p>Was ist die Idee? Der \"Spanner\" ist ein Google-System, das k\u00fcrzlich sogar f\u00fcr die Leute verf\u00fcgbar wurde (sie haben SQL hinzugef\u00fcgt). Jede Transaktion hat dort einen bestimmten Zeitstempel. Da die Zeit synchronisiert ist*, kann jedem Ereignis eine bestimmte Zeit zugewiesen werden \u2013 Atomuhren haben eine Wartezeit, nach der garantiert \"ein anderes Zeitgeschehen\" eintritt.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/707b5998fbb500d201aafffccc666f0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSomit wird durch einfaches Eintragen in die Datenbank und Warten einer gewissen Zeit automatisch die Serialisierbarkeit des Ereignisses garantiert. Sie haben das st\u00e4rkste Konsistenzmodell, das man sich grunds\u00e4tzlich vorstellen kann \u2013 es ist externe Konsistenz.<\/p>\n<p>* Das ist das Hauptproblem der Lamport-Uhren \u2013 sie sind in verteilten Systemen niemals synchron. Sie k\u00f6nnen auseinanderdriften, selbst bei vorhandener NTP funktionieren sie nicht sehr gut. Der \"Spanner\" verf\u00fcgt \u00fcber Atomuhren und Synchronisation, anscheinend auf Mikrosekunden genau.<\/p>\n<p>Warum haben wir uns nicht daf\u00fcr entschieden? Wir gehen nicht davon aus, dass unsere Nutzer \u00fcber eingebaute Atomuhren verf\u00fcgen. Wenn sie eingebaut in jedes Laptop verf\u00fcgbar sind, wird es eine super coole GPS-Synchronisation geben \u2013 dann ja... Aber bis jetzt ist das Beste, was m\u00f6glich ist \u2013 Amazon, Basisstationen \u2013 f\u00fcr Enthusiasten... Deshalb haben wir andere Uhren verwendet.<\/p>\n<h3>Hybride Uhren (Hybrid Clock)<\/h3>\n<p>\nDas ist praktisch das, was in MongoDB tickt, um kausale Konsistenz sicherzustellen. Hybrid sind sie worin? Ein Hybrid ist ein Skalarwert, der aus zwei Komponenten besteht:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/dab03a87d9f6ee2e716f75baff1736bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Die erste ist die Unix-Zeit (die Anzahl der Sekunden seit \"Beginn der Computerwelt\").<\/li>\n<li>Die zweite ist ein gewisser Inkrement, ebenfalls ein 32-Bit unsigned int.<\/li>\n<\/ul>\n<p>\nDas ist im Wesentlichen alles. Es gibt einen Ansatz: Der Teil, der f\u00fcr die Zeit verantwortlich ist, wird st\u00e4ndig mit den Uhren synchronisiert; jedes Mal, wenn ein Update erfolgt, synchronisiert sich dieser Teil mit den Uhren und es stellt sich heraus, dass die Zeit immer mehr oder weniger korrekt ist, w\u00e4hrend der Inkrement es erm\u00f6glicht, Veranstaltungen zu unterscheiden, die im selben Moment stattfinden.<\/p>\n<p>Warum ist das wichtig f\u00fcr MongoDB? Weil es erm\u00f6glicht, bestimmte Backups und Wiederherstellungen zu einem bestimmten Zeitpunkt durchzuf\u00fchren, das hei\u00dft, die Ereignisse werden zeitlich indiziert. Das ist wichtig, wenn bestimmte Ereignisse ben\u00f6tigt werden; f\u00fcr eine Datenbank sind Ereignisse die \u00c4nderungen in der Datenbank, die in bestimmten Zeitr\u00e4umen stattgefunden haben.<\/p>\n<p>Den wichtigsten Grund werde ich nur Ihnen sagen (bitte, erz\u00e4hlen Sie es niemandem)! Wir haben das so gemacht, weil so die geordneten, indizierten Daten im MongoDB OpLog aussehen. OpLog ist eine Datenstruktur, die alle \u00c4nderungen in der Datenbank enth\u00e4lt: Sie gelangen zun\u00e4chst in das OpLog und werden dann erst auf den Storage angewendet, wenn es sich um eine replizierte Datensatz oder Shard handelt.<\/p>\n<p>Das war der Hauptgrund. Es gibt jedoch auch praktische Anforderungen an die Entwicklung der Datenbank, das bedeutet, dass es einfach sein muss - wenig Code, so wenige defekte Elemente wie m\u00f6glich, die neu geschrieben und getestet werden m\u00fcssen. Dass unsere OpLogs mit hybriden Uhren indiziert waren, hat stark geholfen und die richtige Wahl erm\u00f6glicht. Das hat sich tats\u00e4chlich bew\u00e4hrt und irgendwie zauberhaft beim ersten Prototypen funktioniert. Es war wirklich gro\u00dfartig!<\/p>\n<h3>Uhrensynchronisation<\/h3>\n<p>\nEs gibt mehrere synchronisationsmethoden, die in der wissenschaftlichen literatur beschrieben sind. Ich spreche von synchronisation, wenn wir zwei verschiedene shards haben. Wenn es nur einen replika-satz gibt, ist keine synchronisation notwendig: das ist \u00absingle-master\u00bb; wir haben ein OpLog, in das alle \u00e4nderungen eingehen \u2013 in diesem fall sind die gesamten eintr\u00e4ge bereits sequenziell im \u00abOpLog\u00bb geordnet. Aber wenn wir zwei unterschiedliche shards haben, ist die synchronisation der zeit wichtig. Hier haben vektoruhren mehr geholfen! Aber die haben wir nicht.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/7d3306747490ac044b7f8130defea0c9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie zweite m\u00f6glichkeit sind die \u00abHerzschl\u00e4ge\u00bb (Heartbeats). Man kann einige signale austauschen, die in regelm\u00e4\u00dfigen abst\u00e4nden gesendet werden. Aber die \u00abHerzschl\u00e4ge\u00bb sind zu langsam, wir k\u00f6nnen die latenz unseren kunden nicht bieten.<\/p>\n<p>Echte zeit \u2013 das ist nat\u00fcrlich eine gro\u00dfartige sache. Aber wiederum, das ist wahrscheinlich die zukunft\u2026 Obwohl man im \u00abAtlas\u00bb bereits arbeiten kann, gibt es schon schnelle \u00abamazonische\u00bb zeitsynchronisatoren. Aber das wird nicht f\u00fcr alle verf\u00fcgbar sein.<\/p>\n<p>Gossiping ist, wenn alle nachrichten eine zeitangabe enthalten. Das ist ungef\u00e4hr das, was wir verwenden. Jede nachricht zwischen n\u00fctzen, treibern, routen und datenknoten \u2013 alles f\u00fcr \u00abMongoDB\u00bb \u2013 sind irgendwelche elemente, komponenten einer datenbank, die uhren besitzen, die ticken. \u00dcberall haben sie den wert der hybriden zeit, der \u00fcbertragen wird. 64 bit? Das ist m\u00f6glich, das l\u00e4sst sich umsetzen.<\/p>\n<h3>Wie funktioniert das alles zusammen?<\/h3>\n<p>\nHier betrachte ich ein replika-set, um es etwas einfacher zu halten. Es gibt einen Primary und einen Secondary. Der Secondary f\u00fchrt die replikation durch und ist nicht immer vollst\u00e4ndig mit dem Primary synchronisiert.<\/p>\n<p>Es erfolgt ein einf\u00fcgen (insert) im \u00abPrimary\u00bb mit einem bestimmten zeitwert. Dieses insert erh\u00f6ht den internen z\u00e4hler um 11, wenn das maximum erreicht ist. Oder es wird die zeiten \u00fcberpr\u00fcft und synchronisiert sich nach den uhren, wenn die zeiten h\u00f6her sind. Dies erm\u00f6glicht eine zeitliche ordnung.<\/p>\n<p>Nachdem er den eintrag vorgenommen hat, tritt ein wichtiger moment ein. Die uhren in \u00abMongoDB\u00bb werden nur dann inkrementiert, wenn ein eintrag im \u00abOpLog\u00bb erfolgt. Das ist das ereignis, das den zustand des systems \u00e4ndert. In allen klassischen artikeln wird ein ereignis als das eintrudeln einer nachricht in einem knoten betrachtet: eine nachricht ist angekommen \u2013 das bedeutet, das system hat seinen zustand ge\u00e4ndert.<\/p>\n<p>Das h\u00e4ngt damit zusammen, dass man bei der Forschung nicht genau verstehen kann, wie diese Nachricht interpretiert wird. Wir wissen sicher, dass, wenn sie nicht im \"Oplog\" erfasst ist, sie \u00fcberhaupt nicht interpretiert wird, und die Systemzustands\u00e4nderung ist nur der Eintrag im \"Oplog\". Das vereinfacht uns alles: sowohl das Modell als auch die M\u00f6glichkeit, innerhalb eines Replikatsatzes zu ordnen, sowie viele andere n\u00fctzliche Dinge.<\/p>\n<p>Es wird der Wert zur\u00fcckgegeben, der bereits im \"Oplog\" gespeichert ist \u2013 wir wissen, dass dieser Wert im \"Oplog\" bereits vorhanden ist, und seine Zeit ist 12. Angenommen, jetzt beginnt das Lesen von einem anderen Knoten (Secondary), und er \u00fcbertr\u00e4gt bereits afterClusterTime in der Nachricht selbst. Er sagt: \"Ich ben\u00f6tige alles, was mindestens nach 12 oder w\u00e4hrend der zw\u00f6lf passiert ist\" (siehe Bild oben).<\/p>\n<p>Das nennt man Causal a consistent (CAT). Es gibt ein solches Konzept in der Theorie, dass dies ein gewisser Zeitabschnitt ist, der f\u00fcr sich selbst konsistent ist. In diesem Fall kann man sagen, dass dies der Zustand des Systems ist, der im Moment 12 beobachtet wurde.<\/p>\n<p>Hier ist momentan noch nichts, weil es quasi die Situation simuliert, in der der Secondary die Daten vom Primary replizieren muss. Er wartet... Und hier kommen die Daten \u2013 er gibt diese Werte zur\u00fcck.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/54d9de3e2696c1e5d19f4da206be090b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSo funktioniert es ungef\u00e4hr. Fast.<\/p>\n<p>Was bedeutet \"fast\"? Angenommen, es gibt eine Person, die gelesen und verstanden hat, wie das alles funktioniert. Sie hat verstanden, dass jedes Mal, wenn ClusterTime auftritt, die internen logischen Uhren aktualisiert werden, und dann erh\u00f6ht der n\u00e4chste Eintrag um eins. Diese Funktion nimmt 20 Zeilen ein. Angenommen, diese Person \u00fcbertr\u00e4gt die maximal gro\u00dfe 64-Bit-Zahl minus eins.<\/p>\n<p>Warum \"minus eins\"? Weil die internen Uhren in diesen Wert eingesetzt werden (offensichtlich ist das die gr\u00f6\u00dfte m\u00f6gliche und gr\u00f6\u00dfer als die aktuelle Zeit), dann erfolgt der Eintrag im \"Oplog\", und die Uhren werden erneut um eins inkrementiert \u2013 und dann wird bereits der maximale Wert erreicht (da sind einfach alle Einsen, weiter geht es nicht, unsaint int's).<\/p>\n<p>Es ist klar, dass das System danach absolut f\u00fcr nichts verf\u00fcgbar wird. Man kann es nur entladen, reinigen \u2013 viel Handarbeit. Vollst\u00e4ndige Verf\u00fcgbarkeit:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/634b25fe0ef1e0af39181cd59c7b522f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWenn sich das irgendwo anders repliziert, f\u00e4llt der gesamte Cluster aus. Eine absolut inakzeptable Situation, die jeder sehr schnell und einfach organisieren kann! Daher haben wir diesen Punkt als einen der wichtigsten angesehen. Wie kann man das verhindern?<\/p>\n<h3>Unser Weg ist es, clusterTime zu unterschreiben.<\/h3>\n<p>\nSo wird es in der Nachricht \u00fcbermittelt (vor dem blauen Text). Aber wir haben auch begonnen, eine Signatur zu generieren (blauer Text):<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/c16e985f9610e01a61293e0d6dde459b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie Signatur wird mit einem Schl\u00fcssel generiert, der innerhalb der Datenbank im gesch\u00fctzten Bereich gespeichert ist; sie wird selbst generiert und aktualisiert (die Benutzer sehen davon nichts). Ein Hash wird generiert, und jede Nachricht wird beim Erstellen signiert und beim Empfang validiert.<br \/>\nWahrscheinlich fragen sich die Leute: \u201eWie sehr verlangsamt das alles?\u201c Ich habe gesagt, dass es schnell funktionieren sollte, insbesondere ohne diese Funktion.<\/p>\n<p>Was bedeutet es in diesem Fall, Causal consistency zu nutzen? Es zeigt den afterClusterTime-Parameter an. Andernfalls werden Werte in jedem Fall \u00fcbertragen. Gossiping funktioniert seit Version 3.6 immer.<\/p>\n<p>Wenn wir eine st\u00e4ndige Generierung von Signaturen beibehalten, wird das die Systeme selbst ohne diese Funktion verlangsamen, was unseren Ans\u00e4tzen und Anforderungen nicht entspricht. Was haben wir also gemacht?<\/p>\n<h3>Mach das schnell!<\/h3>\n<p>\nEs ist eine ziemlich einfache Sache, aber der Trick ist interessant \u2013 ich teile es, vielleicht interessiert es jemanden.<br \/>\nWir haben einen Hash, in dem signierte Daten gespeichert sind. Alle Daten gehen durch den Cache. Der Cache signiert nicht spezifisch die Zeit, sondern einen Bereich. Wenn ein bestimmter Wert eintrifft, generieren wir einen Bereich, maskieren die letzten 16 Bits, und diesen Wert signieren wir:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/f4810456f08ba1cc69730ac0079d4206.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDurch den Erhalt einer solchen Signatur beschleunigen wir das System (theoretisch) um 65.000 Mal. Es funktioniert hervorragend: Als wir Experimente durchf\u00fchrten, wurde die Zeit f\u00fcr unser sequenzielles Update tats\u00e4chlich um 10.000 Mal verk\u00fcrzt. Es ist klar, dass das nicht funktioniert, wenn sie durcheinander kommen. Aber in den meisten praktischen F\u00e4llen funktioniert es. Die Kombination aus Range-Signatur und Signatur hat das Sicherheitsproblem gel\u00f6st.<\/p>\n<h3>Was haben wir gelernt?<\/h3>\n<p>\nDie Lektionen, die wir daraus gezogen haben:<\/p>\n<ul>\n<li>Man muss Materialien, Geschichten und Artikel lesen, weil es viel Interessantes gibt. Wenn wir an einer Funktion arbeiten (besonders jetzt, wo wir Transaktionen gemacht haben usw.), sollte man lesen und sich einarbeiten. Das kostet Zeit, ist aber sehr n\u00fctzlich, da man versteht, wo wir stehen. Wir haben nichts wirklich Neues erfunden \u2013 wir haben einfach Zutaten verwendet.\n<p>Generell gibt es einen bestimmten Unterschied im Denken, wenn eine akademische Konferenz stattfindet (zum Beispiel \"Sigmon\") \u2013 dort konzentriert sich jeder auf neue Ideen. Was ist die Neuheit unseres Algorithmus? Hier gibt es nicht viel Neuheit. Die Neuheit besteht vielmehr darin, wie wir bestehende Ans\u00e4tze miteinander gemischt haben. Deshalb ist es wichtig, die Klassiker zu lesen, beginnend mit Lamport.<\/li>\n<li>Im Produktionsumfeld gibt es v\u00f6llig andere Anforderungen. Ich bin mir sicher, dass viele von Ihnen es nicht mit \"sph\u00e4rischen\" Datenbanken im abstrakten Vakuum zu tun haben, sondern mit normalen, realen Dingen, die Probleme hinsichtlich Verf\u00fcgbarkeit, Latenz und Fehlertoleranz haben.<\/li>\n<li>Zuletzt mussten wir verschiedene Ideen in Betracht ziehen und mehrere v\u00f6llig unterschiedliche Artikel zu einem Ansatz kombinieren. Die Idee des Signierens stammt zum Beispiel aus einem Artikel, der das Paxos-Protokoll behandelt hat, das f\u00fcr nicht-byzantinische Fehler innerhalb des Autorisierungsprotokolls gedacht ist, f\u00fcr byzantinische \u2013 au\u00dferhalb des Autorisierungsprotokolls... Insgesamt ist das genau das, was wir am Ende getan haben.\n<p>Hier gibt es absolut nichts Neues! Aber sobald wir all das zusammengef\u00fcgt haben... Es ist dasselbe wie zu sagen, dass das Rezept f\u00fcr Salat Olivier nichts Besonderes ist, weil Eier, Mayonnaise und Gurken bereits erfunden wurden... Es ist ungef\u00e4hr die gleiche Geschichte.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/2f9e5cb77079f9a0f7bdf76430c3386e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIch beende damit. Danke!<\/p>\n<h3>Fragen<\/h3>\n<p>\n<b>Frage aus dem Publikum (im Folgenden \u2013 F):<\/b> \u2013 Vielen Dank, Michail, f\u00fcr den Vortrag! Das Thema Zeit ist interessant. Sie verwenden Gossiping. Sie haben gesagt, dass jeder seine eigene Zeit hat, jeder kennt seine lokale Zeit. Ich habe so verstanden, dass wir einen Treiber haben \u2013 es kann viele Kunden mit Treibern geben, ebenso viele Abfrageplaner, auch viele Shards... Was passiert mit dem System, wenn es pl\u00f6tzlich eine Diskrepanz gibt: einer denkt, dass er eine Minute voraus ist, der andere \u2013 eine Minute hinterher? Wo landen wir?<\/p>\n<p><b>MT:<\/b> \u2013 Eine ausgezeichnete Frage! Ich wollte gerade \u00fcber die Shards sprechen. Wenn ich die Frage richtig verstehe, haben wir die Situation, dass es Shard 1 und Shard 2 gibt. Das Lesen erfolgt von diesen beiden Shards \u2013 sie haben unterschiedliche Zeiten, und sie interagieren nicht miteinander, weil die Zeit, die sie kennen, unterschiedlich ist, besonders die Zeit, die in ihren Op-Logs existiert.<br \/>\nAngenommen, Shard 1 hat eine Million Eintr\u00e4ge gemacht, Shard 2 \u2013 \u00fcberhaupt nichts, und die Anfrage kam an beide Shards. Und der erste hat eine afterClusterTime von \u00fcber einer Million. In dieser Situation, wie ich erkl\u00e4rt habe, wird Shard 2 nie antworten.<\/p>\n<p><b>Frage:<\/b> \u2013 Ich wollte wissen, wie sie synchronisiert werden und eine logische Zeit ausw\u00e4hlen?<\/p>\n<p><b>MT:<\/b> \u2013 Die Synchronisierung erfolgt sehr einfach. Wenn Shard eine afterClusterTime erh\u00e4lt und die Zeit im \u201eOp-Log\u201c nicht findet \u2013 initiiert es no approved. Das bedeutet, dass es seine Zeit auf diesen Wert anhebt. Das bedeutet, dass es keine Ereignisse gibt, die auf diese Anfrage reagieren. Es erzeugt dieses Ereignis k\u00fcnstlich und ist somit kausal konsistent.<\/p>\n<p><b>Frage:<\/b> \u2013 Und was, wenn danach noch irgendwelche Ereignisse eintreffen, die im Netzwerk irgendwo verloren gegangen sind?<\/p>\n<p><b>MT:<\/b> \u2013 Shard ist so konstruiert, dass sie nicht mehr eintreffen, da es einen Single Master gibt. Wenn er bereits geschrieben hat, dann werden sie nicht mehr eintreffen, sondern danach. Es kann nicht passieren, dass irgendwo etwas stecken bleibt, dann macht er no write und diese Ereignisse kommen an \u2013 und die kausale Konsistenz wird verletzt. Wenn er no write macht, m\u00fcssen sie alle danach kommen (er wird auf sie warten).<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/dbbc7c5c653f0c9fa449cceb88ed62ef.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Frage:<\/b> \u2013 Ich habe einige Fragen zu den Warteschlangen. Kausale Konsistenz setzt voraus, dass es eine bestimmte Warteschlange von Aktionen gibt, die ausgef\u00fchrt werden m\u00fcssen. Was passiert, wenn ein Paket verloren geht? Es kommt 10., 11. ... aber der 12. geht verloren, w\u00e4hrend alle anderen warten, dass es ausgef\u00fchrt wird. Und pl\u00f6tzlich stirbt die Maschine, wir k\u00f6nnen nichts tun. Gibt es eine maximale L\u00e4nge der Warteschlange, die sich anh\u00e4uft, bevor sie ausgef\u00fchrt wird? Was f\u00fcr einen fatalen Fehler gibt es bei Verlust eines bestimmten Zustands? Zumal wir aufzeichnen, dass es einen vorherigen Zustand gibt, m\u00fcssen wir doch irgendwie darauf basieren? Aber wir haben uns nicht darauf gest\u00fctzt!<\/p>\n<p><b>MT:<\/b> \u2013 Auch eine ausgezeichnete Frage! Was tun wir? In MongoDB gibt es das Konzept von Quorum-Schreibvorg\u00e4ngen und Quorum-Lesungen. In welchen F\u00e4llen kann eine Nachricht verloren gehen? Wenn der Schreibvorgang ohne Quorum ist oder wenn die Lesevorg\u00e4nge nicht quorum sind (da kann auch etwas M\u00fcll anhaften).<br \/>\nBez\u00fcglich der kausalen Konsistenz haben wir eine umfangreiche experimentelle \u00dcberpr\u00fcfung durchgef\u00fchrt, deren Ergebnis war, dass, wenn Aufzeichnungen und Lesevorg\u00e4nge nicht quorum-basiert sind, Verst\u00f6\u00dfe gegen die kausale Konsistenz auftreten. Genau das, was Sie sagen!<\/p>\n<p>Unser Rat: Verwenden Sie mindestens quorum-basiertes Lesen bei der Nutzung der kausalen Konsistenz. In diesem Fall wird nichts verloren gehen, selbst wenn die quorum-basierte Aufzeichnung ausf\u00e4llt\u2026 Das ist eine orthogonale Situation: Wenn der Benutzer nicht m\u00f6chte, dass Daten verloren gehen, muss er eine quorum-basierte Aufzeichnung verwenden. Kausale Konsistenz bietet keine Garantie f\u00fcr die Haltbarkeit. Die Garantie f\u00fcr die Haltbarkeit bietet die Replikation und die mit der Replikation verbundene Technik.<\/p>\n<p><b>Frage:<\/b> \u2013 Wenn wir eine Instanz erstellen, die bei uns das Sharding durchf\u00fchrt (nicht master, sondern slave), st\u00fctzt sie sich auf die Unix-Zeit ihrer eigenen Maschine oder auf die Zeit des \"Masters\"; synchronisiert sie sich beim ersten Mal oder regelm\u00e4\u00dfig?<\/p>\n<p><b>MT:<\/b> \u2013 Jetzt werde ich das kl\u00e4ren. Ein Shard (d. h. eine horizontale Partition) hat immer einen Prim\u00e4rschl\u00fcssel. In einem Shard kann es einen \"Master\" geben und Replikate. Aber der Shard unterst\u00fctzt immer die Speicherung, weil er ein gewisses Dom\u00e4nenmodell unterst\u00fctzen muss (im Shard befindet sich der Prim\u00e4rschl\u00fcssel).<\/p>\n<p><b>Frage:<\/b> \u2013 Das hei\u00dft, alles h\u00e4ngt rein vom \"Master\" ab? Wird immer die \"Master\"-Zeit verwendet?<\/p>\n<p><b>MT:<\/b> \u2013 Ja. Man kann bildlich sagen: Die Uhren ticken, wenn die Aufnahme im \"Master\", im \"OpLog\", erfolgt.<\/p>\n<p><b>Frage:<\/b> \u2013 Wir haben einen Kunden, der sich verbindet, und er muss \u00fcber die Zeit nichts wissen?<\/p>\n<p><b>MT:<\/b> \u2013 Er muss gar nichts wissen! Wenn wir dar\u00fcber sprechen, wie das beim Kunden funktioniert: Der Kunde muss, wenn er die kausale Konsistenz nutzen m\u00f6chte, eine Sitzung er\u00f6ffnen. In dieser Sitzung sind alles enthalten: Transaktionen in der Sitzung sowie Rechte abrufen\u2026 Eine Sitzung ist eine Anordnung der logischen Ereignisse, die mit dem Kunden passieren.<\/p>\n<p>Wenn er diese Sitzung er\u00f6ffnet und dort angibt, dass er kausale Konsistenz m\u00f6chte (sofern die Sitzung standardm\u00e4\u00dfig kausale Konsistenz unterst\u00fctzt), funktioniert alles automatisch. Der Treiber speichert diese Zeit und erh\u00f6ht sie, wenn er eine neue Nachricht erh\u00e4lt. Er merkt sich, welche Antwort der vorherige Server zur\u00fcckgegeben hat, der die Daten geliefert hat. Die n\u00e4chste Anfrage wird afterCluster enthalten (\"Zeit gr\u00f6\u00dfer als diese\").<\/p>\n<p>Der Kunde muss wirklich \u00fcberhaupt nichts wissen! Das ist f\u00fcr ihn v\u00f6llig intransparent. Wenn die Leute diese Funktionen nutzen, was kann man damit erreichen? Erstens kann man sicher auf Secondaries lesen: Man kann auf das Primary schreiben und von geografisch replizierten Secondaries lesen und sich sicher sein, dass es funktioniert. Dabei k\u00f6nnen die Sessions, die auf dem Primary aufgezeichnet wurden, sogar an das Secondary \u00fcbertragen werden, d. h. man kann nicht nur eine Session, sondern mehrere verwenden.<\/p>\n<p><b>Frage:<\/b> \u2013 Das Thema der Eventual Consistency ist eng verbunden mit einem neuen Bereich der Informatik \u2013 den CRDT-Datentypen (Conflict-free Replicated Data Types). Haben Sie \u00fcber die Integration dieser Datentypen in die Datenbank nachgedacht und was k\u00f6nnen Sie dazu sagen?<\/p>\n<p><b>MT:<\/b> \u2013 Gute Frage! CRDT macht bei Konflikten beim Schreiben Sinn: in MongoDB \u2013 ein Single Master.<\/p>\n<p><b>Frage:<\/b> \u2013 Ich habe eine Frage von den DevOps. In der realen Welt gibt es solche heiklen Situationen, in denen ein byzantinischer Fehler auftritt und b\u00f6se Menschen innerhalb des gesch\u00fctzten Bereichs anfangen, in das Protokoll einzugreifen und auf spezielle Weise manipulierte Pakete zu senden?<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" src=\"\/wp-content\/uploads\/2020\/02\/99a521d04b416e6978aa68ce7c4a4c46.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>MT:<\/b> \u2013 B\u00f6se Menschen innerhalb des Bereichs sind wie ein Trojanisches Pferd! B\u00f6se Menschen innerhalb des Bereichs k\u00f6nnen viele schlechte Dinge tun.<\/p>\n<p><b>Frage:<\/b> \u2013 Es ist offensichtlich, dass es nicht richtig ist, im Server ein Loch zu lassen, durch das man einen Zoo von Elefanten schieben und den gesamten Cluster f\u00fcr immer abst\u00fcrzen lassen kann\u2026 Das w\u00fcrde Zeit f\u00fcr eine manuelle Wiederherstellung erfordern\u2026 Das ist, milde gesagt, nicht in Ordnung. Auf der anderen Seite ist es interessant, dass es im wirklichen Leben in der Praxis Situationen gibt, in denen tats\u00e4chlich solche internen Angriffe vorkommen?<\/p>\n<p><b>MT:<\/b> \u2013 Da ich in der realen Welt nicht oft mit Sicherheitsverletzungen konfrontiert bin, kann ich nicht sagen \u2013 vielleicht kommen sie vor. Aber wenn wir \u00fcber die Entwicklerphilosophie sprechen, denken wir so: Wir haben einen Perimeter, der die Leute, die f\u00fcr die Sicherheit zust\u00e4ndig sind, absichert \u2013 das ist das Schloss, die Mauer; und innerhalb des Bereichs kann man tun, was man will. Es ist klar, dass es Benutzer gibt, die nur schauen k\u00f6nnen, und solche, die das Verzeichnis l\u00f6schen k\u00f6nnen.<\/p>\n<p>Je nach Rechten kann der Schaden, den Benutzer anrichten k\u00f6nnen, von einer Maus bis zu einem Elefanten reichen. Klar ist, dass ein Benutzer mit vollen Rechten alles tun kann. Ein Benutzer mit eingeschr\u00e4nkten Rechten kann erheblich weniger Schaden anrichten. Insbesondere kann er das System nicht zerst\u00f6ren.<\/p>\n<p><b>Frage:<\/b> \u2013 Im gesch\u00fctzten Bereich hat jemand unerwartete Protokolle f\u00fcr den Server erstellt, um den Server zu deaktivieren, und falls alles gut geht, sogar den gesamten Cluster... Kann es wirklich so \"gut\" sein?<\/p>\n<p><b>MT:<\/b> \u2013 Ich habe noch nie von solchen Dingen geh\u00f6rt. Dass man einen Server auf diese Weise lahmlegen kann, ist kein Geheimnis. Intern mit einem Protokoll, w\u00e4hrend man ein autorisierter Benutzer ist, der etwas derartiges in eine Nachricht schreiben kann... Eigentlich ist das nicht m\u00f6glich, weil es trotzdem verifiziert werden muss. Es gibt die M\u00f6glichkeit, diese Authentifizierung f\u00fcr Benutzer, die es nicht wollen, zu deaktivieren \u2013 das sind dann deren Probleme; sie haben, grob gesagt, selbst die Mauern eingerissen und man k\u00f6nnte einen Elefanten hineinstecken, der alles niedertrampelt... Aber insgesamt k\u00f6nnte man in der Rolle eines Technikers kommen und ihn herausziehen!<\/p>\n<p><b>Frage:<\/b> \u2013 Danke f\u00fcr den Bericht. Sergey (\"Yandex\"). In \"Mongo\" gibt es eine Konstante, die die Anzahl der stimmberechtigten Mitglieder im Replica Set auf 7 (sieben) limitiert. Warum ist das eine Konstante? Warum ist das kein Parameter?<\/p>\n<p><b>MT:<\/b> \u2013 Im Replica Set haben wir manchmal bis zu 40 Knoten. Dort gibt es immer eine Mehrheit. Ich wei\u00df nicht, welche Version...<\/p>\n<p><b>Frage:<\/b> \u2013 Im Replica Set kann man auch nicht-stimmberechtigte Mitglieder starten, aber stimmberechtigte maximal 7. Wie geht man in diesem Fall mit einem Ausfall um, wenn unser Replica Set \u00fcber 3 Rechenzentren verteilt ist? Ein Rechenzentrum kann problemlos ausfallen, und auch eine Maschine kann ausfallen.<\/p>\n<p><b>MT:<\/b> \u2013 Das ist schon ein bisschen au\u00dferhalb des Berichts. Das ist eine allgemeine Frage. Vielleicht kann ich dar\u00fcber sp\u00e4ter erz\u00e4hlen.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikhail Tyulenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis\" 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 abspielen\" 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>Ein wenig Werbung \ud83d\ude42<\/h3>\n<p>\nDanke, dass Sie bei uns bleiben. Gefallen Ihnen unsere Artikel? M\u00f6chten Sie mehr interessante Inhalte sehen? Unterst\u00fctzen Sie uns, indem Sie eine Bestellung aufgeben oder uns Freunden empfehlen, <noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/cloudvps\/nl\">Cloud-VPS f\u00fcr Entwickler ab 4,99 $<\/a><\/noindex>, <b>ein einzigartiges \u00c4quivalent zu Einsteigerservern, das wir f\u00fcr Sie entwickelt haben:<\/b> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/347386\/\">Die ganze Wahrheit \u00fcber VPS (KVM) E5-2697 v3 (6 Kerne) 10GB DDR4 480GB SSD 1Gbps ab 19 $ oder wie man einen Server richtig teilt?<\/a><\/noindex> (es sind Optionen mit RAID1 und RAID10 bis zu 24 Kernen und bis zu 40GB DDR4 verf\u00fcgbar).<\/p>\n<p><b>Dell R730xd ist im Equinix Tier IV Rechenzentrum in Amsterdam doppelt so g\u00fcnstig?<\/b> Nur bei uns <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 100 TB ab $199<\/a><\/noindex> in den Niederlanden! <b>Dell R420 \u2014 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB \u2014 ab $99!<\/b><\/b> Lesen Sie, wie <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/329618\/\">man eine Unternehmensinfrastruktur der Klasse C mit Dell R730xd E5-2650 v4-Servern f\u00fcr 9000 Euro im Preis-Leistungs-Verh\u00e4ltnis aufbaut?<\/a><\/noindex><br \/>\n<br \/>Quelle: <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.1.1 - 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\/de\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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\/de\/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++, Michail Tju\u013cenev (MongoDB): Kausale Konsistenz: Von der Theorie zur Praxis | ProHoster","description":"Die n\u00e4chste HighLoad++-Konferenz findet am 6. und 7. April 2020 in St. Petersburg statt. Einzelheiten und Tickets unter dem Link.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","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\/de\/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\/de\/wp-json\/wp\/v2\/posts\/56365","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=56365"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/56365\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=56365"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=56365"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=56365"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}