[DB]connection pool

Creating the dots·2022년 2월 1일
0

CS

목록 보기
19/19
post-custom-banner

클라이언트가 데이터베이스에 접근하기 위해서는 connection이 필요하다. connection pool은 여러개의 connection을 생성해두어 저장해두고 필요할때 꺼내쓰고 반환하는 기법을 말한다.

connection pool이 필요한 이유?

데이터베이스 connection을 생성한는 것은 비용이 많이 드는 작업이다. 매번 connection을 생성해서 연결하고 종료하기 때문에 비효율적이다. 따라서 풀에 여러개의 connection들을 active한 상태로 유지시킨후 필요할때 빌려서 사용한 후 반환한다. 만약 모든 connection이 사용중이라면, 클라이언트는 대기상태로 전환되고, connection이 반환되면, 대기 상태에 있는 클라이언트에게 순차적으로 제공된다.

  • 매 연결마다 connection을 만들고 종료(release)시키는 비용을 줄일 수 있다.
  • 미리 생성된 conenction을 사용하기 때문에 DB 접근 시간을 단축할 수 있다.
  • DB에 접근하는 connection 수를 제한하여 DB에 발생할 수 있는 과부하를 방지할 수 있다.

connection 연결 요청이 있을 경우, 풀에 있는 connection 중 사용가능한 것을 할당하여 새로운 connection을 만들지 않아도 된다. 이는 여러 클라이언트로부터 동시에 여러개의 connection 요청들이 있을때, 퍼포먼스가 극대화된다.

MySQL에서 connection pool을 사용할때 장점

유료 DBMS는 타임아웃이라는 기능이 있어 connection을 자동으로 종료(release)시켜주준다. 무료 DBMS인 MySQL에는 이러한 타임아웃기능이 없지만 connection pool을 사용하면 auto release를 지원한다.

connection pool을 만들고 pool.query를 했을때, 내부적으로 getConnection(), connection.query(), connection.release()가 자동으로 일어난다.

createPool 해보기

//db/db.js
const mysql = require("mysql2");

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASS,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit: 300,
  queueLimit: 0,
});

const db = pool.promise(); 
//👉 promise pool을 리턴시켜 controller에서 db를 가져와서 사용할때 .then, .catch, async/await를 사용할 수 있다
module.exports = db;

//controller/users/signup.js
const db = require("../../db/db");

module.exports = async (req, res) => {
  try {
    const {email, password} = req.body;
    const sql = 
    "INSERT INTO user (email, salt, password) 
     VALUES (?,?,?)";
    const params = [email, '123', password];
    await db.query(sql, params);
    return res.status(201).end();
  } catch(err) {
    throw err;
  }
}

만약 createPool을 하고, pool.promise()를 하지 않는다면?

이는 promise가 아닌 데이터를 .then, .catch, 또는 async/await로 사용했을때 발생한 에러이다. 따라서, 에러에서는 con.promise().query()의 형태로 사용하거나 mysql2/promise를 사용하거나 위에서 한 것처럼 pool.promise()의 형태를 export하여 에러를 해결할 수 있다.

(node:131605) UnhandledPromiseRejectionWarning: Error:

You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise, which is a programming error. Try calling con.promise().query(), or require('mysql2/promise') instead of 'mysql2' for a promise-compatible version of the query interface. To learn how to use async/await or Promises check out documentation at https://www.npmjs.com/package/mysql2#using-promise-wrapper, or the mysql2 documentation at https://github.com/sidorares/node-mysql2/tree/master/documentation/Promise-Wrapper.md

reference

profile
어제보다 나은 오늘을 만드는 중
post-custom-banner

0개의 댓글