2015-08-29 3 views
15

Ich bin derzeit mit ziemlich langsamen Antwortzeiten von Azure DocumentDB konfrontiert (beim ersten Versuch).Schlechte Leistung bei Azure DocumentDB

Es gibt 31 Objekte in einer Sammlung, die ich abrufen und an den Aufrufer zurückgeben werde. Der Code, den ich verwende, ist dies:

public async Task<List<dynamic>> Get(string collectionName = null) 
{ 
    // Lookup from Dictionary, takes literally no time 
    var collection = await GetCollectionAsync(collectionName); 

    var sw = Stopwatch.StartNew(); 

    var query = await 
     _client.CreateDocumentQuery(collection.DocumentsLink, 
      new FeedOptions { MaxItemCount = 1000 }) 
      .AsDocumentQuery() 
      .ExecuteNextAsync(); 

    Trace.WriteLine($"Get documents: {sw.ElapsedMilliseconds} ms"); 

    return query.ToList(); 
} 

den Client zu instantiieren, ich bin mit dem folgenden Code:

_client = new DocumentClient(new Uri(endpoint), authKey, new ConnectionPolicy 
{ 
    ConnectionMode = ConnectionMode.Direct, 
    ConnectionProtocol = Protocol.Tcp 
}); 

Die Ansprechzeiten Ich bin von den Stopwatch immer zwischen 360ms und 1200ms zu Rückgabe von 31 Objekten Für mich ist das ganz langsam. Ohne die benutzerdefinierte ConnectionPolicy ist die durchschnittliche Antwortzeit ca. 950ms.

Mache ich hier etwas falsch? Ist es möglich, diese Anfragen irgendwie zu beschleunigen? Hier

ist die Ausgabe von der Spur, die verstrichene Zeit der Stoppuhr Ausdrucken:

Get documents: 1984 ms 
Get documents: 1252 ms 
Get documents: 1246 ms 
Get documents: 359 ms 
Get documents: 356 ms 
Get documents: 356 ms 
Get documents: 351 ms 
Get documents: 1248 ms 
Get documents: 1314 ms 
Get documents: 1250 ms 
+0

Haben Sie versucht, den Code im selben Datencenter wie Ihre DocumentDB-Instanz auszuführen? Ich bin sehr enttäuscht, wenn ich Operationen von meinem System über eine schnelle Internetverbindung (mindestens 250ms für eine einzige Operation) ausführen kann, aber die Latenz liegt unter 10ms, wenn ich im selben Rechenzentrum laufe. Wenn Sie nicht möchten, dass das Experiment an das Rechenzentrum gesendet wird, versuchen Sie eine Abfrage mit der zehnfachen Datenmenge. Mein Verdacht ist, dass Sie nur leicht erhöhte Zahlen sehen werden. Wenn dies der Fall ist, würde dies einen Hinweis darauf geben, dass es sich um die Latenzzeit handelt, die von außerhalb des Rechenzentrums aufgerufen wird. –

+0

Ich denke, dass es einen Fall gibt, dass eine Überschreitung der Grenzen des Datenzentrums aus Latenzperspektive zu teuer ist. Die Ping-Zeit auf meiner Internetverbindung beträgt nur 50-70ms. Selbst das Verdoppeln erklärt nicht die minimale Latenz von 250 ms. –

+0

Ich kann so viel sagen: das Abrufen von 31 Zeilen von einem SQL-Server (Azure) im selben Rechenzentrum ist _much_ schneller als das. Auch wenn die Zeilen mehr Daten enthalten als die Objekte, die von DocumentDB abgerufen wurden. –

Antwort

15

Aktualisiert neueste Service Änderungen widerspiegeln (2017.01.22): DocumentDB garantiert p99 Leselatenz < 10 ms und p99 Schreiblatenz < 15 ms mit SLAs auf der Datenbankseite. Die folgenden Tipps gelten weiterhin, um Lesevorgänge mit niedriger Latenz mithilfe der SDKs zu erreichen. **

Aktualisiert, um die neuesten Serviceänderungen widerzuspiegeln (14.06.2016): Zwischenspeichern von Eigenverknüpfungen bei Verwendung von Routing über Benutzer definierte IDs Außerdem wurden noch ein paar Tipps hinzugefügt. **

Lesevorgänge dauern typischerweise < 1 ms auf der DocumentDB-Speicherpartition selbst; und der Flaschenhals ist oft die Netzwerklatenz zwischen der Anwendung und der Datenbank. Daher ist es am besten, wenn die Anwendung im selben Datencenter ausgeführt wird wie die Datenbank.

