Mongodb Geschwindigkeit nach dem Sharding langsamer eingeben

8

Ich habe einen Mongodb-Cluster, der ein primäres Replikat und ein sekundäres Replikat enthält, die zusammen als Replikationssatz ausgeführt werden. Aber mit dem Verkehr wächst, beschloss ich, eine Sharding durchzuführen, um mehr Schreibgeschwindigkeit zu bekommen.

Ich habe auf der Grundlage dieses Tutorials einen Hash-Hashing für die Spalte "_id" durchgeführt. a> und teile die Daten in zwei Shards. Ich führte dann einige Benchmark-Tests durch und fand heraus, dass der Cluster unter bestimmten Umständen sogar langsamer ist als der Nicht-Cluster.

Hier ist das Testergebnis.

  1. Maximaler Durchsatz-Test: Verwenden Sie zehn Maschinen, um "mongoimport" gleichzeitig auszuführen, um Daten in die Ziel-DB zu laden, um die maximale Schreibgeschwindigkeit von db zu testen.

    Ergebnis:

    Der Sharded Cluster kann 39500 Dokumente / s einfügen.

    Der ungestrichene Cluster kann 27400 Dokumente / s einfügen.

  2. Einzelner Mongoimport-Test: Verwenden Sie nur einen Computer, um "mongoimport" auszuführen, um Daten in die Ziel-db zu laden.

    Ergebnis:

    Der Sharded Cluster kann 14285 Dokumente / s einfügen.

    Der unbeschichtete Cluster kann 14085 Dokumente / s einfügen.

  3. Laden einzelner Daten mit dem mongodb java-Treiber: Verwenden Sie nur eine Instanz, um Daten in die Ziel-db zu laden, indem Sie die API des mongodb java-Treibers aufrufen.

    Ergebnis:

    Der sharded Cluster kann 4630 Dokumente / s einfügen.

    Der nicht gehärtete Cluster kann 17544 Dokumente / s einfügen.

Das Ergebnis des ersten Tests ist absolut sinnvoll. Du hast die db in einen 2-shard Cluster gepackt und den Durchsatz um 50% erhöht, alles ist perfekt, hurra!

Der zweite Test macht etwas Sinn. Nun, der Durchsatz ist ungefähr der gleiche, aber vielleicht liegt der Flaschenhals auf der Seite des Datenladers, nachdem wir alle Daten mit nur einer Instanz geladen haben.

Aber der dritte Test nervt mich wirklich. Es macht keinen Sinn, dass der Sharked Cluster so viel langsamer sein kann als der Unsharded Cluster. Die ungeschwächte db hingegen hat eine erstaunliche Geschwindigkeit, sogar schneller als das Laden von Daten mit Mongoimport.

Der Java-Code, der zum Laden von Daten verwendet wurde, wird unten eingefügt. Ich kann das wirklich nicht herausfinden und danke im Voraus für alle Antworten.

%Vor%     
Mohan Yang 01.03.2017, 02:32
quelle

2 Antworten

3

Hier ist der mögliche Schuldige collection.bulkWrite(list);

Im Falle von Massenschreibvorgängen muss mongos Ihre Stapel in kleinere Stapel aufteilen, die zu jedem Splitter gehören.

Da Sie in Ihrem Stapel keine Angaben zur Reihenfolge der Anzeigen von Dokumenten gemacht haben, muss MongoDB die Anforderung erfüllen, dass die Einfügungen in der angegebenen Reihenfolge ausgeführt werden. Dies hat zur Folge, dass aufeinanderfolgende Inserts genau dann stapelbar sind, wenn sie dem gleichen Shard entsprechen.

  

mongos behält die ursprüngliche Dokumentreihenfolge bei, daher können nur die aufeinanderfolgenden Einfügungen, die zu demselben Shard gehören, zusammen gruppiert werden

Für z. Betrachten Sie den Fall, in dem "k" der Shard-Schlüssel ist. Es gibt zwei Shards, die Bereichen entsprechen

%Vor%

Nun nehmen wir an, dass wir die folgenden Dokumente im Batch einfügen:

%Vor%

