在Node.js中限制对Cassandra DB的并行请求数

时间:2018-11-20 10:22:39

标签: node.js asynchronous cassandra promise

我目前正在解析文件并获取其数据,以便将它们压入数据库。为此,我创建了一个查询数组,并通过循环执行它们。

问题是我仅限于2048个并行请求。

这是我编写的代码:

index.js =>

const ImportClient = require("./scripts/import_client_leasing")
const InsertDb = require("./scripts/insertDb")

const cassandra = require('cassandra-driver');
const databaseConfig = require('./config/database.json');


const authProvider = new cassandra.auth.PlainTextAuthProvider(databaseConfig.cassandra.username, databaseConfig.cassandra.password);

const db = new cassandra.Client({
    contactPoints: databaseConfig.cassandra.contactPoints,
    authProvider: authProvider
});

ImportClient.clientLeasingImport().then(queries => { // this function parse the data and return an array of query
    return InsertDb.Clients(db, queries);    //inserting in the database returns something when all the promises are done
}).then(result => {
    return db.shutdown(function (err, result) {});
}).then(result => {
    console.log(result);
}).catch(error => {
    console.log(error)
});

insertDb.js =>

module.exports = {
    Clients: function (db, queries) {
        DB = db;
        return insertClients(queries);
    }
}

function insertClients(queries) {
    return new Promise((resolve, reject) => {
        let promisesArray = [];

        for (let i = 0; i < queries.length; i++) {
            promisesArray.push(new Promise(function (resolve, reject) {
                DB.execute(queries[i], function (err, result) {
                    if (err) {
                        reject(err)
                    } else {
                        resolve("success");
                    }
                });
            }));
        }
        Promise.all(promisesArray).then((result) => {
            resolve("success");
        }).catch((error) => {
            resolve("error");
        });
    });
}

我尝试了多种方法,例如添加了一个等待函数,该函数每隔x秒在我的for循环中设置一个timout(但由于我已经在承诺中而没有用),我也尝试了p-queuep-limit,但似乎也不起作用。

我有点被困在这里,我想我缺少了一些琐碎的东西,但我并没有真正得到什么。

谢谢

2 个答案:

答案 0 :(得分:1)

在并行提交多个请求时(execute()函数使用异步执行),最终将在以下不同级别之一排队:在驱动程序端,网络堆栈或服务器端。过多的排队会影响每个操作完成的总时间。您应该随时限制并发请求的数量(也称为并发级别),以实现高吞吐量和低延迟。

考虑在代码中实现它时,您应该考虑使用并发级别作为上限来启动固定数量的异步执行,并且只有在该上限内完成执行后才添加新操作。

下面是一个示例,该示例说明在循环中处理项目时如何限制并发执行的数量:https://github.com/datastax/nodejs-driver/blob/master/examples/concurrent-executions/execute-in-loop.js

简而言之:

// Launch in parallel n async operations (n being the concurrency level)
for (let i = 0; i < concurrencyLevel; i++) {
  promises[i] = executeOneAtATime();
}

// ...
async function executeOneAtATime() {
  // ...
  // Execute queries asynchronously in sequence
  while (counter++ < totalLength) {;
    await client.execute(query, params, options);
  }
}

答案 1 :(得分:0)

好,所以我找到了一种解决方法来实现我的目标。 我将所有查询写在文件中

$sets

然后我就用

const fs = require('fs')
fs.appendFileSync('my_file.cql', queries[i] + "\n");

将所有查询插入cassandra