mongoreplay

在本页面

Synopsis

3.4 版的新功能。

Availability

适用于 Linux 和 macOS。

mongoreplay是用于 MongoDB 的流量捕获和重播工具,可用于检查和记录发送到 MongoDB 实例的命令,然后在以后将这些命令重播到另一台主机上。

mongoreplay可以帮助您预览 MongoDB 部署将如何在不同的环境下(例如,使用不同的存储引擎,在不同的硬件上或在不同的 os 配置下)执行生产工作负载。 mongoreplay还可以通过记录和重放触发问题的操作来帮助重现和调查问题。最后,mongoreplay是旧版mongosniff工具的更灵活版本,可帮助您调查数据库活动。

从系统命令行运行mongoreplay,而不是mongo shell。

Required Access

mongoreplay要求访问recordmonitor命令将监听的网络接口。您可能需要以 root 特权运行mongoreplay才能访问网络设备。

mongoreplay不适用于使用 SSL 连接的 MongoDB 实例。

Warning

连接到受信任的源时仅使用 root 特权。

如果您使用play连接到实施访问控制的 MongoDB 部署,则必须以具有所需特权的用户身份连接才能执行记录的操作。在--host MongoDB 连接字符串中包括用户的凭据。

Options

  • mongoreplay

  • --verbosity `,` `-v`

    • 增加在标准输出或日志文件中返回的内部报告的数量。通过多次包含该选项(例如-vvvvv)来提高-v形式的详细程度。
  • --debug `,` `-d`

    • 增加有关在日志文件中记录的 mongoreplay 操作和错误的详细信息。通过多次包含该选项(例如-ddd)来增加-d表单的调试详细信息。
  • --silent `,` `-s`

    • 设置后, mongoreplay 不会产生任何日志输出。
  • --help ``

    • 返回有关选项和 mongoreplay 使用的信息。

Commands

mongoreplay包含以下命令,用于记录,回放和监视 MongoDB 网络流量。

record

record根据网络流量产生一个播放文件。 record支持直接收集网络流量,或者可以接受pcap file来生成播放文件。回放文件包含在记录过程中发送到mongod实例的所有请求的列表,以及在记录过程中发送给 Client 端的所有响应。回放文件还记录每个请求的元数据,例如连接标识符和时间戳。

以下原型使用mongoreplay在回送网络接口上记录数据,并创建位于~/recordings/playback的回放文件。

mongoreplay record -i eth0 -e "port 27017" -p ~/recordings/playback

同样,以下原型使用mongoreplay从现有的 pcap 文件中生成一个回放文件:

mongoreplay record -f traffic.pcap -p ~/recordings/playback

record支持以下选项:

  • mongoreplay record

  • record

  • -f <path>

    • 指定record应该读取以生成播放文件的 pcap 文件的路径。

使用-f作为使用-i捕获网络流量的替代方法。您必须指定-f-i *。如果同时包含两个选项,则 mongoreplay 记录 会产生错误。

  • -b <number>

    • 用于将单独的流合并在一起的堆大小。
  • --expr <filter expression> , -e <filter expression>

例如,要捕获来自端口 27017 上运行的 MongoDB 实例的流量,您可以指定-e 'port 27017'

  • -i <interface>
    • 指定record应该侦听以捕获网络流量的网络接口。

-e一起使用。

使用-i替代使用-i读取现有的 pcap 文件。您必须指定-f-i *。如果同时包含两个选项,则 mongoreplay 记录 会产生错误。

  • --gzip <boolean>

    • 如果已指定,record将使用 gzip 压缩播放文件。
  • --playback-file <path> , -p <path>

    • 指定写入播放文件的路径。

产生的播放文件是 BSON 文件。

See

Use record举例说明如何将mongoreplayrecord命令一起使用。

play

playmongod实例重放用record创建的播放文件。

以下原型使用mongoreplay~/recordings/playback回放文件回放到192.168.0.4:27018上运行的mongod实例:

mongoreplay play -p ~/recordings/playback --report ~/reports/replay_stats.json --host mongodb://192.168.0.4:27018

