2016-09-10 3 views
1

Ich habe eine Multithread-App, die Hunderte von Transaktionen pro Sekunde ausführt, aber nach einer Weile die Leistung sinkt und die Abfragen dauern zu lange, um auszuführen. Ich habe daran gearbeitet, die Verbindung mit dem folgenden Code zu optimieren, um Fehler zu vermeiden, aber dies führte zu einer schlechten Leistung.Mongodb-Abfragen sind sehr langsam

Meine Abfragen variieren von Einfügungen, Löschen und Multi-Update; Sammlungen überschreiten nicht 100.000 Zeilen.

Ich habe einen Cluster von 4 VMs für Mongoldb jeder hat 4 Kerne und 28 GB Ram auf Azure. Ich baute den Cluster bitnami Produktion (https://azure.microsoft.com/en-us/marketplace/partners/bitnami/production-mongodbdefault/)

private static MongoClientOptions options = MongoClientOptions.builder() 
.connectionsPerHost(1000) 
.threadsAllowedToBlockForConnectionMultiplier(15) 
.connectTimeout(60 * 1000) 
.maxWaitTime(60 * 1000) 
.socketTimeout(60 * 1000) 
.connectTimeout(60 * 1000) 
.build(); 

Ich benutze keine Indizes verwenden und hier ist meine App Flow:

  1. sind die db Geschichten zum Einreihen und Verarbeitung msgs verwenden. Jeder Auftrag wird in einer separaten Sammlung gespeichert, mit einem Dokument für jeden msg die wie folgt aussieht (Status ‚bereit‘ für die msgs in diesem Stadium):
{ 
"_id": ObjectId("57cd303743ffe80f3728fcf5"), 
"_class": "com.mongodb.BasicDBObject", 
"job_id": "57cd3031d9991f8639487013", 
"priority": 1, 
"title": "1", 
"sender_id": "sender 1", 
"account_id": "57c2d556d9991fbc15897275", 
"schedule_date": ISODate("2016-09-05T08:43:00Z"), 
"utf8": false, 
"content": "text to be sent", 
"number": "962799000001", 
"status": "ready", 
"user_id": "57c2d602d9991fbc1589727b", 
"adv": true, 
"number_of_sms_msgs": 1, 
"uuid": "57cd3031d9991f8639487013_57cd303743ffe80f3728fcf5", 
"msg_id": "1955559517" 
} 
  1. Dann bin ich Chargen von jedem Auftrag nach ihren Prioritäten von Status ‚bereit‘ zu ‚Warteschlange‘ und fügen sie sie auf-Speicherwarteschlange zu bewegen verarbeitet werden:
List<DBObject> batch = scaffoldingRepository.findPageNoSort(dataType, page, next_batch_size, query, null); 
if (batch != null && batch.size() > 0) {  
    BasicDBList ids = new BasicDBList(); 
    for (final DBObject msg : batch) { 
     msg.put("status", "queued"); 
     msg.put("uuid", job_id + "_" + msg.get("_id")); 
     ids.add(new ObjectId(msg.get("_id").toString())); 
    } 
    BasicDBObject search = new BasicDBObject(); 
    search.put("_id", new BasicDBObject("$in", ids)); 
    BasicDBObject update = new BasicDBObject(); 
    update.put("$set", new BasicDBObject("status", "queued")); 
    scaffoldingRepository.updateObjects(search, update, dataType); 
} 
  1. Dann sendet ein anderer Thread die aktuellen Nachrichten aus der On-Memory-Queue und aktualisiert eac h msg's Status getrennt (gesendet/fehlgeschlagen); Ich füge einen Index für diese Nachricht in einer separaten Tabelle hinzu, damit ich es finden kann, sobald der Absender mir den endgültigen Status zurücksendet.
  2. Schließlich bekomme ich ein Endergebnis vom Absender über die msg (geliefert/nicht geliefert) und ich aktualisiere diese Nachricht entsprechend, dann entfernen Sie den Index aus der Sammlung (Job_Index) im vorherigen Schritt.

========================== UPDATE: ============= =========

ich bemerkte, dass ich in Java-Protokolle diesen Fehler bekam:

com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message 
at com.mongodb.connection.InternalStreamConnection.translateReadException(InternalStreamConnection.java:475) 
at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:226) 
at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java:105) 
at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java:438) 
at com.mongodb.connection.WriteCommandProtocol.receiveMessage(WriteCommandProtocol.java:262) 
at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:104) 
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:64) 
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:37) 
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:168) 
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:289) 
at com.mongodb.connection.DefaultServerConnection.updateCommand(DefaultServerConnection.java:143) 
at com.mongodb.operation.UpdateOperation.executeCommandProtocol(UpdateOperation.java:76) 
at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:142) 
at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:134) 
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:232) 
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:223) 
at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:134) 
at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:61) 
at com.mongodb.Mongo.execute(Mongo.java:827) 
at com.mongodb.Mongo$2.execute(Mongo.java:810) 
at com.mongodb.DBCollection.executeWriteOperation(DBCollection.java:333) 
at com.mongodb.DBCollection.updateImpl(DBCollection.java:495) 
at com.mongodb.DBCollection.update(DBCollection.java:455) 
at com.mongodb.DBCollection.update(DBCollection.java:432) 
at com.mongodb.DBCollection.update(DBCollection.java:522) 
at com.mongodb.DBCollection.updateMulti(DBCollection.java:552) 
at java.util.TimerThread.mainLoop(Timer.java:555) 
at java.util.TimerThread.run(Timer.java:505) 