Doc1 - & gt; Shard1, Doc2 - & gt; Shard2, Doc3 - & gt; Shard3

Keine zwei aufeinander folgenden Dokumente gehören zum selben Shard. Daher ist ein Aufruf von getLastError erforderlich jedes Dokument in diesem Fall.

Im Fall von Hash-Schlüsseln werden Dokumente zufälliger unter den Shards verteilt. dh Dokumente, die zu denselben Shards gehören, können verstreut sein und daher eine größere Anzahl von Batches erstellen. Je zufälliger die Distribution ist, desto kleiner die Chargengröße, desto mehr Chargenanzahl, desto höher die angefallenen Kosten für getLastError was bedeutet, dass die Leistung schlechter ist.

FIX : Geben Sie "ordered: false" an.

%Vor%

Dies teilt der Datenbank mit, dass es Ihnen nicht wichtig ist, die Reihenfolge, in der die Einfügungen stattfinden, strikt zu bewahren. Mit "ordered: false" erstellt mongos einen einzelnen Batch pro Shard, wodurch zusätzliche getLastError-Aufrufe vermieden werden. Jeder Stapelvorgang kann gleichzeitig mit dem entsprechenden Shard ausgeführt werden, ohne auf die getLastError -Antwort des vorherigen Stapels zu warten.

Auch

MongoClient mongoClient = new MongoClient(host, port);

  

Erzeugt eine Mongo-Instanz basierend auf einem einzelnen Mongodb-Knoten und kann keine anderen Knoten in Ihrem Replikat-Satz oder dem Sharded-Cluster entdecken.

In diesem Fall werden all Ihre Schreibanforderungen an einen einzelnen Knoten weitergeleitet, der für die zusätzliche Buchhaltung aufgrund von sharded-cluster verantwortlich ist. Was Sie verwenden sollten, ist

%Vor%
  

Wenn mehr als ein Server ausgewählt werden soll, basierend auf dem Typ der Anfrage (Lesen oder Schreiben) und der Lesefreundlichkeit (wenn es ein   Leseanforderung), wählt der Treiber nach dem Zufallsprinzip einen Server aus, um einen zu senden   anfordern. Dies gilt sowohl für Replikat-Sets als auch für Sharded Cluster.

     

Hinweis: Setzen Sie so viele Server wie möglich in die Liste und das System wird es tun   finde den Rest heraus.

    
Rahul 10.03.2017 10:37
quelle
0

Wenn Sie eine sharded Lösung verwenden, müssen Sie im Allgemeinen Folgendes denken:

  1. Ihre Client-Anwendung ist clusterfähig und kann das Routing selbst durchführen
  2. Ihre Clientanwendung wird mit Zwischenknoten in Kontakt treten, die das Routing durchführen

Mein Verdacht ist, dass der Mongo-Client nicht automatisch "cluster-aware" ist, was bedeutet, dass er die Knoten des Clusters nicht nachschlägt, wenn Sie sie nicht angeben. Dieses Gefühl wird durch Folgendes verstärkt:

  • Die offizielle MongoDB-Dokumentation für Clustering und Sharting führt routers -Komponente ein ( Ссылка )
  • Das Javadoc sagt ausdrücklich, den ServerAddress [] - Konstruktor zu verwenden, um entweder eine Replikatmenge oder einen Sharded Cluster zu verbinden.
  

Sie können eine Verbindung zu einem Replikat mithilfe des Java-Treibers herstellen, indem Sie a übergeben   ServerAddress-Liste für den MongoClient-Konstruktor Zum Beispiel:

     

MongoClient mongoClient = neuer MongoClient (Arrays.asList (neu   ServerAddress ("localhost", 27017), neue ServerAddress ("localhost",   27018), neue ServerAddress ("localhost", 27019)));

     

Sie können eine Verbindung herstellen   zu einem Sharded Cluster mit dem gleichen Konstruktor. MongoClient wird   Automatische Erkennung, ob es sich bei den Servern um eine Liste von Replikatgruppenmembern oder a   Liste der Mongo-Server.

    
Edmondo1984 09.03.2017 21:16
quelle