play支持以下选项:

  • mongoreplay play

  • play

  • --collect <json|format|none>

    • 默认:格式

指定收集的统计信息的输出格式。

  • json:将统计信息输出为 json

  • format:使用--format选项中指定的格式来生成输出文件。

  • none:不提供任何输出

  • --report <path>

    • 指定写入执行报告的路径。使用--collect指定报告的输出格式。

如果未指定--report,则play写入 STDOUT。

  • --no-truncate ``

    • 如果指定,则在play日志输出中禁用大答复有效载荷数据的截断。
  • --format ``

    • 默认%F{blue}%t%f %F{cyan}(Connection: %o:%i)%f %F{yellow}%l%f %F{red}%T %c%f %F{white}%n%f %F{green}%Q{Request:}%f%q%F{green}%R{Response:}%f%r)

指定终端输出的格式。您可以通过将其用大括号括起来,例如%Q{<arg>},在格式“动词”之后立即指定参数。

如果指定--format,则还要指定format作为--collect选项的值。

--format支持以下动词:

  • %n:名称空间

  • %l:延迟

  • %t:时间。您可以选择使用 Go 编程语言的time formatting指定日期布局。 Go 使用Mon Jan 2 15:04:05 MST 2006作为参考时间。您必须使用参考时间指定时间格式。因此,如果要以yyyy-mm-dd hh:mm格式打印日期,则应指定%t{2006-01-02 15:04}。有关更多信息,请参阅 Go time formatting文档。

  • %T:操作时间

  • %c:命令

  • %o:连接数

  • %i:请求 ID

  • %q:请求。您可以在 JSON 结构中最终指定一个以点分隔的字段,例如%q{command_args.documents}

  • %r:回复。您可以在 JSON 结构中最终指定一个以点分隔的字段,例如%q{command_args.documents}

  • %Q{<arg>}:显示请求数据时显示<arg>

  • %R{<arg>}:显示响应数据时显示<arg>

此外,--format支持以下开始/结束 ANSI 转义序列:

  • %B/%b:粗体

  • %U/%u:下划线

  • %S/%s:出色

  • %F/%f:文本颜色(必填 arg-单词或数字,8 色)

  • %K/%k:背景色(必填 arg –与%F /%f 相同)

  • --no-colors ``

  • --playback-file <path> , -p <path>

    • 指定从中读取播放文件的路径。

如果播放文件是使用--gzip选项创建的,则在运行play时还必须指定--gzip

  • --speed number
    • 默认:1.0

指定一个乘数以调整播放速度。 --speed 1.0实时处理回放文件; --speed 0.5半速; --speed 3.0以三倍的速度。

指定的速度是目标速度。如果 mongoreplay 播放 遇到瓶颈,则播放速度可能会比指定的乘数慢。

  • --host <hostname><:port> , -h <hostname><:port>
    • 默认:localhost:27017

为 MongoDB 部署指定一个 MongoDB connection string,以将捕获的网络流量回放到其中。

默认情况下,play尝试连接到端口号27017在 localhost 上运行的mongod实例。

  • --repeat number
    • 默认:1

指定播放播放文件的次数。

  • --queueTime number
    • 默认:15

指定在传输操作之前将操作排队的最长时间(以秒为单位)。

  • --no-preprocess ``

    • 设置后,play不会将 Importing 文件预处理为预先 Map 的数据,例如 MongoDB 光标 ID。
  • --gzip <boolean>

    • 如果指定,play将使用 gzip 解压缩播放文件。

See

Use play举例说明如何将mongoreplayplay命令一起使用。

monitor

monitor检查实时或预先记录的 MongoDB 网络流量。

以下原型使用mongoreplay根据~/recordings目录中的playback.bson播放文件生成 JSON 报告:

mongoreplay monitor --collect json --report ~/reports/monitor-report.json -p ~/recordings/playback.bson

monitor支持以下选项:

  • mongoreplay monitor

  • monitor

  • --collect <json|format|none>

    • 默认:格式

指定收集的统计信息的输出格式。

  • json:将统计信息输出为 json

  • format:使用--format选项中指定的格式来生成输出文件。

  • none:不提供任何输出

  • --report <path>

    • 指定写入执行报告的路径。使用--collect指定报告的输出格式。

