Vikas Singh
Vikas Singh

Reputation: 419

Why Cassandra Node js driver is slower than java

I’m using Cassandra Node js driver in my application and for fetching 100k records it’s taking 5.1 seconds but the same is happing in 2.7 seconds using java driver. Below is my schema and code in java and node js.

Cassandra table schema

CREATE TABLE transactions_data (
app_name text,
api_name text,
app_id text,
start_time timestamp,
duration int,
end_time timestamp,
node_id text,
request_body text,
request_parameter_name1 text,
request_parameter_name2 text,
request_parameter_name3 text,
request_parameter_name4 text,
request_parameter_name5 text,
request_parameter_value1 text,
request_parameter_value2 text,
request_parameter_value3 text,
request_parameter_value4 text,
request_parameter_value5 text,
response_body text,
response_parameter_name1 text,
response_parameter_name2 text,
response_parameter_name3 text,
response_parameter_name4 text,
response_parameter_name5 text,
response_parameter_value1 text,
response_parameter_value2 text,
response_parameter_value3 text,
response_parameter_value4 text,
response_parameter_value5 text,
responsestatus text,
responsestatuscode text,
transaction_id text,
PRIMARY KEY ((app_name, api_name, app_id), start_time)
); 

Java Code

public class CassandraQueryPerformance {

private Cluster cluster;
private Session session;

private String query;

public CassandraQueryPerformance(String host,String query) throws 
IOException {
    this.query=query;
    cluster = Cluster.builder().addContactPoints(host)
            .withSocketOptions(new 
SocketOptions().setConnectTimeoutMillis(2000000)).build();
    session = cluster.connect();
}

public void performanceTest() throws IOException {
    Statement statement = new SimpleStatement(query);
    statement.setFetchSize(100000);
    statement.setReadTimeoutMillis(650000).enableTracing();

     ResultSet rs = session.execute(statement);

    ArrayList<Row> list = new ArrayList<>();
    for (com.datastax.driver.core.Row row : rs) {
        list.add(row);
    }
    System.out.println("list count "+list.size());
}


public void close() {
    cluster.close();
    session.close();
}

public static void main(String[] args) throws IOException {

    long startTime = System.currentTimeMillis();
    CassandraQueryPerformance cqp = new 
CassandraQueryPerformance(args[0],args[1]);

    long onlyQueryTime = System.currentTimeMillis();

    cqp.performanceTest();
    System.out.println("total time without open close " + 
(System.currentTimeMillis() - onlyQueryTime));

    cqp.close();

    System.out.println("total time " + (System.currentTimeMillis() - 
startTime));
}

}

Node js code

    'use strict';

    const Hapi = require('hapi');
    const cassandra = require('cassandra-driver');

    const options1 = {
     contactPoints: ['abcserver:9042'],
     keyspace: 'demo'
    }

    const server = new Hapi.Server();
    server.connection({
        host: 'localhost',
        port: 9999
    });

    // Add the route
    server.route({
        method: 'GET',
        path:'/get-transaction',
        handler: function (request, reply) {

          let allResults = [];
          //console.time('client_initialize');
          var client = new cassandra.Client(options1);
         // console.timeEnd('client_initialize');

    var cqlQuery="SELECT start_time, end_time, duration FROM " + 
             "transactions_data WHERE app_name = 'app_name-100'"+
             " AND api_name ='api_name-1'"+ 
            " AND app_id='app_id_19999999' AND "+
            " start_time >= '2017-03-20 13:40:29' AND "+
            " start_time <= '2017-04-25 13:40:29' ";

          client.connect(function(err, response) {

            console.time('queryTime');
            const options = { prepare : true , fetchSize : 100000};
            let formattedRow;
            client.eachRow(cqlQuery, {}, options, function (n, row) {
                 allResults.push(row);
            }, function (err, result) {

                if (result && result.nextPage) {
                    result.nextPage();
                }
                else{
                    console.timeEnd('queryTime');
                    console.log("Total no of records...",allResults.length);
                    reply('success');
                }
             reply('Hello '+request.query.limit);
            });
          });

        }
    });

    server.start((err) => {

        if (err) {
            throw err;
        }
        console.log('Server running at:', server.info.uri);
    });

Result captured in milliseconds

Number of records   Node      Java       Difference
10k                 846.232    494       352.232
20k                 1115.307   624       491.307
30k                 1603.353   897       706.353
40k                 2124.656   1051     1073.656
50k                 2626.624   1437     1189.624
60k                 2940.313   1912     1028.313
70k                 3478.797   1866     1612.797
80k                 4293.986   2108     2185.986
90k                 4677.516   2228     2449.516
100k                5175.231   2379     2796.231

Upvotes: 0

Views: 674

Answers (1)

nevsv
nevsv

Reputation: 2466

Start with that NodeJS is single threaded, and java driver shouldn't be. This can make CPU intensive tasks (such as decompression or parsing of Cassandra record) work slowly on NodeJS.

There's can be many differences on driver implementation level, starting with how much time does take to open connection and finishing with record construction on the client side. There's can be many differences also in defaults, for example using or not compression for data transfer.

I've ran tests with python and go, and managed to get to x10 performance with go in many workflows. NodeJS and Java are very different languages, and Java should provide better performance by default.

Upvotes: 1

Related Questions