NestJS + Prisma + AWS RDS ์„ฑ๋Šฅ ์ตœ์ ํ™”

ํ…Œ
ํ…Œ์ŠคํŠธ์ €์žAuthor
4 min read

Connection Pool ์ „๋žต ์™„์ „ ๊ฐ€์ด๋“œ

NestJS์™€ Prisma, ๊ทธ๋ฆฌ๊ณ  AWS RDS๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋Š” ๋งค์šฐ ๋งŽ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์‹ค๋ฌด์—์„œ ๊ฝค ํ”ํ•˜๊ฒŒ ๊ฒช๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ”๋กœ Connection Pool ๊ณผ๋ถ€ํ•˜๋กœ ์ธํ•œ ๋А๋ ค์ง, DB ์—ฐ๊ฒฐ ์—๋Ÿฌ, ๋Œ€๊ธฐ ์‹œ๊ฐ„ ์ฆ๊ฐ€ ๊ฐ™์€ ์„ฑ๋Šฅ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

ํŠนํžˆ ๋‹ค์Œ ์ƒํ™ฉ์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ๋” ์ž์ฃผ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • NestJS API๊ฐ€ ์„œ๋ฒ„๋ฆฌ์Šค(Lambda) ๋˜๋Š” ์˜คํ† ์Šค์ผ€์ผ๋ง ํ™˜๊ฒฝ์ผ ๋•Œ
  • Prisma๊ฐ€ ๋งค ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ์šด DB ์ปค๋„ฅ์…˜์„ ์ƒ์„ฑํ•  ๋•Œ
  • RDS์˜ max_connections ๊ฐ’์„ ์ดˆ๊ณผํ•  ๋•Œ
  • Prisma๋ฅผ ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ณ  DI๋กœ ์—ฌ๋Ÿฌ ๊ฐœ ์ƒ์„ฑํ•œ ๊ฒฝ์šฐ
  • ๋Œ€๊ทœ๋ชจ ์ฝ๊ธฐ/์“ฐ๊ธฐ ํŠธ๋ž˜ํ”ฝ์ด ๋™์‹œ์— ๋ชฐ๋ฆด ๋•Œ

์ด ๊ธ€์—์„œ๋Š” Prisma Connection Pool ์ดํ•ด โ†’ ๋ฌธ์ œ ๋ฐœ์ƒ ์›์ธ โ†’ ์ตœ์ ํ™” ์ „๋žต โ†’ ์‹ค์ „ ์ฝ”๋“œ ์˜ˆ์ œ ์ˆœ์œผ๋กœ
์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


1. Prisma์˜ Connection Pool ๋™์ž‘ ๋ฐฉ์‹

Prisma๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์„ ํ’€(pool) ํ˜•ํƒœ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
์ฆ‰, DB์— ์—ฐ๊ฒฐ์„ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค์–ด๋‘๊ณ  ์š”์ฒญ๋งˆ๋‹ค ํ•„์š”ํ•œ ์—ฐ๊ฒฐ์„ ๋น ๋ฅด๊ฒŒ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•˜์ฃ .

ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž˜๋ชป ์„ค์ •ํ•˜๊ฑฐ๋‚˜ NestJS ๊ตฌ์กฐ๊ฐ€ ๋ณต์žกํ•˜๋ฉด ํ’€ ์ƒ์„ฑ ๋กœ์ง์ด ๊ผฌ์ด๋ฉด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

โŒ ๋ฌธ์ œ ์‚ฌ๋ก€ 1: ๋งค ์š”์ฒญ๋งˆ๋‹ค PrismaClient๊ฐ€ ์ƒˆ๋กœ ์ƒ์„ฑ๋จ

์˜ˆ:

const prisma = new PrismaClient();

์ด ์ฝ”๋“œ๋ฅผ DI ์—†์ด ์„œ๋น„์Šค๋งˆ๋‹ค ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜, ์„œ๋ฒ„๋ฆฌ์Šค์—์„œ ๋งค ์‹คํ–‰๋งˆ๋‹ค ์ดˆ๊ธฐํ™”ํ•˜๋ฉดโ€ฆ

  • DB ์—ฐ๊ฒฐ ํญ์ฆ
  • RDS max_connections ์ดˆ๊ณผ
  • Too many connections ๋ฐœ์ƒ

โŒ ๋ฌธ์ œ ์‚ฌ๋ก€ 2: RDS์˜ ๊ธฐ๋ณธ max_connections ํ•œ๊ณ„

AWS RDS์˜ max_connections๋Š” ์ธ์Šคํ„ด์Šค ํƒ€์ž…์— ๋”ฐ๋ผ ์ •ํ•ด์ง‘๋‹ˆ๋‹ค.

