文档数据库性能问题

3
运行在本地计算机上的C#代码从DocumentDB查询时,平均一个简单的DocumentDB查询大约需要0.5秒。另一个例子是,获得文档集合的引用平均需要0.7秒。这是否符合预期?下面是检查集合是否存在的代码,非常简单明了 - 但有没有改善性能差的方法?
// Create a new instance of the DocumentClient
var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);

// Get the database with the id=FamilyRegistry
var database = client.CreateDatabaseQuery().Where(db => db.Id == "FamilyRegistry").AsEnumerable().FirstOrDefault();

var stopWatch = new Stopwatch();
stopWatch.Start();

// Get the document collection with the id=FamilyCollection
var documentCollection = client.CreateDocumentCollectionQuery("dbs/" 
    + database.Id).Where(c => c.Id == "FamilyCollection").AsEnumerable().FirstOrDefault();

stopWatch.Stop();

// Get the elapsed time as a TimeSpan value.
var ts = stopWatch.Elapsed;

// Format and display the TimeSpan value.
var elapsedTime = String.Format("{0:00} seconds, {1:00} milliseconds",
    ts.Seconds,
    ts.Milliseconds );

Console.WriteLine("Time taken to get a document collection: " + elapsedTime);
Console.ReadKey();

本地计算机的平均输出:

Time taken to get a document collection: 0 seconds, 752 milliseconds

在我的另一段代码中,我正在进行20个小型文档的更新,每个文档的JSON大小约为400字节,但总共仍需要12秒才能完成。虽然我只是在开发环境下运行,但我预期性能应该更好。


1
您尝试在与 DocumentDB 相同的数据中心中运行此代码了吗?我注意到,当 DocumentDB 操作跨越数据中心边界时,会出现大约 250 毫秒的延迟。但是,如果我从在 Azure 数据中心内运行的实例中调用它,则延迟很低,大约只有 10 毫秒。 - Larry Maccherone
@LarryMaccherone,我还没有这样做过,目前我只在本地开发环境中运行了我的代码。 - user152949
1个回答

7
简而言之,使用DocumentDB可以在端到端大约9毫秒内完成。下面将介绍所需要进行的更改以及它们对结果产生的影响。
在DocumentDB中,第一个查询总是需要更长的时间,因为它会进行一些设置工作(获取DocumentDB分区的物理地址)。接下来的几个请求需要一点时间来预热连接池。随后的查询将与您的网络速度一样快(由于SSD存储,DocumentDB读取的延迟非常低)。
例如,如果您修改上面的代码以测量10次读取而不仅仅是第一次,如下所示:
using (DocumentClient client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey))
{
    long totalRequests = 10;

    var database = client.CreateDatabaseQuery().Where(db => db.Id == "FamilyRegistry").AsEnumerable().FirstOrDefault();

    Stopwatch watch = new Stopwatch();
    for (int i = 0; i < totalRequests; i++)
    {
        watch.Start();
        var documentCollection = client.CreateDocumentCollectionQuery("dbs/"+ database.Id)
            .Where(c => c.Id == "FamilyCollection").AsEnumerable().FirstOrDefault();

        Console.WriteLine("Finished read {0} in {1}ms ", i, watch.ElapsedMilliseconds);
        watch.Reset();
    }
}

Console.ReadKey();

我在 Redmond 的桌面上运行下面的命令,测试连接 Azure West US 数据中心的 DocumentDB ,大约需要50毫秒。由于客户端与 Azure DC 的距离以及网络连接的差异,这些数字可能会有所不同:

Finished read 0 in 217ms
Finished read 1 in 46ms
Finished read 2 in 51ms
Finished read 3 in 47ms
Finished read 4 in 46ms
Finished read 5 in 93ms
Finished read 6 in 48ms
Finished read 7 in 45ms
Finished read 8 in 45ms
Finished read 9 in 51ms

接下来,我将从默认的网关切换到直接/TCP连接,以改善延迟从两个跳数到一个跳数,即将初始化代码更改为:

using (DocumentClient client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey, new ConnectionPolicy { ConnectionMode = ConnectionMode.Direct, ConnectionProtocol = Protocol.Tcp }))

现在通过ID查找集合的操作只需要23毫秒就能完成:

Finished read 0 in 197ms
Finished read 1 in 117ms
Finished read 2 in 23ms
Finished read 3 in 23ms
Finished read 4 in 25ms
Finished read 5 in 23ms
Finished read 6 in 31ms
Finished read 7 in 23ms
Finished read 8 in 23ms
Finished read 9 in 23ms

当您在同一Azure数据中心运行Azure VM或Worker角色时,运行相同的结果会在约9毫秒内完成!
Finished read 0 in 140ms
Finished read 1 in 10ms
Finished read 2 in 8ms
Finished read 3 in 9ms
Finished read 4 in 9ms
Finished read 5 in 9ms
Finished read 6 in 9ms
Finished read 7 in 9ms
Finished read 8 in 10ms
Finished read 9 in 8ms
Finished read 9 in 9ms

因此,总结一下:

  • 为了进行性能测量,请允许几个测量样本来考虑DocumentDB客户端的启动/初始化。
  • 请使用TCP /直接连接以获得最低延迟。
  • 尽可能在同一个Azure区域内运行。
  • 如果您遵循这些步骤,您可以获得出色的性能,并且可以使用DocumentDB获得最佳的性能数据。

我得到的时间是你的10倍,但是我从欧洲调用DocumentDB服务。不过,出于某种原因,当我调用Azure表存储时,我的性能并不那么糟糕。我在这里添加了一个PasteBin,其中包含我的结果http://pastebin.com/3u1VpgRB - user152949
@Aravind,我在工作中运行时(即使初始化和预热后)也远远达不到您的性能水平(约250毫秒与您的约23毫秒)。我没有从北卡罗来纳州连接到美国东部数据中心。对我来说,另一个区别是我使用了node.js,我知道它不使用TCP/Direct,但我也想知道您提到的“两个跳跃”是否适用于node.js的使用?第二个跳跃的目的是什么?CORS?作为微软员工,您的实验是否具有加速到数据中心的网络连接?不过,这可能只是我的工作连接不好。 - Larry Maccherone
@LarryMaccherone,作为对比,从我的家庭互联网连接上,我得到的延迟是33毫秒对比23毫秒,并没有太大的差异。如果你能给我发送一份WireShark跟踪报告,我们可以进行调试。 - Aravind Krishna R.
@AravindRamachandran 我没有WireShark,但我正在从北欧调用一个美国中部的DocumentDB服务,如果这有帮助的话。我正在使用DocumentDB客户端的v1.5版本。 - user152949
@AravindRamachandran(请看我一小时前的评论)...运行CreateDatabaseQuery()时的结果甚至更糟糕-在第一次调用时使用了长达5秒钟,请查看我的代码和结果,链接在这里http://pastebin.com/jU0r9wLj - user152949
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接