Und hier ist meine MongoDB config:

# mongod.conf 
# for documentation of all options, see: 
# http://docs.mongodb.org/manual/reference/configuration-options/ 

# Where and how to store data. 
storage: 
    dbPath: /opt/bitnami/mongodb/data/db 
    journal: 
    enabled: true 
    #engine: 
    mmapv1: 
    smallFiles: true 
# wiredTiger: 

# where to write logging data. 
systemLog: 
    destination: file 
    logAppend: true 
    path: /opt/bitnami/mongodb/logs/mongodb.log 

# network interfaces 
net: 
    port: 27017 
    bindIp: 0.0.0.0 
    unixDomainSocket: 
    enabled: true 
    pathPrefix: /opt/bitnami/mongodb/tmp 

# replica set options 
replication: 
    replSetName: replicaset 

# process management options 
processManagement: 
    fork: false 
    pidFilePath: /opt/bitnami/mongodb/tmp/mongodb.pid 

# set parameter options 
setParameter: 
    enableLocalhostAuthBypass: true 

# security options 
security: 
    authorization: disabled 
    #keyFile: replace_me 

#profiling 
#operationProfiling: 
    #slowOpThresholdMs: 100 
    #mode: slowOp 
+0

Das Wichtigste zuerst würde ich nehmen ein Mongo-Profil und sehen, wer der Engpass ist - Mongo oder Ihr Anwendungscode. So etwas wie 'mongod -profile 1 -slowms 20'. Siehe http://stackoverflow.com/a/18451741/4148708 – evilSnobu

Antwort

1

Einige Tipps



-In MongoDB Profiler haben Sie die langsam laufenden Abfragen überprüft.

- Haben Sie versucht, die Dokumente zu indexieren (verwenden Sie die Eingaben von oben)

- Welche Version von MongoDB verwenden Sie und welche ist die Speicher-Engine?

-Haben Sie Replikation des Servers fertig.Wenn ja, bitte den Schreib Sorge Teil https://docs.mongodb.com/manual/core/replica-set-write-concern/

erneut -Kann Sie prüfen, ob mongodb In-Memory-Implementierung https://docs.mongodb.com/manual/core/inmemory/

helfen können -Sie können einige wichtige Tipps, siehe hier - https://docs.mongodb.com/manual/administration/analyzing-mongodb-performance/