tutorial net microsoft management cosmosdb c# .net azure azure-cosmosdb

c# - net - Rendimiento lento en Azure DocumentDB



cosmosdb net core (1)

Actualmente me enfrento a tiempos de respuesta bastante lentos de Azure DocumentDB (la primera vez que lo intento).

Hay 31 objetos en una colección, que voy a buscar y devolver a la persona que llama. El código que estoy usando es este:

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(); }

Para crear una instancia del cliente, estoy usando el siguiente código:

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

Los tiempos de respuesta que obtengo del Stopwatch son entre 360 ​​ms y 1200 ms para devolver 31 objetos. Para mí, eso es bastante lento. Sin la política de ConnectionPolicy personalizada, el tiempo de respuesta promedio es de aproximadamente 950 ms.

¿Estoy haciendo algo mal aquí? ¿Es posible acelerar estas solicitudes de alguna manera?

Aquí está la salida del Rastreo, imprimiendo el tiempo transcurrido del Cronómetro:

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


Actualizado para reflejar los últimos cambios en el servicio (1/22/2017): DocumentDB garantiza una latencia de lectura p99 <10 ms y una latencia de escritura p99 <15 ms con SLA en el lado de la base de datos. Las siguientes sugerencias aún se aplican para lograr lecturas de baja latencia utilizando los SDK **

Actualizado para reflejar los cambios más recientes en el servicio (14/06/2016): no es necesario almacenar enlaces automáticos cuando se utiliza el enrutamiento a través de las identificaciones definidas por el usuario. También agregó algunos consejos más. **

Las lecturas suelen tardar <1 ms en la partición de almacenamiento DocumentDB; y el cuello de botella es a menudo la latencia de la red entre la aplicación y la base de datos. Por lo tanto, es mejor tener la aplicación ejecutándose en el mismo centro de datos que la base de datos.

Aquí hay algunos consejos generales sobre el uso de SDK:

Consejo # 1: Use un cliente de DocumentDB de singleton durante la vida útil de su aplicación

Tenga en cuenta que cada instancia de DocumentClient es segura para subprocesos y realiza una gestión eficiente de la conexión y el almacenamiento en caché de direcciones cuando se opera en modo directo. Para permitir una gestión eficiente de la conexión y un mejor rendimiento por parte de DocumentClient, se recomienda usar una sola instancia de DocumentClient por AppDomain durante toda la vida de la aplicación.

Consejo # 2: almacenamiento en caché de documentos y autoenlaces de enlaces para una menor latencia de lectura

En Azure DocumentDB, cada documento tiene un enlace automático generado por el sistema. Se garantiza que estas autoenlaces son únicas e inmutables durante la vida útil del documento. Leer un solo documento usando un enlace automático es la forma más eficiente de obtener un solo documento. Debido a la inmutabilidad del enlace automático, debe guardar los enlaces automáticos siempre que sea posible para obtener el mejor rendimiento de lectura.

Document document = await client.ReadDocumentAsync("/dbs/1234/colls/1234354/docs/2332435465");

Dicho esto, puede que no siempre sea posible que la aplicación funcione con el enlace automático de un documento para escenarios de lectura; en este caso, la siguiente manera más eficiente de recuperar un documento es consultar por la propiedad Id proporcionada por el usuario del documento. Por ejemplo:

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; } }

Consejo # 3: Ajuste el tamaño de la página para consultas / lecturas de fuentes para un mejor rendimiento

Al realizar una lectura masiva de documentos con la función de fuente de lectura (es decir, ReadDocumentFeedAsync) o al emitir una consulta SQL DocumentDB, los resultados se devuelven de forma segmentada si el conjunto de resultados es demasiado grande. De forma predeterminada, los resultados se devuelven en partes de 100 elementos o 1 MB, independientemente del límite que se alcance.

Para reducir el número de viajes de ida y vuelta de red necesarios para recuperar todos los resultados aplicables, puede aumentar el tamaño de la página utilizando el encabezado de solicitud x-ms-max-item-count hasta 1000. En los casos en los que necesita mostrar solo unos pocos resultados, por ejemplo, si la interfaz de usuario o la API de la aplicación solo obtienen diez resultados a la vez, también puede reducir el tamaño de la página a 10 para reducir el rendimiento consumido para lecturas y consultas.

También puede establecer el tamaño de página utilizando los SDK de DocumentDB disponibles. Por ejemplo:

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

Algunos consejos más (14/06/2016):

  • Utilice lecturas de puntos (p. Ej., Lea el documento en lugar del documento de consulta) para buscar por ID
  • Configure el cliente DocumentDB (usando ConnectionPolicy) para usar la conectividad directa a través de la puerta de enlace
  • Ubique clientes en la misma región de Azure que su base de datos
  • Llame a OpenAsync () para evitar una mayor latencia de la primera llamada
  • Puede depurar las consultas LINQ llamando a ToString () en la consulta para ver la consulta SQL enviada a través del cable

Para obtener más consejos de rendimiento, echa un vistazo a esta entrada de blog .