Node.js mysql connection pool 성능 비교

 

Summry

본 문서에서는 node.js와 mysql를 연동하는 방법 두 가지(connection, pool)의 성능을 비교 정리한다.

send me email if you have any questions.


Connection

const mysql = require('mysql');

const connection = mysql.createConnection({ 
  host : 'localhost',
  port : 3306,
  user : 'root',
  password : 'password',
  database : 'testdb'
}

connection.connect();

// test 테이블에 저장된 데이터 확인
sql = "SELECT * FROM test";
connection.query(sql, function(err, rows, fields){
  if(err) console.log(err);
  console.log(rows);
});

connection.end();

connection을 맺는데 사용하는 주요 옵션

  • host : connection을 맺을 mysql 서버의 hostname
  • port : mysql 서버의 port
  • user / password : mysql 서버의 user와 패스워드
  • database : 사용할 데이터베이스 이름
  • charset : connection에 대한 인코딩 방식(default) : utf8_general_ci)
  • timezone : mysql 서버에 구성된 표준 시간대, 이 값은 javascript Data 객체에 값을 입력하는데 사용되며 반대로 Data 객체에 있는 값을 mysql에 입력할 때 사용 (기본값 : local)
  • connectionTimeout : mysql 서버에 처음 connection을 맺는데 이 값보다 오래걸리면 timeout이 발생(기본 값 : 10000ms)
  • ssl : SSL(Secure Socket Layer)와 관련된 설정

Connection Pool

Connection Pool을 사용하기 위해서는 최대 connection 수를 정해줘야하는데 connectionLimit이라는 옵션을 주어 정할 수 있다.

const mysql = require('mysql');
const connection = mysql.createPool({ 
  host : 'localhost',
  port : 3306,
  user : 'root',
  password : 'password',
  database : 'testdb'
  connectionLimit : 5
}

// DB connection 얻기
pool.getConnection((err, connection) => {
  if (err) {
    switch (err.code) {
      case "PROTOCOL_CONNECTION_LOST":
        console.error("Database connection was closed.");
        break;
      case "ER_CON_COUNT_ERROR":
        console.error("Database has too many connections.");
        break;
      case "ECONNREFUSED":
        console.error("Database connection was refused.");
        break;
    }

    conn.query("select * from testdb", function(err, rows) {
      if(err) console.log(err);
        console.log(rows);
      })
  }
  if (connection) return connection.release();
});

성능비교

아래의 내용은 [Node.js] mysql 모듈로 mysql 서버와 connection 맺기 (Connection Pool의 성능비교) - 해피쿠 블로그 에서 실험한 결과를 정리하였음.

db server와 connection을 맺고 끊는 작업은 상당한 비용이 드는 작업이다. 그렇기에 connection을 미리 생성해놓고 대여하고 반납하는 형태인 connection Pool을 자주 사용한다.

max_connections 값이 1000이상인 경우 1000번의 쿼리를 실행했을 때

  • Connection을 사용한 경우 507ms가 소요
  • Connection Pool을 사용했을 때 265ms가 소요

connection을 쿼리 실행 후 바로 반납하거나 끊지 않고, Connection Pool방식은 100ms 후에 반납하고 끊는다면 11초나 걸렸다고 한다. 그 이유는 10개의 connection을 Pool에 저장해놓고 재사용하며 사용하기 때문이다. Pool에 사용할 수 있는 connection이 없으면 다른 요청들은 connection 반납이 있을 때까지 대기하기 때문에 시간이 엄청 소요되었다.

그렇다고 매 요청마다 connection 을 맺고 끊는 방법이 마냥 좋은것은 아니다. 실제로 이렇게 1000개 이상의 많은 connection을 생성하는 것은 서버의 과부하를 불러 일으키고 장애를 일으키는 요인이 된다. 따라서, 동시접속자가 많고, connection을 오래 붙잡고 있는 경우에는 connection Pool을 사용하되 Pool에 저장되는 connection 수를 적절하게 조절하는 것이 현명하다. 하지만, connection Pool의 사용은 메모리를 많이 차지하기 때문에 사용자의 요청이 적거나 동시 접속자 수가 적은 경우에는 mysql 서버의 max_connections을 적당하게 설정하여 요청마다 connection을 맺고 끊는 것이 좋다.

Reference

[Node.js] mysql 모듈로 mysql 서버와 connection 맺기 (Connection Pool의 성능비교) - 해피쿠 블로그
mysql 패키지) connection pool의 필요성 및 생성 - HotHandCoding
node.js + mysql connection pooling - stackoverflow