Hier sind einige allgemeine Tipps zur SDK Nutzung:

Tipp # 1: ein Singleton DocumentDB-Client für die gesamte Lebensdauer Ihrer Anwendung verwenden

Beachten Sie, dass jede DocumentClient Instanz Thread-sicher ist und führt effizient Verbindungsverwaltung und Adress-Caching im direkten Modus. Um ein effizientes Verbindungsmanagement und eine bessere Performance durch den DocumentClient zu ermöglichen, wird empfohlen, eine einzige Instanz von DocumentClient pro Anwendungsdomäne für die Lebensdauer der Anwendung zu verwenden.

Spitze # 2: Cache-Dokument und Sammlung SelfLinks für niedrigere Leselatenz

In Azure DocumentDB weist jedes Dokument, das eine vom System erzeugte selfLink. Diese SelfLinks sind garantiert einmalig und unveränderlich für die Lebensdauer des Dokuments. Das Lesen eines einzelnen Dokuments mit einem selfLink ist der effizienteste Weg, um ein einzelnes Dokument zu erhalten. Aufgrund der Unveränderlichkeit des SelfLink sollten Sie SelfLinks zwischenspeichern, wann immer dies möglich ist, um die beste Leseleistung zu erzielen.

Dennoch ist es möglicherweise nicht immer möglich, dass die Anwendung mit dem SelfLink eines Dokuments für Leseszenarien arbeitet; In diesem Fall besteht die nächst effizienteste Methode zum Abrufen eines Dokuments in der Abfrage nach der vom Benutzer bereitgestellten ID-Eigenschaft des Dokuments. Zum Beispiel:

IDocumentQuery<Document> query = (from doc in client.CreateDocumentQuery(colSelfLink) where doc.Id == "myId" select document).AsDocumentQuery(); 
      Document myDocument = null; 
      while (query.HasMoreResults) 
      { 
       FeedResponse<Document> res = await query.ExecuteNextAsync<Document>(); 
       if (res.Count != 0) { 
        myDocument = res.Single(); 
        break; 
       } 
      } 

Tipp # 3: Tune Seitengröße für Abfragen/Feeds lesen für eine bessere Leistung

Bei der Durchführung einer Masse von Dokumenten lesen lesen Feed-Funktionalität (dh ReadDocumentFeedAsync) oder bei der Ausgabe einer DocumentDB SQL-Abfrage werden die Ergebnisse segmentiert zurückgegeben, wenn die Ergebnismenge zu groß ist. Standardmäßig werden Ergebnisse in Teilen von 100 Elementen oder 1 MB zurückgegeben, je nachdem, welches Limit zuerst erreicht wird.

Um die Anzahl der erforderlichen Netzwerk-Roundtrips zum Abrufen aller zutreffenden Ergebnisse zu reduzieren, können Sie die Seitengröße mit x-ms-max-item-count Anforderungsheader auf bis zu 1000 erhöhen. In Fällen, in denen dies erforderlich ist Zeigen Sie nur einige Ergebnisse an, z. B. wenn Ihre Benutzerschnittstelle oder Anwendungs-API nur zehn Ergebnisse pro Zeit zurückgibt, können Sie die Seitengröße auf 10 reduzieren, um den Durchsatz für Lese- und Abfragevorgänge zu reduzieren.

Sie können die Seitengröße auch mithilfe der verfügbaren DocumentDB SDKs festlegen. Zum Beispiel:

IQueryable<dynamic> authorResults = 
client.CreateDocumentQuery(documentCollection.SelfLink, "SELECT p.Author FROM Pages p WHERE p.Title = 'About Seattle'", new FeedOptions { MaxItemCount = 1000 }); 

Noch ein paar Tipps (2016.06.14):

  • Verwendung punkt liest (zB Dokument statt Abfragedokument lesen) für die Suche nach ID
  • Konfigurieren Sie den DocumentDB-Client (unter Verwendung von ConnectionPolicy), um direkte Konnektivität über Gateway zu verwenden
  • Kollokieren Sie Clients in derselben Azure-Region wie Ihre Datenbank
  • Call Op enAsync() höher ersten Anruf Latenz zu verhindern
  • Sie LINQ-Abfragen durch den Aufruf von ToString() auf dem abfragbaren debuggen können die SQL-Abfrage über den

Weitere Performance-Tipps, lesen Sie in diesen blog post Draht geschickt, um zu sehen.

+1

Warum ist Tipp # 2 durchgestrichen? – Andy