MongoDB: Lokalisieren Sie den Mongos-Prozess auf Anwendungsservern

12

Ich möchte eine Frage zu einer in diesem Dokument beschriebenen Best Practice stellen:

http://info.mongodb.com/rs/mongodb/images/MongoDB-Performance-Best-Practices.pdf

Verwenden Sie mehrere Abfragerouter. Verwenden Sie mehrere Mongos-Prozesse, die auf mehrere Server verteilt sind. Eine übliche Bereitstellung besteht darin, den Mongos-Prozess auf Anwendungsservern zu lokalisieren, wodurch die lokale Kommunikation zwischen der Anwendung und dem Mongos-Prozess ermöglicht wird. Die entsprechende Anzahl von Mongos-Prozessen hängt von der Art der Anwendung und der Bereitstellung ab.

Nur ein paar Hintergrundinformationen zu unserer Bereitstellung. Wir haben viele Anwendungsserverknoten. Jeder von ihnen führt einen JVM-basierten Prozess mit zustandslosem RESTful WS aus. Wie aus dieser Best Practice hervorgeht, wird auf jedem einzelnen Anwendungsserverknoten ein eigener mongosProzess ausgeführt. Dies bedeutet, dass die Anzahl der JVM-Prozesse immer der Anzahl der mongosProzesse entspricht.

Alle mongosProzesse stellen eine Verbindung zu 3 Konfigurationsservern und mehreren Mongo-Shards her (mit Replikatsätzen in jedem Shard). Obwohl wir eine Sharded-Bereitstellung verwenden, werden unsere Sammlungen nicht wirklich gesplittet. Tatsächlich haben wir eine große Anzahl von Datenbanken, die während ihrer Erstellungszeit auf alle Shards verteilt sind (und dies ist derzeit unser Hauptanwendungsfall für das Sharding).

Da die Best Practice auch vorschlägt, dass "die angemessene Anzahl von Mongos-Prozessen von der Art der Anwendung und Bereitstellung abhängt", begann ich mich zu fragen, ob unsere Verwendung mongostatsächlich angemessen ist oder ob es für uns besser wäre, mehrere dedizierte mongosKnoten zu haben und zu vermieten Unsere App-Server stellen eine Verbindung zu ihnen her, ohne dass mongossie lokal ausgeführt werden.

Was ist Ihre Meinung zum besten Ansatz, um zu entscheiden, wie viele mongosInstanzen in Bezug auf die Anzahl der Anwendungsserverinstanzen oder die Größe des MongoDB-Clusters angemessen sind?

Vor kurzem haben wir angefangen, uns mit der Clusterverwaltung für unsere zustandslosen Webdienste zu befassen, womit ich Tools wie Docker, Apache Mesos und Kubernetes meine. Wenn wir Docker verwenden, wird im Allgemeinen davon abgeraten, mehr als einen Prozess innerhalb eines Containers auszuführen. Angesichts dieser Tatsache wird es sehr schwierig, sicherzustellen, dass sich der Anwendungsserver-Container und der mongosContainer immer auf demselben physischen Knoten befinden und über die gleiche Anzahl von Prozessen verfügen. Ich frage mich daher, ob diese bewährte Methode noch für die soeben beschriebene Cluster-Architektur gilt. Wenn nicht, können Sie bitte vorschlagen, wie mongosProzesse in dieser Architektur besser lokalisiert und bereitgestellt werden können.

Tenshi
quelle

Antworten:

12

Da bereits eine Antwort eingereicht wurde, und zwar eine nützliche und gültige, möchte ich nicht von ihrer eigenen Nützlichkeit ablenken, aber es gibt in der Tat Punkte, die weit über einen kurzen Kommentar hinausgehen. Betrachten Sie also diese "Erweiterung", die hoffentlich gültig ist, aber in erster Linie zusätzlich zu dem, was bereits gesagt wurde.

Die Wahrheit ist, wirklich zu überlegen, "wie Ihre Anwendung die Daten verwendet", und sich auch der Faktoren in einer "Sharded Environment" sowie Ihrer vorgeschlagenen "Container Environment" bewusst zu sein, die sich darauf auswirken.

Der Hintergrundfall

Die allgemeine Annahme der Übungsempfehlung für die gemeinsame Lokalisierung des mongosProzesses zusammen mit der Anwendungsinstanz besteht darin, jeglichen Netzwerk-Overhead zu vermeiden, der erforderlich ist, damit die Anwendung mit diesem mongosProzess kommuniziert . Natürlich ist es auch "empfohlene Praxis", eine Anzahl von mongosInstanzen in der Anwendungsverbindungszeichenfolge anzugeben, falls dieser "nächstgelegene" Knoten aus irgendeinem Grund nicht verfügbar sein sollte, dann könnte ein anderer ausgewählt werden, wenngleich mit dem möglichen Mehraufwand für die Kontaktaufnahme mit a entfernter Knoten.

