Tiếp tục test về hiệu suất connection pooling trong nodejs

Nội dung bài viết

Connection pool trong nodejs là rất quan trọng, nó là một kỹ thuật rất quan trọng cho việc tương tác bất kỳ resource như Mysql, PostgreSQL, Redis or MongoDB. 


Tips: Hiệu suất giữa lập trình đồng bộ và không đồng bộ trong Nodejs

Connection pool là gì? 


Trong bài viết này tôi sẽ đề cập đến việc sử dụng Connection pool  nó sẽ ảnh hưởng đến hiệu suất của ứng dụng như thế nào so với việc không sử dụng Connection pool. Để chứng minh điều này tôi sẽ viết 2 chương trình, một không sử dụng pooling và một sử dụng pooling với một query trong db đơn giản thôi.


Connection pooling on node.js performance


Ở đây chỉ đề cập tới việc so sánh giữa hai cách triển khai giữa việc không sử dụng connection Pool và có sử dụng connection Pooling. Và đây cũng chính là một trong những kỹ thuật quan trọng khi phát triển một ứng dụng có quy mô lớn. Để chứng minh thì là một chương trình đơn giản. Đây là môt chức năng cơ bản gọi đến Database. Bài viết này liên quan đến dự án lớn về phát triển một ứng dụng như thương mại điện tử shopee, bạn muốn xem qua nó không? 


function callback(){
	process.exit();
}

function hitQuery(callback) {
    var user_query = "select count(*) from user u, access_code uac, user_location_info uli   where u.id = uac.user_id and u.id = uli.user_id"


    connection.query(user_query, function(err, rows, fields) {
        if (err) throw err;

        if (rows.length == 0) {
            console.log("No device token found for user: " + 16182);
            callback(null, null);
        } else {
            var deviceToken = rows[0]['device_token'];
            callback(null, rows[0]);
        }
    });
}

hitQuery(callback);


Nếu tôi thực hiện điều này và hãy xem thời gian, nó mất trung bình 1,5 - 2 giây.


$ time node paralleltest.js

real	0m1.756s
user	0m0.159s
sys	    0m0.017s


Tiếp theo tôi thử nghiệm việc chạy tuần tự nó như thế nào? Khái niệm này có trong Promise Serial javascript


async.series([function(callback) {
        hitQuery(callback);
    }, function(callback) {
        hitQuery(callback);
    },
    function(callback) {
        hitQuery(callback);
    },
    function(callback) {
        hitQuery(callback);
    },
    function(callback) {
        hitQuery(callback);
    }
], function done(err, results) {
    console.log(results);
    process.exit()
});


Khi tôi thực hiện phiên bản này trong đó tôi thực hiện 5 cuộc gọi nối tiếp, tôi nhận được trung bình 8-9 giây


$ time node paralleltest.js

real	0m8.579s
user	0m0.178s
sys	    0m0.019s


Tiếp theo tôi thay đổi việc chạy tuần tự sang chạy song song. Khái niệm này có trong Promise parallel javascript


async.parallel([function(callback) {
        hitQuery(callback);
    }, function(callback) {
        hitQuery(callback);
    },
    function(callback) {
        hitQuery(callback);
    },
    function(callback) {
        hitQuery(callback);
    },
    function(callback) {
        hitQuery(callback);
    }
], function done(err, results) {
    console.log(results);
    process.exit()
});


Và check lại thời gian xem:


$ time node paralleltest.js

real	0m8.168s
user	0m0.165s
sys	    0m0.018s


Trong 3 cách trên, nhìn chung nếu chúng ta sử dụng cách nào đi chăng nữa thì tình hình chung đều giống nhau, không có chút cải thiện hiệu suất ở đây. Vậy chúng ta qua cách sử dụng Connnection Pooling để xem hiệu suất có cải thiện gì không? Để khắc phục điều này, tôi sẽ thay đổi chương trình để sử dụng nhóm kết nối. Tôi đang tạo một nhóm đơn giản như sau:


var pool = mysql.createPool({
    connectionLimit: 100, //important
    host: '127.0.0.1',
    user: '***',
    password: '***',
    database: 'user',
    debug: false
});

Và thay đổi chức năng của chúng tôi để sử dụng createPool trong mysql:

function hitQuery(callback) {
    var user_query = "select count(*) from user u, access_code uac, user_location_info uli   where u.id = uac.user_id and u.id = uli.user_id"

    pool.getConnection(function(err, connection) {
        if (err) {
            connection.release();
            res.json({ "code": 100, "status": "Error in connection database" });
            return;
        }

        connection.query(user_query, function(err, rows, fields) {
            if (err) throw err;

            if (rows.length == 0) {
                console.log("No device token found for user: " + 16182);
                callback(null, null);
            } else {
                callback(null, rows[0]);

            }
        });

    });
}


Một lần nữa, Nếu tôi tính thời gian thực hiện đơn ở đây. tôi có


$ time node paralleltest1.js

real	0m1.763s
user	0m0.163s
sys	    0m0.020s


Ta thấy cũng không có nhiều thay đổi về hiệu suất, vì cơ bản mọi thứ đều là 1 kết nối thì tương đương nhau là điều hiển nhiên. Tiếp tục tôi cho test về cách chạy tuần tự


$ time node paralleltest1.js

real	0m8.192s
user	0m0.182s
sys	    0m0.019s


Nó vẫn vậy, nhưng điều đó là ổn vì tính tuần tự là chạy lần lượt. Chủ yếu ta test vè cách chạy song song.


$ time node paralleltest1.js

real	0m2.311s
user	0m0.175s
sys	    0m0.019s


Lần này chúng tôi đã đưa nó xuống 2.311 seconds từ 8.168 seconds đó là thời gian nó thực thi mà không sử dụng Connection Pooling.


Tóm lại


Việc triển khai trên cho bạn một thông số khá rõ ràng, nếu ứng dụng của bạn lơn thì việc triển khai cụm kết nối trong Nodejs và mysql là một việc nên làm và nên hiểu quy trình. Và đó cũng là một tiền đề để bạn hiểu về mysql chạy với pool như thế nào? 

MỌi ví dụ có thể tham khảo tại đây: https://www.madhur.co.in

Có thể bạn đã bị missing