猿教程 Logo

.Net连接MongoDb:诊断

介绍

在上一篇文章中,我们了解到在MongoDb文档中为文本字段构建索引。 如果要在较大文本中搜索某些文本位,则索引字段非常有用。 文本搜索在找到最好的比赛时做得很好。 我们甚至可以要求MongoDb为我们排列匹配的文件。

我们实际上完成了关于MongoDb中索引的讨论。 这篇文章将简要介绍MongoDb中可用的诊断工具。 它们帮助我们提取了有关MongoDb中发生的大量有用信息。

缓慢查询的默认日志记录

Mongod有一个日志目标取决于它是如何开始的。 在本系列中,我们在控制台窗口中启动了Mongo数据库,其中包含“mongod”。 因此MongoDb将在该窗口中写入其输出。 默认情况下,MongoDb将记录每个需要超过100ms的查询完成。

如果我们在zipcodes集合上运行我们早期的聚合示例之一...:

db.zipcodes.aggregate([
{$group : { "_id" : {"state" : "$state", "city" : "$city"}, "population"  : {$sum : "$pop"}}},
{$sort: {"_id.state" : 1, "population" : -1}},
{$group: {"_id" : {"state" : "$_id.state"}, "largest_city" : {$first: "$_id.city"}, "population" : {$first: "$population"}}},
{$sort : {"_id.state" : 1}},
{$project : {"_id" : 0, "state" : "$_id.state" ,"largest_city" : 1, "population": 1}}
])

那么在没有任何相关索引的情况下,查询几乎肯定需要100多个时间才能完成。 我的mongod窗口因此登录到控制台窗口:

2016-05-31T20:47:50.861+0200 I COMMAND  [conn1] command model.zipcodes command: aggregate { aggregate: "zipcodes", pipeline: [ { $group: { _id: { state: "$state", city: "$city" }, population: { $sum: "$pop" } } }, { $sort: { _id.state: 1.0, population: -1.0 } }, { $group: { _id: { state: "$_id.state" }, largest_city: { $first: "$_id.city" }, population: { $first: "$population" } } }, { $sort: { _id.state: 1.0 } }, { $project: { _id: 0.0, state: "$_id.state", largest_city: 1.0, population: 1.0 } } ], cursor: {} } keyUpdates:0 writeConflicts:0 numYields:229 reslen:3501 locks:{ Global: { acquireCount: { r: 466 } }, Database: { acquireCount: { r: 233 } }, Collection: { acquireCount: { r: 233 } } } protocol:op_command 146ms

如果我另一方面在一个只有10个文件的小集合上运行find命令...:

db.people.find()

那么mongod控制台将保持“沉默”。 因此,这个默认日志功能可以成为找到缓慢查询的良好起点。

内置的分析器

数据库分析器将为我们提供有关查询的更多详细信息。 它将其日志写入system.profile集合。 mongod的默认轮廓器级别为0,表示已关闭。 使用级别1,我们可以指定响应时间(以毫秒为单位)。 如果一个查询的时间要长于完成时间,那么它将被记录到system.profile集合中。 最后,我们有2级,我们要求mongod记录对数据库所做的每一个查询。

当mongod启动时,分析必须打开,如下所示:

mongod --profile 1 --slowms 10

... slowms参数是前面提到的毫秒的执行时间限制。 我们将上限设置为10ms。 请注意,我们在te配置文件和slowms参数前面有双击。

如果我们运行与上述相同的聚合示例,我们将在mongod控制台中立即看到创建了配置文件集合:

Creating profile collection: model.system.profile

我们可以得到该收集的文件如下:

db.system.profile.find()

汇总查询的记录方式如下:

{
        "op" : "command",
        "ns" : "model.zipcodes",
        "command" : {  //command ignored

        },
        "keyUpdates" : 0,
        "writeConflicts" : 0,
        "numYield" : 229,
        "locks" : {
                "Global" : {
                        "acquireCount" : {
                                "r" : NumberLong(466)
                        }
                },
                "Database" : {
                        "acquireCount" : {
                                "r" : NumberLong(233)
                        }
                },
                "Collection" : {
                        "acquireCount" : {
                                "r" : NumberLong(233)
                        }
                }
        },
        "responseLength" : 3501,
        "protocol" : "op_command",
        "millis" : 158,
        "execStats" : {

        },
        "ts" : ISODate("2016-05-31T19:11:22.192Z"),
        "client" : "127.0.0.1",
        "allUsers" : [ ],
        "user" : ""
}