Der von Ihnen erwähnte "Docker" -Fall scheint etwas willkürlich. Während es wahr ist, dass eines der Hauptziele von Containern (und davor so etwas wie BSD-Jails oder sogar Chroot) im Allgemeinen darin besteht, ein gewisses Maß an "Prozessisolation" zu erreichen, gibt es nichts wirklich Falsches daran, mehrere Prozesse so lange auszuführen, wie Sie Verstehe die Implikationen.

In diesem speziellen Fall mongossoll das Programm "leicht" sein und als "zusätzliche Funktion" für den Anwendungsprozess ausgeführt werden, so dass es so gut wie ein "gepaarter" Teil der Anwendung selbst ist. Docker-Images selbst haben also keinen "initd" -ähnlichen Prozess, aber es ist eigentlich nichts Falsches daran, einen Prozesscontroller wie supervisord (zum Beispiel) als Hauptprozess für den Container auszuführen , über den Sie dann die Prozesssteuerung übernehmen können dieser Behälter auch. Diese Situation von "gepaarten Prozessen" ist ein vernünftiger Fall und es wird häufig verlangt, dass es dafür offizielle Unterlagen gibt .

Wenn Sie diese Art von "gepaartem" Vorgang für die Bereitstellung ausgewählt haben, wird tatsächlich der primäre Punkt der Aufrechterhaltung einer mongosInstanz auf derselben Netzwerkverbindung und tatsächlich der "Serverinstanz" wie der Anwendungsserver selbst angesprochen. Es kann auch in gewisser Weise als ein Fall angesehen werden, in dem der "gesamte Container" ausfallen würde, dann wäre dieser Knoten an sich einfach ungültig. Nicht, dass ich es empfehlen würde, und in der Tat sollten Sie wahrscheinlich immer noch Verbindungen konfigurieren, um nach anderen mongosInstanzen zu suchen, auch wenn diese nur über eine Netzwerkverbindung zugänglich sind, die die Latenz erhöht.

Versionsspezifisch / Verwendungsspezifisch

Nachdem dieser Punkt ausgeführt wurde, wird die andere Überlegung hier auf die ursprüngliche Überlegung zurückgeführt, den mongosProzess zusammen mit der Anwendung zu Zwecken der Netzwerklatenz zu lokalisieren . In MongoDB-Versionen vor 2.6 und insbesondere in Bezug auf Vorgänge wie das Aggregationsframework gab es dann den Fall, dass viel mehr Netzwerkverkehr und anschließend nach der Verarbeitung durch den mongosProzess für den Umgang mit Daten aus verschiedenen Shards ausgeführt wurde . Das ist jetzt nicht mehr so ​​sehr der Fall, da ein Großteil der Verarbeitungsarbeit nun auf diesen Shards selbst ausgeführt werden kann, bevor zum "Router" "destilliert" wird.

Der andere Fall ist das Nutzungsmuster Ihrer Anwendung selbst in Bezug auf das Sharding. Dies bedeutet, ob die primäre Arbeitslast darin besteht, die Schreibvorgänge auf mehrere Shards zu verteilen, oder ob es sich tatsächlich um einen "Scatter-Gather" -Ansatz bei der Konsolidierung von Leseanforderungen handelt. In diesen Szenarien

Testen, testen und dann erneut testen

Der letzte Punkt hier ist also wirklich selbsterklärend und beruht auf dem Grundkonsens jeder vernünftigen Antwort auf Ihre Frage. Dies ist keine neue Sache für MongoDB oder eine andere Speicherlösung, aber Ihre tatsächliche Implementierungsumgebung muss auf "Verwendungsmuster" getestet werden, die der tatsächlichen Realität genau so nahe kommen wie "Komponententests" der erwarteten Funktionalität von Kernkomponenten oder Gesamtergebnis muss getestet werden.

Es gibt wirklich keine "definitive" Aussage, die "auf diese Weise konfigurieren" oder "auf diese Weise verwenden" besagt, die tatsächlich Sinn macht, außer zu testen, was für die Leistung und Zuverlässigkeit Ihrer Anwendung erwartungsgemäß "am besten funktioniert".

Natürlich wird der "beste Fall" immer darin bestehen, die mongosInstanzen nicht mit Anfragen von "vielen" Anwendungsserverquellen "zu überfüllen" . Aber dann, um ihnen eine natürliche "Parität" zu ermöglichen, die durch die verfügbaren Ressourcen-Workloads verteilt werden kann, um "mindestens" einen "Pool von Ressourcen" zu haben, der ausgewählt werden kann, und zwar idealerweise in vielen Fällen, aber um die Notwendigkeit zu vermeiden, einen zusätzlichen zu induzieren msgstr "Netztransportaufwand".