์˜ˆ:

  • db.t3.micro โ†’ ์•ฝ 90๊ฐœ
  • db.t3.small โ†’ ์•ฝ 150๊ฐœ
  • db.t3.medium โ†’ ์•ฝ 300๊ฐœ

ํŠธ๋ž˜ํ”ฝ ๋งŽ์€ API๋Š” ๊ธˆ๋ฐฉ ์ดˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.


2. NestJS + Prisma ํ™˜๊ฒฝ์—์„œ ๋‚˜ํƒ€๋‚˜๋Š” ์ „ํ˜•์ ์ธ ๋ฌธ์ œ

โ‘  API ์š”์ฒญ์ด ๋งŽ์„ ๋•Œ ์†๋„๊ฐ€ ๊ธ‰๊ฒฉํžˆ ์ €ํ•˜๋จ

Connection Pool์ด ์ดˆ๊ณผ๋˜๋ฉด DB๊ฐ€ ์ƒˆ ์—ฐ๊ฒฐ์„ ๊ฑฐ์ ˆํ•˜๊ฑฐ๋‚˜ ๋Œ€๊ธฐ ํ๋กœ ๋ฐ€๋ ค๋‚ฉ๋‹ˆ๋‹ค.

โ‘ก 500 ์—๋Ÿฌ - Too many connections

RDS์—์„œ ํ”ํžˆ ๋‚˜ํƒ€๋‚˜๋Š” ์˜ค๋ฅ˜:

ERROR: remaining connection slots are reserved for non-replication superuser connections

โ‘ข ์„œ๋ฒ„๋ฆฌ์Šค ํ™˜๊ฒฝ์—์„œ Prisma๊ฐ€ ํญ๋ฐœ์ ์œผ๋กœ ์ปค๋„ฅ์…˜ ์ƒ์„ฑ

Lambda + Prisma ์กฐํ•ฉ์—์„œ ์•…๋ช… ๋†’์•„์š”.

โ‘ฃ NestJS ๋ชจ๋“ˆ ๊ตฌ์กฐ๊ฐ€ ์ปค์ง€๋ฉด์„œ PrismaClient๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์ƒ๊น€

์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์„ ๋ฐ˜๋“œ์‹œ ์ง€์ผœ์•ผ ํ•จ.


3. ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ 4๊ฐ€์ง€ ํ•ต์‹ฌ ์ „๋žต


์ „๋žต 1. PrismaClient๋ฅผ ๋ฌด์กฐ๊ฑด ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

NestJS์—์„œ๋Š” Provider๋ฅผ ํ†ตํ•ด PrismaClient๋ฅผ ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PrismaService ๊ตฌํ˜„ ์˜ˆ์ œ

import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
  async onModuleInit() {await this.$connect();
  }

  async onModuleDestroy() {await this.$disconnect();
  }
}

AppModule์— ๋“ฑ๋ก

@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class AppModule {}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด NestJS ์ „์ฒด์—์„œ PrismaClient๋Š” ๋‹จ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


์ „๋žต 2. Prisma์˜ Connection Pool ํฌ๊ธฐ ์กฐ์ ˆํ•˜๊ธฐ

Prisma๋Š” DATABASE_URL ๋’ค์— pool ์˜ต์…˜์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ (PostgreSQL)

DATABASE_URL="postgresql://user:pass@host:5432/db?schema=public&connection_limit=5&pool_timeout=10"

์ฃผ์š” ์˜ต์…˜

์˜ต์…˜ ์„ค๋ช…
connection_limit Prisma๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ์ตœ๋Œ€ DB ์—ฐ๊ฒฐ ์ˆ˜
pool_timeout ์—ฐ๊ฒฐ ๋Œ€๊ธฐ ์‹œ๊ฐ„(ms)

์ถ”์ฒœ๊ฐ’ (RDS t3.small ๊ธฐ์ค€)

  • connection_limit = 5~10
  • pool_timeout = 5~10์ดˆ

๋Œ€๊ทœ๋ชจ ํŠธ๋ž˜ํ”ฝ์ด๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ๋‚ฎ๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ •์ ์ž…๋‹ˆ๋‹ค.

connection_limit=5

์ „๋žต 3. AWS RDS ์„ค์ • ์ตœ์ ํ™”

1) max_connections ํ™•์ธ

RDS PostgreSQL:

SHOW max_connections;

์—ฌ๊ธฐ์„œ ๊ฐ’์ด ๋„ˆ๋ฌด ์ž‘๋‹ค๋ฉด ์ธ์Šคํ„ด์Šค ํƒ€์ž…์„ ํ•œ ๋‹จ๊ณ„ ์˜ฌ๋ ค์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

2) ํŒŒ๋ผ๋ฏธํ„ฐ ๊ทธ๋ฃน ์กฐ์ •

  • idle_in_transaction_session_timeout
  • statement_timeout
  • max_connections