这里最有趣的信息是“millis”属性,显示执行查询所花费的时间。 “ns”属性将显示我们查询了哪个集合。 “ts”时间戳属性在查询发生时显示。 另外,由于system.profile是一个带有BSON文档的“正常”集合,所以没有什么可以阻止我们查询它。 我们可以查询最慢的查询,在特定时间段内执行的查询等

在启动mongod之后,我们可以使用setProfilingLevel()函数打开分析。 它接受两个整数值:分析级别和以毫秒为单位的限制:

db.setProfilingLevel(1, 10)

getProfilingStatus函数返回当前的分析模式:

db.getProfilingStatus()

最后这是如何关闭剖析:

db.setProfilingLevel(0)

setProfilingLevel命令始终返回在进行更改之前的概要分析级别。

Mongotop

Mongotop是另一个有趣的工具,它向我们展示了MongoDb的整体情况。 我们可以在单独的命令窗口中启动它。 我们可以提供一个整数参数。 它设置mongotop输出的间隔:

mongotop 5

如果数据库中没有任何事情,那么我们会得到一堆0:

ns    total    read    write    2016-05-31T21:35:07+02:00
  admin.system.roles      0ms     0ms      0ms
admin.system.version      0ms     0ms      0ms
  loadtest.customers      0ms     0ms      0ms
   loadtest.products      0ms     0ms      0ms
   local.startup_log      0ms     0ms      0ms
local.system.replset      0ms     0ms      0ms
     model.companies      0ms     0ms      0ms
        model.people      0ms     0ms      0ms
   model.restaurants      0ms     0ms      0ms
model.system.profile      0ms     0ms      0ms

你可能会理解这里的输出。 它告诉我们在诊断输出时在各种命名空间中读取和写入花费多少时间。 一旦我们从mongo shell开始执行几个命令,mongotop输出就会改变。 这里我只显示邮政编码集合统计信息:

ns    total    read    write    2016-05-31T21:36:52+02:00
      model.zipcodes     23ms    23ms      0ms
 

                  ns    total     read    write    2016-05-31T21:36:57+02:00
      model.zipcodes    119ms    119ms      0ms
  
                  ns    total    read    write    2016-05-31T21:37:02+02:00
      model.zipcodes     70ms    70ms      0ms

当您想要比较优化运行之前和之后的数据库的一般状态时,Mongotop是一个很好的工具。 理想情况下,您将执行相同的命令设置,以反映数据库的一些平均流量和查询。

Mongostat

我们最后可以提到另一种称为mongostat的诊断工具。 它可以在像mongotop这样的单独的窗口中启动。 Mongostat接受默认值为27017的端口号。我们使用mongostat命令启动mongostat:

mongostat

它将开始输出关于给定端口上的数据库的CRUD操作数的一些总体信息。 日志的间隔为1秒,并且在此秒内显示状态。 以下是执行一些查询的一些示例输出:

insert query update delete getmore command % dirty % used flushes  vsize   res qr|qw ar|aw netIn netOut conn                      time
    *0     3     *0     *0       0     6|0     0.0    0.0       0 190.0M 23.0M   0|0   0|0  671b    49k    2 2016-05-31T21:49:36+02:00
    *0     4     *0     *0       0     5|0     0.0    0.0       0 190.0M 23.0M   0|0   0|0  663b    59k    2 2016-05-31T21:49:37+02:00
    *0    *0     *0     *0       0     7|0     0.0    0.0       0 190.0M 23.0M   0|0   0|0  518b    19k    2 2016-05-31T21:49:38+02:00
    *0     3     *0     *0       0     4|0     0.0    0.0       0 190.0M 23.0M   0|0   0|0  517b    49k    2 2016-05-31T21:49:39+02:00

有关mongostat的用法,输入参数和输出的更多信息,请参阅本文档页面

在下一篇文章中,我们将看到如何处理.NET驱动程序中的索引。


版权声明:本站所有教程均为本站原创或翻译,转载请注明出处,请尊重他人劳动果实。请记住本站地址:www.yuanjiaocheng.net (猿教程) 作者:卿文刚
本文标题: C#环境
本文地址:http://www.yuanjiaocheng.net/CsharpMongo/38.html