Таким образом, просто нецелесообразно отправлять 200 000 запросов одновременно в вашу базу данных. В любом случае ваша база данных не может работать с несколькими запросами одновременно, поэтому все, что вы делаете, отправляя столько запросов одновременно, просто вызывает огромное количество пиковой нагрузки на память.
С небольшим тестированием вы бы приблизительно выяснили, сколько одновременных запросов все еще эффективно, и это полностью зависит от вашей базы данных и ее конфигурации. Большой железный сервер баз данных может иметь доступ к большому количеству процессоров / потоков и, возможно, даже к некоторым эффективным разделам диска и иметь возможность выполнять несколько запросов одновременно. Меньшая конфигурация может ничего не получить после нескольких запросов в полете за один раз.
Здесь есть несколько десятков опций в stackoverflow и в других местах для выполнения асинхронного вызова функции при обработке массива и выполнения его так, чтобы только N запросов находятся в полете одновременно. Это, вероятно, общая концепция, которую вы хотите здесь. В библиотеках, таких как Bluebird и Asyn c -Promises, есть встроенные функции для управления одновременным доступом.
Один из моих простых фаворитов (просто функцию, которую вы можете скопировать) называется mapConcurrent()
. Вы передаете ему массив, максимальное количество запросов, которые вы хотите выполнить за один раз, и функцию возврата обещания, которую она будет вызывать для каждого элемента в массиве.
Вы запускаете эксперименты с вашей конфигурацией, чтобы увидеть, что оптимальное значение для maxConcurrent - это (подсказка, вероятно, это довольно небольшое число, например, меньше 10).
// takes an array of items and a function that returns a promise
function mapConcurrent(items, maxConcurrent, fn) {
let index = 0;
let inFlightCntr = 0;
let doneCntr = 0;
let results = new Array(items.length);
let stop = false;
return new Promise(function(resolve, reject) {
function runNext() {
let i = index;
++inFlightCntr;
fn(items[index], index++).then(function(val) {
++doneCntr;
--inFlightCntr;
results[i] = val;
run();
}, function(err) {
// set flag so we don't launch any more requests
stop = true;
reject(err);
});
}
function run() {
// launch as many as we're allowed to
while (!stop && inflightCntr < maxConcurrent && index < items.length) {
runNext();
}
// if all are done, then resolve parent promise with results
if (doneCntr === items.length) {
resolve(results);
}
}
run();
});
}
В этом ответе упоминаются некоторые другие параметры Пакетная асинхронная операция .