Azure DocumentDB上的性能较低 [英] Slow performance on Azure DocumentDB

查看:66
本文介绍了Azure DocumentDB上的性能较低的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前面临来自Azure DocumentDB的相当慢的响应时间(第一次尝试)。

集合中有31个对象,我将获取它们并返回给调用者。我使用的代码是:

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

要实例化客户端,我使用以下代码:

_client = new DocumentClient(new Uri(endpoint), authKey, new ConnectionPolicy
{
    ConnectionMode = ConnectionMode.Direct,
    ConnectionProtocol = Protocol.Tcp
});
我从Stopwatch获得的返回31个对象的响应时间介于360ms到1200ms之间。对我来说,这相当慢。如果没有自定义ConnectionPolicy,平均响应时间约为950ms。

我是不是做错了什么?是否有可能以某种方式加快这些请求的速度?

以下是跟踪的输出,打印出秒表的运行时间:

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

推荐答案

已更新以反映最新服务变更(2017年01月22日):DocumentDB在数据库端保证P99读取延迟<;10ms和P99写入延迟<;15ms。以下提示仍然适用于使用SDK实现低延迟读取**

更新以反映最新服务变化(2016-06-14):使用自定义ID路由时无需缓存自链接。还添加了更多提示。**

读取DocumentDB存储分区本身通常需要<;1毫秒;瓶颈通常是应用程序和数据库之间的网络延迟。因此,最好让应用程序在与数据库相同的数据中心中运行。

以下是SDK使用的一些一般提示:

提示1:在应用程序的整个生命周期内使用单例DocumentDB客户端

请注意,在直接模式下操作时,每个DocumentClient实例都是线程安全的,并执行高效的连接管理和地址缓存。若要允许DocumentClient进行高效的连接管理并提高性能,建议在应用程序的整个生命周期内为每个AppDomain使用DocumentClient的单个实例。

提示2:缓存文档和集合自链接以降低读取延迟

在Azure DocumentDB中,每个文档都有一个系统生成的selfLink。这些selfLink保证在文档的生命周期内是唯一和不可变的。使用selfLink阅读单个文档是获取单个文档的最有效方式。由于selfLink的不变性,您应该尽可能缓存selfLink以获得最佳读取性能。

Document document = await client.ReadDocumentAsync("/dbs/1234/colls/1234354/docs/2332435465");
话虽如此,应用程序可能并不总是可以使用文档的selfLink进行读取场景;在这种情况下,检索文档的下一个最有效的方法是通过文档的用户提供的ID属性进行查询。例如:

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

提示3:调整查询/阅读提要的页面大小以获得更好的性能

使用Read Feed功能(即ReadDocumentFeedAsync)执行文档批量读取或发出DocumentDB SQL查询时,如果结果集太大,则会以分段方式返回结果。默认情况下,结果以100个项目或1 MB的区块为单位返回,以最先达到的限制为准。

为了减少检索所有适用结果所需的网络往返次数,您可以使用x-ms-max-item-count请求头将页面大小增加到最多1000。如果您只需要显示几个结果,例如,如果您的用户界面或应用程序API一次只返回10个结果,您还可以将页面大小减少到10,以减少读取和查询消耗的吞吐量。

您还可以使用可用的DocumentDB SDK设置页面大小。例如:

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

更多提示(2016/6/14):

  • 使用点读取(例如读取文档而不是查询文档)按ID查找
  • 配置DocumentDB客户端(使用ConnectionPolicy)以使用网关上的直接连接
  • 将客户端与您的数据库并置在同一Azure区域
  • 调用OpenAsync()以防止较高的首次调用延迟
  • 您可以通过调用Queryable上的ToString()来调试LINQ查询,以查看通过网络发送的SQL查询

有关更多性能提示,请查看此blog post

这篇关于Azure DocumentDB上的性能较低的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