如果未指定--report,则monitor写入 STDOUT。

  • --no-truncate ``

    • 如果指定,则在monitor日志输出中禁用大答复有效载荷数据的截断。
  • --format ``

    • 默认%F{blue}%t%f %F{cyan}(Connection: %o:%i)%f %F{yellow}%l%f %F{red}%T %c%f %F{white}%n%f %F{green}%Q{Request:}%f%q%F{green}%R{Response:}%f%r)

指定终端输出的格式。您可以通过将其用大括号括起来,例如%Q{<arg>},在格式“动词”之后立即指定参数。

如果指定--format,则还要指定format作为--collect选项的值。

--format支持以下动词:

  • %n:名称空间

  • %l:延迟

  • %t:时间。您可以选择使用 Go 编程语言的time formatting指定日期布局。 Go 使用Mon Jan 2 15:04:05 MST 2006作为参考时间。您必须使用参考时间指定时间格式。因此,如果要以yyyy-mm-dd hh:mm格式打印日期,则应指定%t{2006-01-02 15:04}。有关更多信息,请参阅 Go time formatting文档。

  • %T:操作时间

  • %c:命令

  • %o:连接数

  • %i:请求 ID

  • %q:请求。您可以在 JSON 结构中最终指定一个以点分隔的字段,例如%q{command_args.documents}

  • %r:回复。您可以在 JSON 结构中最终指定一个以点分隔的字段,例如%q{command_args.documents}

  • %Q{<arg>}:显示请求数据时显示<arg>

  • %R{<arg>}:显示响应数据时显示<arg>

此外,--format支持以下开始/结束 ANSI 转义序列:

  • %B/%b:粗体

  • %U/%u:下划线

  • %S/%s:出色

  • %F/%f:文本颜色(必填 arg-单词或数字,8 色)

  • %K/%k:背景色(必填 arg –与%F /%f 相同)

  • --no-colors ``

  • -f <path>

    • 指定monitor应该读取以生成播放文件的 pcap 文件的路径。

使用-f作为使用-i捕获网络流量的替代方法。您必须指定-f-i *。如果同时包含两个选项,则 mongoreplay 监控器 会产生错误。

  • -b <number>

    • 用于将单独的流合并在一起的堆大小。
  • --expr <filter expression> , -e <filter expression>

例如,要捕获来自端口 27017 上运行的 MongoDB 实例的流量,您可以指定-e 'port 27017'

  • -i <interface>
    • 指定monitor应该侦听以捕获网络流量的网络接口。

-e一起使用。

使用-i替代使用-i读取现有的 pcap 文件。您必须指定-f-i *。如果同时包含两个选项,则 mongoreplay 监控器 会产生错误。

  • --paired ``

    • 指定后,monitor为每个请求/答复对记录输出一行。
  • --gzip <boolean>

    • 如果指定,monitor将使用 gzip 解压缩播放文件。
  • --playback-file <path> , -p <path>

    • 指定从中读取播放文件的路径。

See

Use monitor举例说明如何将mongoreplaymonitor命令一起使用。

mongoreplay 报告格式

当使用--report选项运行时,monitorplay可以基于播放文件生成报告。

Sample Record

以下是 JSON 格式的monitor报告的示例记录:

{
   "order" : 1,
   "op" : "op_msg",
   "command" : "aggregate",
   "ns" : "test",
   "request_data" : {
      "sections" : [
         {
            "payload" : {
               "$db" : "test",
               "aggregate" : "restaurants",
               "cursor" : {

               },
               "pipeline" : [
                  {
                     "$match" : {
                        "borough" : "Manhattan"
                     }
                  },
                  {
                     "$group" : {
                        "_id" : "$cuisine"
                     }
                  }
               ]
            },
            "payloadType" : 0
         }
      ]
   },
   "connection_num" : 0,
   "seen" : "2018-11-15T16:02:08.219652-05:00",
   "request_id" : 12
}

Fields

