NestJS + Prisma + AWS RDS ์ฑ๋ฅ ์ต์ ํ
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 ํ๋์ ์ ํ์ด ์๋๋ผ ํ์
connection_limit=3~5
pool_timeout=10
connection_limit=10~20
pool_timeout=5
NestJS + Prisma + AWS RDS ์กฐํฉ์ ์์ฐ์ฑ๊ณผ ๊ตฌ์กฐ๊ฐ ๋ฐ์ด๋ ๋ฐ๋ฉด,
DB ์ฐ๊ฒฐ ๊ด๋ฆฌ๊ฐ ์กฐ๊ธ๋ง ์๋ชป๋ผ๋ ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ์ฆ์ ํ์ด๋์ค๋ ํ๊ฒฝ์
๋๋ค.
ํต์ฌ์ ๋ค์ ๋ค ๊ฐ์ง์ ๋๋ค:
- PrismaClient๋ ๋ฐ๋์ ์ฑ๊ธํด์ผ๋ก ๊ด๋ฆฌํ ๊ฒ
- Connection Pool(connection_limit)์ ์๋ฒ ์ฉ๋์ ๋ง๊ฒ ์กฐ์ ํ ๊ฒ
- AWS RDS ํ๋ผ๋ฏธํฐ + RDS Proxy๋ก ์์ ์ฑ ํฅ์
- ์ฟผ๋ฆฌ ์์ฒด๋ ์ต์ ํ ํ์ (N+1, ๊ณผ๋ํ include ๋ฑ)
์ด ๋ค ๊ฐ์ง๋ง ์ก์๋ API ๋ฐ์ ์๋๋ ๋์ ๋๊ฒ ๋นจ๋ผ์ง๊ณ
RDS connection ํญ์ฃผ ๋ฌธ์ ๋ ํฌ๊ฒ ์ค์ด๋ญ๋๋ค.