Ana*_*eev 5 performance mongodb
我有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
Run Code Online (Sandbox Code Playgroud)
实际上,它是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
Run Code Online (Sandbox Code Playgroud)
我试图在这样的单独进程中使用--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
Run Code Online (Sandbox Code Playgroud)
等等。但是直到第一个非零SKIP的命令启动,我还是无法完成等待!
我也尝试了--forceTableScan选项,但没有任何区别。
我在场所表上没有索引。
我的存储配置:
journal.enabled: false
wiredTiger.collectionConfig.blockCompressor: zlib
Run Code Online (Sandbox Code Playgroud)
收集统计信息:
'ns': 'maps.places',
'size': 2360965435671,
'count': 130084054,
'avgObjSize': 18149,
'storageSize': 585095348224.0
Run Code Online (Sandbox Code Playgroud)
我的服务器规格:
Windows Server 2012 R2 x64
10Gb RAM 4TB HDD 6 cores Xeon 2.2Ghz
Run Code Online (Sandbox Code Playgroud)
我已经进行了一项测试,使用SSD时,其读取吞吐量与使用HDD时相同。
我的问题:
为什么阅读这么慢?还有其他人遇到过同样的问题吗?您能给我一些有关如何加快数据转储的提示吗?
我将数据库移到了快速的NVME SSD驱动器上,我想现在可以更清楚地说明我对MongoDB读取性能的担忧。
为什么执行此命令,以查找没有特定字段的大量文档:
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
Run Code Online (Sandbox Code Playgroud)
仅对快速闪存驱动器产生50Mb / sec的读取压力?显然,这是单线程随机(分散)读取的性能。而我刚刚证明该驱动器可以轻松实现1Gb /秒的读取/写入吞吐量。
就Mongo内部而言,按顺序读取BSON文件并提高20倍的扫描速度是否明智?(而且,由于我的块是zlib压缩的,并且服务器具有16个内核,因此更好地在一个或几个辅助线程中解码获取的块吗?)而不是在一个文档之间迭代BSON文档。
我也可以确认,即使当我没有指定任何查询过滤器,并且显然要迭代整个IREIRE集合时,也不会发生快速顺序读取BSON文件的情况。
限制出口业绩的因素有很多。
secondaryPreferred,这意味着它将尝试从辅助读取。如果正在积极写入副本集,则辅助节点上的 oplog 应用操作将阻止读取器。这将进一步增加延迟。一种可能的改进是,如果这是您经常执行的操作,则在相关字段上创建索引并使用覆盖查询将其导出可以提高性能,因为索引将小于完整文档。
编辑:mongoexport在这种情况下并行运行可能会有所帮助:
根据提供的其他信息,我进行了一项测试,似乎在某种程度上缓解了这个问题。
似乎mongoexport并行运行,其中每个mongoexport处理集合的子集可能能够加速导出。
为此,请_id根据mongoexport您计划运行的进程数划分对应的命名空间。
例如,如果我有 200,000 个文档,从_id:0to开始_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 &
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,两个mongoexport进程各处理一半的集合。
使用 1 个流程、2 个流程、4 个流程和 8 个流程测试此工作流程,我得出以下时间:
使用1个过程:
real 0m32.720s
user 0m33.900s
sys 0m0.540s
Run Code Online (Sandbox Code Playgroud)
2个过程:
real 0m16.528s
user 0m17.068s
sys 0m0.300s
Run Code Online (Sandbox Code Playgroud)
4道工序:
real 0m8.441s
user 0m8.644s
sys 0m0.140s
Run Code Online (Sandbox Code Playgroud)
8道工序:
real 0m5.069s
user 0m4.520s
sys 0m0.364s
Run Code Online (Sandbox Code Playgroud)
根据可用资源,mongoexport并行运行 8 个进程似乎可以将进程加速约 6 倍。这是在一台 8 核的机器上测试的。
注意:halfer 的答案在想法上是相似的,尽管这个答案基本上是试图看看mongoexport并行调用是否有任何好处。
我不使用 Mongo,但可以使用一个常见的技巧:制作一个简单的应用程序,可以有效地按顺序查询所有数据,过滤数据并以您想要的格式保存。
如果您需要以复杂的格式保存并且没有库可以使用它(我真的很怀疑),那么读取全部、过滤、将其放回到临时集合中、完全导出该集合、删除可能仍然有效。临时收集。
| 归档时间: |
|
| 查看次数: |
2404 次 |
| 最近记录: |