mongoreplay报告可以包含以下字段:

  • order

    • 单调递增的键,指示记录和播放操作的 Sequences。这可以用于重构在连接上执行的一系列操作的 Sequences,因为它们在报告文件中出现的 Sequences 可能与播放 Sequences 不匹配。
  • op

    • 请求所代表的操作类型:即“查询”,“插入”,“命令”,“ getmore”。
  • command

    • 执行的数据库命令的名称,例如isMastergetLastError。对于非命令的操作(例如查询和插入),此字段保留为空白。
  • ns

  • request_data

    • 操作的有效负载。
  • 查询操作:request_data包含已发出的实际查询。

  • 插入操作:request_data包含要插入的文档。

  • 更新操作:request_data包含查询 selectors 和更新修饰符。

  • reply_data

    • 回复请求的有效负载。
  • nreturned

    • 作为操作结果返回的文档数。
  • played_at

    • play命令执行操作的时间。
  • play_at

    • play命令应该执行该操作的时间。
  • playbacklag_us

    • played_atplay_at之间的时间差(以微秒为单位)。较高的值通常表示目标服务器无法跟上根据回放文件执行请求的速率。
  • connection_num

    • 标识执行请求的连接的键。在同一连接上执行的所有请求/回复的connection_num值都相同。

connection_num值与服务器端记录的连接 ID 不匹配。

  • latency_us

    • Client 端发送请求与接收到服务器响应之间的时间差(以微秒为单位)。
  • errors

    • 列出从服务器返回的所有错误。
  • msg

    • 列出从服务器返回的错误消息。
  • seen

    • 最初捕获操作的时间。
  • request_id

    • MongoDB 操作的 ID。请求操作的request_id与相应回复的response_id相同。

使用--format 输出格式

monitorplay输出到终端,或者在与--report(即monitor --reportplay --report)一起运行时,输出到文件。

使用--collect(monitor --collectplay --collect)选项来指定输出的格式:

  • --collect json产生 JSON 输出,

  • --collect format根据--format选项为monitorplay指定的格式输出数据。

Examples

Use record

使用记录捕获 TCP 数据

要创建流量记录,请使用record命令。以下操作记录通过eth0网络接口上的端口27017的流量,并将捕获的流量写入~/recordings/recording.bson

mongoreplay record -i eth0 -e "port 27017" -p ~/recordings/recording.bson

产生的回放文件包含在另一个系统上重新执行工作负载所需的所有内容。

根据现有的 pcap 数据记录播放文件

如果您不想使用mongoreplay捕获流量,则可以使用tcpdump之类的 Util 捕获流量,然后从静态 pcap 文件创建mongoreplay记录。

Warning

连接到可信源时仅使用 root 特权。

以下操作使用tcpdump通过eth0网络接口上的端口27017捕获流量,并将捕获的数据写入名为traffic.pcap的 pcap 文件中:

sudo tcpdump -B $((100*1024)) -i eth0 -n "port 27017" -w traffic.pcap

要创建mongoreplay播放文件,可以将record-f选项一起使用,以指定从中创建播放文件的 pcap 文件,如下所示:

mongoreplay record -f traffic.pcap -p ~/recordings/playback.bson

产生的回放文件包含在另一个系统上重新执行工作负载所需的所有内容。

Use play

对目标主机执行播放文件

play获取一个播放文件,并针对mongodb://example.com:27018主机执行记录的操作。由于mongod强制执行身份验证,因此为--host指定的connection string还包括用户名,密码和身份验证数据库,以便mongoreplay可以写入数据库。

mongoreplay play -p ~/recordings/recording.bson --host mongodb://username:[email protected]:27018/admin

默认情况下,~bin.play以记录速率执行播放文件。 --speed可让您修改播放速度。例如,以下操作以记录速度的两倍执行recording.bson中的操作:

mongoreplay play -p ~/recordings/recording.bson --speed=2.0 --host mongodb://username:[email protected]:27018/admin

有关回放期间执行性能的日志 Metrics

play可以生成一个报告,其中包含有关回放期间执行的每个操作的性能的详细 Metrics。

以下示例针对mongodb://example.com:27017主机执行回放,并生成写入~/reports/playback-report.json的 JSON 报告

