gpt4 book ai didi

mongodb - 是否可以提高 Mongoexport 的速度?

转载 作者:IT老高 更新时间:2023-10-28 13:35:02 24 4
gpt4 key购买 nike

我有一个 1.3 亿行的 MongoDB 3.6.2.0 集合。它有几个简单的字段和 2 个带有嵌套 JSON 文档的字段。数据以压缩格式 (zlib) 存储。

我需要尽快将其中一个嵌入字段导出为 JSON 格式。但是,mongoexport 将永远存在。运行 12 小时后,它只处理了 5.5% 的数据,这对我来说太慢了。

CPU 不忙。 Mongoexport 似乎是单线程的。

我正在使用的导出命令:

mongoexport -c places --fields API \
--uri mongodb://user:pass@hostIP:hostPort/maps?authSource=admin \
-o D:\APIRecords.json

实际上是 getMore 命令,它在后台运行的速度非常慢:

2018-05-02T17:59:35.605-0700 I COMMAND  [conn289] command maps.places command: getMore { getMore: 14338659261, collection: "places", $db: "maps" } originatingCommand: { find: "places", filter: {}, sort: {}, projection: { _id: 1, API: 1 }, skip: 0, snapshot: true, $readPreference: { mode: "secondaryPreferred" }, $db: "maps" } planSummary: COLLSCAN cursorid:14338659261 keysExamined:0 docsExamined:5369 numYields:1337 nreturned:5369 reslen:16773797 locks:{ Global: { acquireCount: { r: 2676 } }, Database: { acquireCount: { r: 1338 } }, Collection: { acquireCount: { r: 1338 } } } protocol:op_query 22796ms

我尝试在像这样的单独进程中使用 --SKIP--LIMIT 选项运行多个命令

mongoexport -c places --SKIP 10000000 --LIMIT 10000000 --fields API \
--uri mongodb://user:pass@hostIP:hostPort/maps?authSource=admin \
-o D:\APIRecords.json
mongoexport -c places --SKIP 20000000 --LIMIT 10000000 --fields API \
--uri mongodb://user:pass@hostIP:hostPort/maps?authSource=admin \
-o D:\APIRecords.json

等等。但是我无法完成等到第一个非零 SKIP 的命令甚至开始!

我也试过 --forceTableScan 选项,没有任何区别。

我在 places 表上没有索引。

我的存储配置:

journal.enabled: false
wiredTiger.collectionConfig.blockCompressor: zlib

收藏统计:

'ns': 'maps.places',
'size': 2360965435671,
'count': 130084054,
'avgObjSize': 18149,
'storageSize': 585095348224.0

我的服务器规范:

Windows Server 2012 R2 x64
10Gb RAM 4TB HDD 6 cores Xeon 2.2Ghz

我进行了一项测试,SSD 的读取吞吐量与 HDD 相同。

我的问题:

为什么阅读这么慢?有没有其他人遇到过同样的问题?您能给我一些关于如何加快数据转储速度的提示吗?

更新

我将数据库移至快速 NVME SSD 驱动器,我想现在我可以更清楚地表达我对 MongoDB 读取性能的担忧。

为什么这个命令,它试图找到一 block 没有特定字段的文档:

2018-05-05T07:20:46.215+0000 I COMMAND  [conn704] command maps.places command: find { find: "places", filter: { HTML: { $exists: false }, API.url: { $exists: true } }, skip: 9990, limit: 1600, lsid: { id: UUID("ddb8b02c-6481-45b9-9f84-cbafa586dbbf") }, $readPreference: { mode: "secondaryPreferred" }, $db: "maps" } planSummary: COLLSCAN cursorid:15881327065 keysExamined:0 docsExamined:482851 numYields:10857 nreturned:101 reslen:322532 locks:{ Global: { acquireCount: { r: 21716 } }, Database: { acquireCount: { r: 10858 } }, Collection: { acquireCount: { r: 10858 } } } protocol:op_query 177040ms

仅在快速闪存驱动器上产生 50Mb/秒的读取压力?这显然是单线程随机(分散)读取的性能。而我刚刚证明该驱动器可以轻松实现 1Gb/秒的读/写吞吐量。

就 Mongo 内部而言,按顺序读取 BSON 文件并获得 20 倍的扫描速度提升不是更明智吗? (而且,由于我的 block 是 zlib 压缩的,并且服务器有 16 个内核,最好在一个或多个辅助线程中解码获取的 block ?)而不是一个又一个文档地迭代 BSON 文档。

我也可以确认,即使我没有指定任何查询过滤器,并且显然想要迭代整个集合,BSON 文件的快速顺序读取也没有发生。

最佳答案

限制导出性能的因素有很多。

  • 与可用内存相比,数据大小相对较大:~2 TB 与 ~5 GB WiredTiger 缓存(如果设置为默认值)。那是:
    • 整个 WiredTiger 缓存充其量只能包含 ~0.22% 的集合,实际上它很可能比这少得多,因为缓存会包含来自其他集合和索引的数据。
    • 这意味着 WiredTiger 需要非常频繁地从磁盘中获取数据,同时清除缓存的当前内容。如果副本集被积极使用,这将意味着从缓存中清除“脏”数据并将它们持久化到磁盘,这需要时间。
    • 请注意,WiredTiger 缓存中的文档未压缩。
  • 该集合包含大型文档,您只需要其中的一部分。这意味着处理文件需要额外的时间。
  • 集合使用 zlib 压缩,这意味着必须使用额外的时间来解压缩文档。
  • readPreference 是 secondaryPreferred,这意味着它将尝试从辅助节点读取。如果副本集正在被主动写入,则辅助节点上的 oplog 应用操作将阻塞读取器。这将进一步增加延迟。

一个可能的改进是,如果这是您经常执行的操作,请在相关字段上创建索引并使用 covered query 导出它。可以提高性能,因为索引会小于完整文档。

编辑:在这种情况下并行运行 mongoexport 可能会有所帮助:

根据提供的其他信息,我进行了一项测试,似乎在一定程度上缓解了这个问题。

似乎并行运行 mongoexport,其中每个处理集合子集的 mongoexport 可能能够加快导出速度。

为此,请根据您计划运行的 mongoexport 进程的数量划分 _id 命名空间。

例如,如果我有 200,000 个文档,从 _id:0_id:199,999 并使用 2 个 mongoexport 进程:

mongoexport -q '{"_id":{"$gte":0, "$lt":100000}}' -d test -c test > out1.json &
mongoexport -q '{"_id":{"$gte":100000, "$lt":200000}}' -d test -c test > out2.json &

在上面的例子中,两个 mongoexport 进程各自处理一半的集合。

使用 1 个流程、2 个流程、4 个流程和 8 个流程测试此工作流程我到达以下时间:

使用 1 个进程:

real    0m32.720s
user 0m33.900s
sys 0m0.540s

2 个进程:

real    0m16.528s
user 0m17.068s
sys 0m0.300s

4 个进程:

real    0m8.441s
user 0m8.644s
sys 0m0.140s

8 个进程:

real    0m5.069s
user 0m4.520s
sys 0m0.364s

根据可用资源,并行运行 8 个 mongoexport 进程似乎可以将进程加速约 6 倍。这是在一台 8 核的机器上测试的。

注意:halfer 的回答在思想上是相似的,虽然这个回答基本上是想看看并行调用 mongoexport 是否有任何好处。

关于mongodb - 是否可以提高 Mongoexport 的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50145668/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com