Как улучшить производительность вставки MongoDB

Результат:

Если вы работаете с набором данных, который является отказоустойчивым, или выполняете одноразовый процесс, который вы можете проверить, то может помочь изменение WriteAcknowledge на Unacknowledged.

Кроме того, массовые операции IsOrdered по умолчанию, о которых я не знал. Если задать для этого параметра значение "Ложь", операция будет выполняться массово, иначе она будет действовать как один поток обновлений.


MongoDB 3.0 / WiredTiger / C# Драйвер

У меня есть коллекция с 147 000 000 документов, из которых я обновляю каждую секунду (надеюсь) ок. 3000 документов.

Вот пример обновления:

"query" : {
    "_id" : BinData(0,"UKnZwG54kOpT4q9CVWbf4zvdU223lrE5w/uIzXZcObQiAAAA")
},
"updateobj" : {
    "$set" : {
        "b" : BinData(0,"D8u1Sk/fDES4IkipZzme7j2qJ4oWjlT3hvLiAilcIhU="),
        "s" : true
    }
}

Это типичное обновление, в котором мои требования должны быть вставлены со скоростью 3000 в секунду.

К сожалению, они занимают вдвое больше времени, например, последнее обновление было для 1723 документов и заняло 1061 мс.

Коллекция имеет только индекс _id, никаких других индексов, а средний размер документа для коллекции составляет 244 байта, без ограничений.

Сервер имеет 64 ГБ памяти, 12 потоков. Производительность вставки превосходна при меньших размерах коллекций, скажем, около 50 миллионов, но после 80 миллионов действительно начинает падать.

Может быть потому, что весь набор не сидит в памяти? База данных поддерживается твердотельными накопителями RAID0, поэтому производительность ввода-вывода не должна становиться узким местом, и если это так, то это должно было показать это в начале?

Буду признателен за некоторые рекомендации, так как я уверен, что MongoDB может удовлетворить мои довольно скудные требования по сравнению с некоторыми приложениями, в которых он используется. В базе данных нет существенной скорости чтения, поэтому Sharding не улучшит ситуацию, хотя, возможно, я ошибаюсь.

В любом случае, текущая скорость вставки недостаточно хороша.

Обновление: вот объяснение () только для запроса...

"queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "Collection",
    "indexFilterSet" : false,
    "parsedQuery" : {
        "_id" : {
            "$eq" : { "$binary" : "SxHHwTMEaOmSc9dD4ng/7ILty0Zu0qX38V81osVqWkAAAAAA", "$type" : "00" }
        }
    },
    "winningPlan" : {
        "stage" : "IDHACK"
    },
    "rejectedPlans" : []
},
"executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 1,
    "executionTimeMillis" : 1,
    "totalKeysExamined" : 1,
    "totalDocsExamined" : 1,
    "executionStages" : {
        "stage" : "IDHACK",
        "nReturned" : 1,
        "executionTimeMillisEstimate" : 0,
        "works" : 2,
        "advanced" : 1,
        "needTime" : 0,
        "needFetch" : 0,
        "saveState" : 0,
        "restoreState" : 0,
        "isEOF" : 1,
        "invalidates" : 0,
        "keysExamined" : 1,
        "docsExamined" : 1
    },
    "allPlansExecution" : []
},

Сам запрос выполняется очень быстро, и операция обновления занимает около 25-ти миллисекунд, они отправляются в Mongo с помощью BulkWriter: await m_Collection.BulkWriteAsync(updates);

4 ответа

Решение

Вы можете попытаться изменить уровни записи. Очевидно, что это сопряжено с риском, поскольку вы не сможете отследить какую-либо ошибку записи, но, по крайней мере, вы все равно сможете фиксировать сетевые ошибки. Поскольку MongoDB группирует операции массовой вставки в группы по 1000, это должно ускорить процесс.

W по умолчанию равно 1:

Когда вы измените его на 0:

Если вас не беспокоит порядок элементов, вы можете получить некоторую скорость, вызывая неупорядоченную массовую операцию

await m_Collection.BulkWriteAsync(updates, new BulkWriteOptions() { IsOrdered = false });

С неупорядоченным списком операций MongoDB может параллельно выполнять операции записи в списке и в любом порядке. Ссылка на сайт

Отмеченный ответ здесь хорош. Я хочу добавить дополнительный код, чтобы помочь другим, кто использует InsertMany вместо BulkWriteAsync воспользоваться IsOrdered = false быстрее

    m_Collection.InsertMany(listOfDocument, new InsertManyOptions() { IsOrdered = false });

"В базе данных нет существенной скорости чтения, поэтому Sharding не улучшит ситуацию, хотя, возможно, я ошибаюсь".

Обновление включает в себя чтение. он также обнаружил, что оставил _id - так что, возможно, sharding может быть полезным, если не v полезным

Мы перешли на Кассандру, потому что Монго плохо масштабируется. Если вы говорите, что после 80M вы заметили снижение производительности, это легко связано с памятью. Я больше разбираюсь в базах данных SQL, но я бы не сказал, что 25 мс для обновления неключевых полей впечатляют. Я подозреваю, что подобное обновление будет работать лучше на Oracle, MySql, ...

Другие вопросы по тегам