mongoreplay play -p ~/recordings/recording.bson --report ~/reports/playback-report.json --collect json --host mongodb://example.com:27017

play报告的内容类似于:

{
   "order" : 0,
   "op" : "op_msg",
   "command" : "isMaster",
   "ns" : "test",
   "request_data" : {
      "sections" : [
         {
            "payload" : {
               "$db" : "test",
               "forShell" : 1,
               "isMaster" : 1
            },
            "payloadType" : 0
         }
      ]
   },
   "reply_data" : {
      "sections" : [
         {
            "payload" : {
               "ismaster" : true,
               "localTime" : {
                  "$date" : "2018-11-15T21:17:37.070Z"
               },
               "logicalSessionTimeoutMinutes" : 30,
               "maxBsonObjectSize" : 16777216,
               "maxMessageSizeBytes" : 48000000,
               "maxWireVersion" : 6,
               "maxWriteBatchSize" : 100000,
               "minWireVersion" : 0,
               "ok" : 1,
               "readOnly" : false
            },
            "payloadType" : 0
         }
      ]
   },
   "played_at" : "2018-11-15T16:17:37.070406-05:00",
   "play_at" : "2018-11-15T16:17:37.070301-05:00",
   "playbacklag_us" : 105,
   "connection_num" : 1,
   "latency_us" : 167,
   "seen" : "2018-11-15T21:13:48.047567Z",
   "request_id" : 22
}
{
   "order" : 2,
   "op" : "op_msg",
   "command" : "listCollections",
   "ns" : "test",
   "request_data" : {
      "sections" : [
         {
            "payload" : {
               "$db" : "test",
               "filter" : {

               },
               "listCollections" : 1
            },
            "payloadType" : 0
         }
      ]
   },
   "reply_data" : {
      "sections" : [
         {
            "payload" : {
               "cursor" : {
                  "firstBatch" : [
                     {
                        "idIndex" : {
                           "key" : {
                              "_id" : 1
                           },
                           "name" : "_id_",
                           "ns" : "test.foo",
                           "v" : 2
                        },
                        "info" : {
                           "readOnly" : false,
                           "uuid" : {
                              "$binary" : "b99bVslUS0+mZwMMZDxqwQ==",
                              "$type" : "04"
                           }
                        },
                        "name" : "foo",
                        "options" : {

                        },
                        "type" : "collection"
                     }
                  ],
                  "id" : {
                     "$numberLong" : "0"
                  },
                  "ns" : "test.$cmd.listCollections"
               },
               "ok" : 1
            },
            "payloadType" : 0
         }
      ]
   },
   "nreturned" : 1,
   "played_at" : "2018-11-15T16:17:38.192447-05:00",
   "play_at" : "2018-11-15T16:17:38.188742-05:00",
   "playbacklag_us" : 3705,
   "connection_num" : 1,
   "latency_us" : 739,
   "seen" : "2018-11-15T21:13:49.166008Z",
   "request_id" : 23
}
{
   "order" : 4,
   "op" : "op_msg",
   "command" : "isMaster",
   "ns" : "test",
   "request_data" : {
      "sections" : [
         {
            "payload" : {
               "$db" : "test",
               "forShell" : 1,
               "isMaster" : 1
            },
            "payloadType" : 0
         }
      ]
   },
   "reply_data" : {
      "sections" : [
         {
            "payload" : {
               "ismaster" : true,
               "localTime" : {
                  "$date" : "2018-11-15T21:17:38.193Z"
               },
               "logicalSessionTimeoutMinutes" : 30,
               "maxBsonObjectSize" : 16777216,
               "maxMessageSizeBytes" : 48000000,
               "maxWireVersion" : 6,
               "maxWriteBatchSize" : 100000,
               "minWireVersion" : 0,
               "ok" : 1,
               "readOnly" : false
            },
            "payloadType" : 0
         }
      ]
   },
   "played_at" : "2018-11-15T16:17:38.193707-05:00",
   "play_at" : "2018-11-15T16:17:38.189618-05:00",
   "playbacklag_us" : 4089,
   "connection_num" : 1,
   "latency_us" : 282,
   "seen" : "2018-11-15T21:13:49.166884Z",
   "request_id" : 24
}
{
   "order" : 6,
   "op" : "op_msg",
   "command" : "aggregate",
   "ns" : "test",
   "request_data" : {
      "sections" : [
         {
            "payload" : {
               "$db" : "test",
               "aggregate" : "restaurants",
               "cursor" : {

               },
               "pipeline" : [
                  {
                     "$match" : {
                        "borough" : "Manhattan"
                     }
                  },
                  {
                     "$group" : {
                        "_id" : "$cuisine"
                     }
                  }
               ]
            },
            "payloadType" : 0
         }
      ]
   },
   "reply_data" : {
      "sections" : [
         {
            "payload" : {
               "cursor" : {
                  "firstBatch" : [ ],
                  "id" : {
                     "$numberLong" : "0"
                  },
                  "ns" : "test.restaurants"
               },
               "ok" : 1
            },
            "payloadType" : 0
         }
      ]
   },
   "played_at" : "2018-11-15T16:17:43.201298-05:00",
   "play_at" : "2018-11-15T16:17:43.198242-05:00",
   "playbacklag_us" : 3056,
   "connection_num" : 1,
   "latency_us" : 988,
   "seen" : "2018-11-15T21:13:54.175508Z",
   "request_id" : 25
}