Dies ist das Ziel, aber im Idealfall können Sie die verschiedenen wahrgenommenen Konfigurationen "im Labor testen", um eine "am besten geeignete" Lösung für Ihre eventuelle Bereitstellungslösung zu finden.

Ich würde auch die "kostenlosen" (wie in Bier) Kurse empfehlen, die wie bereits erwähnt angeboten werden, unabhängig von Ihrem Kenntnisstand. Ich finde, dass verschiedene Kursmaterialquellen oft "versteckte Schätze" bieten, um mehr Einblick in Dinge zu geben, die Sie vielleicht nicht in Betracht gezogen oder auf andere Weise übersehen haben. Die erwähnte M102-Klasse wurde von Adam Commerford konstruiert und durchgeführt, von dem ich bescheinigen kann, dass er über ein hohes Maß an Wissen in Bezug auf umfangreiche Bereitstellungen von MongoDB und anderen Datenarchitekturen verfügt. Es lohnt sich, zumindest einen neuen Blick auf das zu werfen, von dem Sie vielleicht denken, dass Sie es bereits wissen.

Neil Lunn
quelle
5

Da die Best Practice auch vorschlägt, dass "die angemessene Anzahl von Mongos-Prozessen von der Art der Anwendung und Bereitstellung abhängt", begann ich mich zu fragen, ob unsere Verwendung von Mongos tatsächlich angemessen ist

Ich denke, das ist eine Frage, die letztendlich nur Sie beantworten können, wie in der Dokumentation erwähnt.

Eine der empfohlenen Strategien besteht darin, mongosauf jedem Anwendungsknoten einen Dienst und möglicherweise sogar auf einem zusätzlichen dedizierten Knoten einen Dienst für zusätzliche Verfügbarkeit bereitzustellen. Da Sie dies derzeit haben, sehe ich nichts falsch mit Ihrer aktuellen Bereitstellung. Wenn sich an Ihrer Architektur nichts ändert, liegen Sie derzeit im Rahmen der Best Practices. Jedoch...

Wenn wir Docker verwenden, wird im Allgemeinen davon abgeraten, mehr als einen Prozess innerhalb eines Containers auszuführen.

Da der mongosProzess nicht sehr ressourcenintensiv ist, können Sie auch eine Instanz davon auf jedem Ihrer Shards platzieren und jeden mongodKnoten auch als mongosKnoten fungieren lassen . Dies ist möglicherweise sinnvoller, wenn Sie die Anwendungsserverarchitektur etwas komplexer gestalten.

Ich persönlich kenne diese Produkte nicht so gut, aber ich erkundige mich seitdem auch beim Hersteller nach deren Empfehlungen mongos möglicherweise weniger intensiv sind als die meisten anderen Prozesse, die Sie nebeneinander ausführen können.

Schließlich könnten Sie immer dedizierte Knoten für den mongosProzess einbinden, abhängig von Ihrer Größe, Ihren Ressourcen usw., was ebenfalls gut zu den Best Practices passt. Der eigentliche Nachteil dabei ist, dass Sie es gut machen, solange Sie irgendwo eine Reihe von mongosProzessen haben .

Wie viele davon tatsächlich vorhanden sind, hängt jedoch von der Größe Ihrer Bereitstellung und den SLA-Anforderungen ab. Wenn Sie die Shards verwenden, haben Sie mehr als genug, aber wenn Sie dedizierte Knoten verwenden, würde ich versuchen, die Anzahl der Anwendungsknoten so genau wie möglich anzupassen.

Sie können sich dieses Video aus dem MongoDB M102-Onlinekurs ansehen, der diese Themen behandelt, und versuchen, sich das nächste Mal in der Sitzung für den M102 für DBAs- Kurs anzumelden (kostenlos, online).

LowlyDBA
quelle
Danke für die tolle Antwort! "Aber wenn Sie dedizierte Knoten verwenden möchten, würde ich versuchen, die Anzahl der Anwendungsknoten so genau wie möglich anzupassen." Was ist die Begründung für diese Aussage?
Tenshi
Meine Meinung: In den meisten Fällen gibt es weniger Anwendungsknoten als Shards. Da empfohlen wird, Anwendungsknoten für zu verwenden mongos, sollte eine Übereinstimmung mit der gleichen Anzahl dedizierter Knoten mindestens genügend mongosInstanzen liefern . Es ist keine exakte Wissenschaft und hängt von Ihren Bedürfnissen ab, aber so würde ich eine Produktionsumgebung bevorzugen.
LowlyDBA