У меня есть коллекция MongoDB 3.6.2.0 на 130 миллионов строк. Он имеет несколько простых полей и 2 поля с вложенными документами JSON. Данные хранятся в сжатом формате (zlib).
Мне нужно как можно быстрее экспортировать одно из встроенных полей в формат JSON. Тем не менее, Монгоэкспорт берет навсегда. После 12 часов работы он обработал только 5,5% данных, что для меня слишком медленно.
Процессор не занят. Монгоэкспорт кажется однопоточным.
Команда экспорта, которую я использую:
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
, которая не имела никакого значения.
У меня нет индексов на таблице мест.
Моя конфигурация хранилища:
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.
Мой вопрос:
Почему чтение так медленно? Кто-нибудь еще испытывал такую же проблему? Можете ли вы дать мне какие-либо советы о том, как ускорить дамп данных?
Обновление
Я переместил БД на быстрые SSM-накопители NVME, и теперь я думаю, что могу более четко изложить свои опасения по поводу производительности чтения 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
дает только скорость чтения 50 Мб / с на флешку? Это явно производительность однопоточного случайного (рассеянного) чтения. Принимая во внимание, что я только что доказал, что этот накопитель обеспечивает скорость чтения / записи 1 Гбит / с.
Если говорить о внутренностях Монго, не было бы разумнее читать файл BSON в последовательном порядке и получить 20-кратное улучшение скорости сканирования? (И, поскольку мои блоки сжаты zlib, а сервер имеет 16 ядер, лучше декодировать извлеченные фрагменты в одном или нескольких вспомогательных потоках?) Вместо итерации документа BSON за документом.
Я также могу подтвердить, что даже если я не указываю никаких фильтров запросов и явно хочу повторить ВСЮ коллекцию, быстрого последовательного чтения файла BSON не происходит.