有关每个字段的描述,请参考mongoreplay 报告格式

Use monitor

检查记录的操作

monitor可以基于播放文件的内容创建报告。 monitor的报告包含所有操作以及有关每个操作执行的一些元数据。

以下操作使用monitor根据~/recordings目录中recording.bson回放文件的内容创建 JSON 报告,并将报告写入~/reports/monitoring-report.json

mongoreplay monitor -p ~/recordings/recording.bson --report ~/reports/monitoring-report.json --collect json

报告内容类似于:

{
   "order" : 0,
   "op" : "op_msg",
   "command" : "isMaster",
   "ns" : "test",
   "request_data" : {
      "sections" : [
         {
            "payload" : {
               "$db" : "test",
               "forShell" : 1,
               "isMaster" : 1
            },
            "payloadType" : 0
         }
      ]
   },
   "connection_num" : 0,
   "seen" : "2018-11-15T21:13:48.047567Z",
   "request_id" : 22
}
{
   "order" : 1,
   "op" : "op_msg",
   "command" : "reply",
   "reply_data" : {
      "sections" : [
         {
            "payload" : {
               "ismaster" : true,
               "localTime" : {
                  "$date" : "2018-11-15T21:13:48.047Z"
               },
               "logicalSessionTimeoutMinutes" : 30,
               "maxBsonObjectSize" : 16777216,
               "maxMessageSizeBytes" : 48000000,
               "maxWireVersion" : 6,
               "maxWriteBatchSize" : 100000,
               "minWireVersion" : 0,
               "ok" : 1,
               "readOnly" : false
            },
            "payloadType" : 0
         }
      ]
   },
   "connection_num" : 0,
   "latency_us" : 179,
   "seen" : "2018-11-15T21:13:48.047746Z",
   "request_id" : 22
}
{
   "order" : 2,
   "op" : "op_msg",
   "command" : "listCollections",
   "ns" : "test",
   "request_data" : {
      "sections" : [
         {
            "payload" : {
               "$db" : "test",
               "filter" : {

               },
               "listCollections" : 1
            },
            "payloadType" : 0
         }
      ]
   },
   "connection_num" : 0,
   "seen" : "2018-11-15T21:13:49.166008Z",
   "request_id" : 23
}

有关每个字段的描述,请参考mongoreplay 报告格式

检查 MongoDB 实时流量

monitor还可以检查实时流量,还可以根据观察到的操作创建报告。

要实时监视终端中的流量,请省略--report选项,如下所示:

mongoreplay monitor -i eth0 -e 'port 27017' --collect json

(可选)您可以基于使用monitor观察到的操作来创建报告。以下示例根据通过eth0网络接口上通过端口27017的流量创建写入~/reports/monitor-live.json的 JSON 报告:

mongoreplay monitor -i eth0 -e 'port 27017' --report ~/reports/monitor-live.json --collect json