Timeout ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ์—ฐ๊ฒฐ์ด ์˜ค๋ž˜ ์ ์œ ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด์š”.

3) RDS Proxy ๊ณ ๋ ค (๊ฐ•๋ ฅ ์ถ”์ฒœ)

AWS LambdaยทFargate ๊ฐ™์€ ํ™˜๊ฒฝ์—์„œ๋Š”
RDS Proxy๋ฅผ ๋ผ์šฐ๋ฉด DB ์—ฐ๊ฒฐ ํญ์ฆ ๋ฌธ์ œ๋ฅผ ๊ฑฐ์˜ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ.


์ „๋žต 4. ์š”์ฒญ ๊ธฐ๋ฐ˜ ์ฟผ๋ฆฌ ์ตœ์ ํ™”

Connection Pool ํŠœ๋‹๋งŒ์œผ๋กœ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋„ ๋งŽ์Šต๋‹ˆ๋‹ค.
ํŠนํžˆ ๋‹ค์Œ ์ƒํ™ฉ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ ์ตœ์ ํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

โœ” N+1 ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” Prisma ๊ตฌ์กฐ

์˜ˆ:

await prisma.user.findMany({
  include: { posts: true },
});

๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฉด Pool์„ ๊ธˆ๋ฐฉ ์ฑ„์›Œ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

โœ” ๋Œ€ํ˜• ํŠธ๋žœ์žญ์…˜์„ ๋‚˜๋ˆ„๊ธฐ

1๊ฐœ ์š”์ฒญ์ด Pool 10๊ฐœ๋ฅผ ์žก์•„๋จน๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Œ.

โœ” read-only ์ฟผ๋ฆฌ๋ฅผ replica๋กœ ๋ถ„์‚ฐ

RDS read replica๋ฅผ ๋„์ž…ํ•˜๋ฉด ์ฝ๊ธฐ ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


4. ์ถ”์ฒœ Connection Pool ์„ค์ • ์กฐํ•ฉ

โญ ์†Œ๊ทœ๋ชจ ์„œ๋ฒ„ (t3.micro / t3.small)

connection_limit=3~5  
pool_timeout=10

โญ ์ค‘ํ˜• ์„œ๋ฒ„ (t3.medium ์ด์ƒ)

connection_limit=10~20  
pool_timeout=5

โญ ์„œ๋ฒ„๋ฆฌ์Šค(Lambda)

  • connection_limit=1
  • ๋ฐ˜๋“œ์‹œ RDS Proxy ์‚ฌ์šฉ
  • PrismaClient ์žฌ์‚ฌ์šฉ ์ฝ”๋“œ ์ ์šฉ

5. ๊ฒฐ๋ก : Connection Pool ํŠœ๋‹์€ ์„ ํƒ์ด ์•„๋‹ˆ๋ผ ํ•„์ˆ˜

NestJS + Prisma + AWS RDS ์กฐํ•ฉ์€ ์ƒ์‚ฐ์„ฑ๊ณผ ๊ตฌ์กฐ๊ฐ€ ๋›ฐ์–ด๋‚œ ๋ฐ˜๋ฉด,
DB ์—ฐ๊ฒฐ ๊ด€๋ฆฌ๊ฐ€ ์กฐ๊ธˆ๋งŒ ์ž˜๋ชป๋ผ๋„ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ์ฆ‰์‹œ ํŠ€์–ด๋‚˜์˜ค๋Š” ํ™˜๊ฒฝ์ž…๋‹ˆ๋‹ค.

ํ•ต์‹ฌ์€ ๋‹ค์Œ ๋„ค ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค:

  1. PrismaClient๋Š” ๋ฐ˜๋“œ์‹œ ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ๊ด€๋ฆฌํ•  ๊ฒƒ
  2. Connection Pool(connection_limit)์„ ์„œ๋ฒ„ ์šฉ๋Ÿ‰์— ๋งž๊ฒŒ ์กฐ์ ˆํ•  ๊ฒƒ
  3. AWS RDS ํŒŒ๋ผ๋ฏธํ„ฐ + RDS Proxy๋กœ ์•ˆ์ •์„ฑ ํ–ฅ์ƒ
  4. ์ฟผ๋ฆฌ ์ž์ฒด๋„ ์ตœ์ ํ™” ํ•„์š” (N+1, ๊ณผ๋„ํ•œ include ๋“ฑ)

์ด ๋„ค ๊ฐ€์ง€๋งŒ ์žก์•„๋„ API ๋ฐ˜์‘ ์†๋„๋Š” ๋ˆˆ์— ๋„๊ฒŒ ๋นจ๋ผ์ง€๊ณ 
RDS connection ํญ์ฃผ ๋ฌธ์ œ๋Š” ํฌ๊ฒŒ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

NestJS + Prisma + AWS RDS ์„ฑ๋Šฅ ์ตœ์ ํ™”