νμ΄μ¬ 컀λ₯μ νλ§μΌλ‘ μ΅μ μ λ°μ΄ν°λ² μ΄μ€ μ±λ₯μ λ¬μ±νμΈμ. κ°λ ₯νκ³ νμ₯ κ°λ₯ν μ ν리μΌμ΄μ μ μν λ€μν μ λ΅, μ΄μ , μ€μ ꡬν μμ λ₯Ό μμλ΄ λλ€.
νμ΄μ¬ λ°μ΄ν°λ² μ΄μ€ 컀λ₯μ νλ§: μ±λ₯μ μν 컀λ₯μ κ΄λ¦¬ μ λ΅
νλ μ ν리μΌμ΄μ κ°λ°μμ λ°μ΄ν°λ² μ΄μ€μμ μνΈμμ©μ κΈ°λ³Έμ μΈ μꡬμ¬νμ λλ€. νμ§λ§ λͺ¨λ μμ²μ λν΄ λ°μ΄ν°λ² μ΄μ€ μ°κ²°μ μ€μ νλ κ²μ νΉν νΈλν½μ΄ λ§μ νκ²½μμ μ¬κ°ν μ±λ₯ λ³λͺ© νμμ μ λ°ν μ μμ΅λλ€. νμ΄μ¬ λ°μ΄ν°λ² μ΄μ€ 컀λ₯μ νλ§μ λ°λ‘ μ¬μ©ν μ μλ 컀λ₯μ νμ μ μ§νμ¬ μ°κ²° μμ± λ° ν΄μ μ€λ²ν€λλ₯Ό μ΅μνν¨μΌλ‘μ¨ μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν©λλ€. μ΄ κΈμμλ νμ΄μ¬ λ°μ΄ν°λ² μ΄μ€ 컀λ₯μ νλ§μ μ΄μ , λ€μν μ λ΅ λ° μ€μ ꡬν μμ λ₯Ό μ΄ν΄λ³΄λ©° μ’ ν©μ μΈ κ°μ΄λλ₯Ό μ 곡ν©λλ€.
컀λ₯μ νλ§μ νμμ± μ΄ν΄νκΈ°
λ°μ΄ν°λ² μ΄μ€ μ°κ²°μ μ€μ νλ κ³Όμ μλ λ€νΈμν¬ ν΅μ , μΈμ¦, 리μμ€ ν λΉ λ± μ¬λ¬ λ¨κ³κ° ν¬ν¨λ©λλ€. μ΄λ¬ν λ¨κ³λ€μ μκ°κ³Ό 리μμ€λ₯Ό μλͺ¨νμ¬ μ ν리μΌμ΄μ μ±λ₯μ μν₯μ λ―ΈμΉ©λλ€. λ§μ μμ μμ²μ΄ λ°μ΄ν°λ² μ΄μ€ μ κ·Όμ νμλ‘ ν λ, λ°λ³΅μ μΌλ‘ μ°κ²°μ μμ±νκ³ λ«λ λ° λ°λ₯΄λ λμ μ€λ²ν€λλ μλΉν΄μ Έμ μ§μ° μκ° μ¦κ°μ μ²λ¦¬λ κ°μλ‘ μ΄μ΄μ§ μ μμ΅λλ€.
컀λ₯μ νλ§μ 미리 μ€μ λμ΄ λ°λ‘ μ¬μ©ν μ μλ λ°μ΄ν°λ² μ΄μ€ 컀λ₯μ νμ μμ±νμ¬ μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν©λλ€. μ ν리μΌμ΄μ μ΄ λ°μ΄ν°λ² μ΄μ€μ μνΈμμ©ν΄μΌ ν λ, νμμ κ°λ¨ν 컀λ₯μ μ λΉλ €μ¬ μ μμ΅λλ€. μμ μ΄ μλ£λλ©΄, ν΄λΉ 컀λ₯μ μ λ€λ₯Έ μμ²μ΄ μ¬μ¬μ©ν μ μλλ‘ νμ λ°νλ©λλ€. μ΄ μ κ·Ό λ°©μμ λ°λ³΅μ μΌλ‘ μ°κ²°μ μ€μ νκ³ λ«μ νμλ₯Ό μμ μ£Όμ΄ μ±λ₯κ³Ό νμ₯μ±μ ν¬κ² ν₯μμν΅λλ€.
컀λ₯μ νλ§μ μ΄μ
- μ°κ²° μ€λ²ν€λ κ°μ: 컀λ₯μ νλ§μ κ° μμ²μ λν λ°μ΄ν°λ² μ΄μ€ μ°κ²° μ€μ λ° ν΄μ μ€λ²ν€λλ₯Ό μ κ±°ν©λλ€.
- μ±λ₯ ν₯μ: κΈ°μ‘΄ μ°κ²°μ μ¬μ¬μ©ν¨μΌλ‘μ¨ μ»€λ₯μ νλ§μ μ§μ° μκ°μ μ€μ΄κ³ μ ν리μΌμ΄μ μλ΅ μκ°μ κ°μ ν©λλ€.
- νμ₯μ± κ°ν: 컀λ₯μ νλ§μ μ ν리μΌμ΄μ μ΄ λ°μ΄ν°λ² μ΄μ€ μ°κ²° λ³λͺ© νμμ μ νλ°μ§ μκ³ λ λ§μ λμ μμ²μ μ²λ¦¬ν μ μκ² ν΄μ€λλ€.
- 리μμ€ κ΄λ¦¬: 컀λ₯μ νλ§μ νμ± μ°κ²° μλ₯Ό μ ννμ¬ λ°μ΄ν°λ² μ΄μ€ 리μμ€λ₯Ό ν¨μ¨μ μΌλ‘ κ΄λ¦¬νλ λ° λμμ΄ λ©λλ€.
- μ½λ λ¨μν: 컀λ₯μ νλ§μ μ°κ²° κ΄λ¦¬μ 볡μ‘μ±μ μΆμννμ¬ λ°μ΄ν°λ² μ΄μ€ μνΈμμ© μ½λλ₯Ό λ¨μνν©λλ€.
컀λ₯μ νλ§ μ λ΅
νμ΄μ¬ μ ν리μΌμ΄μ μλ μ¬λ¬ 컀λ₯μ νλ§ μ λ΅μ΄ μ¬μ©λ μ μμΌλ©°, κ°κ° μ₯λ¨μ μ΄ μμ΅λλ€. μ λ΅μ μ νμ μ ν리μΌμ΄μ μꡬμ¬ν, λ°μ΄ν°λ² μ΄μ€ μλ²μ μ±λ₯, κΈ°λ³Έ λ°μ΄ν°λ² μ΄μ€ λλΌμ΄λ²μ κ°μ μμμ λ°λΌ λ¬λΌμ§λλ€.
1. μ μ 컀λ₯μ νλ§
μ μ 컀λ₯μ νλ§μ μ ν리μΌμ΄μ μμ μ κ³ μ λ μμ 컀λ₯μ μ μμ±νκ³ μ ν리μΌμ΄μ μλͺ λμ μ΄λ₯Ό μ μ§νλ λ°©μμ λλ€. μ΄ μ κ·Ό λ°©μμ ꡬνμ΄ κ°λ¨νκ³ μμΈ‘ κ°λ₯ν μ±λ₯μ μ 곡ν©λλ€. νμ§λ§ 컀λ₯μ μκ° μ ν리μΌμ΄μ μ μμ λΆνμ λ§κ² μ λλ‘ μ‘°μ λμ§ μμΌλ©΄ λΉν¨μ¨μ μΌ μ μμ΅λλ€. ν ν¬κΈ°κ° λ무 μμΌλ©΄ μμ²μ΄ μ¬μ© κ°λ₯ν 컀λ₯μ μ κΈ°λ€λ €μΌ ν μ μμ΅λλ€. ν ν¬κΈ°κ° λ무 ν¬λ©΄ λ°μ΄ν°λ² μ΄μ€ 리μμ€λ₯Ό λλΉν μ μμ΅λλ€.
μμ (SQLAlchemy μ¬μ©):
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# Database connection details
database_url = "postgresql://user:password@host:port/database"
# Create a database engine with a fixed pool size
engine = create_engine(database_url, pool_size=10, max_overflow=0)
# Create a session factory
Session = sessionmaker(bind=engine)
# Use a session to interact with the database
with Session() as session:
# Perform database operations
pass
μ΄ μμ μμ `pool_size`λ νμ μμ±λ 컀λ₯μ μλ₯Ό μ§μ νκ³ , `max_overflow`λ νμ΄ μμ§λμμ λ μμ±λ μ μλ μΆκ° 컀λ₯μ μλ₯Ό μ§μ ν©λλ€. `max_overflow`λ₯Ό 0μΌλ‘ μ€μ νλ©΄ μ΄κΈ° ν ν¬κΈ°λ₯Ό μ΄κ³Όνλ μΆκ° 컀λ₯μ μμ±μ λ°©μ§ν©λλ€.
2. λμ 컀λ₯μ νλ§
λμ 컀λ₯μ νλ§μ μ ν리μΌμ΄μ μ μμ λΆνμ λ°λΌ νμ 컀λ₯μ μκ° λμ μΌλ‘ λμ΄λκ³ μ€μ΄λ€ μ μλλ‘ ν©λλ€. μ΄ μ κ·Ό λ°©μμ μ μ 컀λ₯μ νλ§λ³΄λ€ μ μ°νλ©° λ³ννλ νΈλν½ ν¨ν΄μ μ μν μ μμ΅λλ€. νμ§λ§ λ μ κ΅ν κ΄λ¦¬κ° νμνλ©° 컀λ₯μ μμ± λ° ν΄μ μ μ½κ°μ μ€λ²ν€λλ₯Ό μ λ°ν μ μμ΅λλ€.
μμ (SQLAlchemyμμ QueuePool μ¬μ©):
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import QueuePool
# Database connection details
database_url = "postgresql://user:password@host:port/database"
# Create a database engine with a dynamic pool size
engine = create_engine(database_url, poolclass=QueuePool, pool_size=5, max_overflow=10, pool_timeout=30)
# Create a session factory
Session = sessionmaker(bind=engine)
# Use a session to interact with the database
with Session() as session:
# Perform database operations
pass
μ΄ μμ μμ `poolclass=QueuePool`μ λμ 컀λ₯μ νμ μ¬μ©ν΄μΌ ν¨μ μ§μ ν©λλ€. `pool_size`λ νμ μ΄κΈ° 컀λ₯μ μλ₯Ό, `max_overflow`λ μμ±λ μ μλ μ΅λ μΆκ° 컀λ₯μ μλ₯Ό, `pool_timeout`μ 컀λ₯μ μ μ¬μ©ν μ μκ² λ λκΉμ§ κΈ°λ€λ¦¬λ μ΅λ μκ°μ μ§μ ν©λλ€.
3. λΉλκΈ° 컀λ₯μ νλ§
λΉλκΈ° 컀λ₯μ νλ§μ `asyncio`μ κ°μ νλ μμν¬λ₯Ό μ¬μ©νλ λΉλκΈ° μ ν리μΌμ΄μ μ μν΄ μ€κ³λμμ΅λλ€. μ΄λ λΈλ‘νΉ μμ΄ μ¬λ¬ μμ²μ λμμ μ²λ¦¬ν μ μκ² νμ¬ μ±λ₯κ³Ό νμ₯μ±μ λμ± ν₯μμν΅λλ€. μ΄λ μΉ μλ²μ κ°μ I/O λ°μ΄λ μ ν리μΌμ΄μ μμ νΉν μ€μν©λλ€.
μμ (`asyncpg` μ¬μ©):
import asyncio
import asyncpg
async def main():
# Database connection details
database_url = "postgresql://user:password@host:port/database"
# Create a connection pool
pool = await asyncpg.create_pool(database_url, min_size=5, max_size=20)
async with pool.acquire() as connection:
# Perform asynchronous database operations
result = await connection.fetch("SELECT 1")
print(result)
await pool.close()
if __name__ == "__main__":
asyncio.run(main())
μ΄ μμ μμ `asyncpg.create_pool`μ λΉλκΈ° 컀λ₯μ νμ μμ±ν©λλ€. `min_size`λ νμ μ΅μ 컀λ₯μ μλ₯Ό, `max_size`λ μ΅λ 컀λ₯μ μλ₯Ό μ§μ ν©λλ€. `pool.acquire()` λ©μλλ νμμ λΉλκΈ°μ μΌλ‘ 컀λ₯μ μ νλνλ©°, `async with` ꡬ문μ λΈλ‘μ΄ μ’ λ£λ λ 컀λ₯μ μ΄ νλ‘ λ€μ λ°νλλλ‘ λ³΄μ₯ν©λλ€.
4. μꡬ 컀λ₯μ
μꡬ 컀λ₯μ (keep-alive connectionsλΌκ³ λ ν¨)μ μμ²μ΄ μ²λ¦¬λ νμλ μ΄λ¦° μνλ₯Ό μ μ§νλ 컀λ₯μ μ λλ€. μ΄λ νμ μμ²μ λν μ°κ²°μ λ€μ μ€μ νλ μ€λ²ν€λλ₯Ό λ°©μ§ν©λλ€. κΈ°μ μ μΌλ‘ 컀λ₯μ *ν*μ μλμ§λ§, μꡬ 컀λ₯μ μ λΉμ·ν λͺ©νλ₯Ό λ¬μ±ν©λλ€. μ΄λ μ’ μ’ κΈ°λ³Έ λλΌμ΄λ²λ ORMμ μν΄ μ§μ μ²λ¦¬λ©λλ€.
μμ (`psycopg2`μμ keepalive μ¬μ©):
import psycopg2
# Database connection details
database_url = "postgresql://user:password@host:port/database"
# Connect to the database with keepalive parameters
conn = psycopg2.connect(database_url, keepalives=1, keepalives_idle=5, keepalives_interval=2, keepalives_count=2)
# Create a cursor object
cur = conn.cursor()
# Execute a query
cur.execute("SELECT 1")
# Fetch the result
result = cur.fetchone()
# Close the cursor
cur.close()
# Close the connection (or leave it open for persistence)
# conn.close()
μ΄ μμ μμ `keepalives`, `keepalives_idle`, `keepalives_interval`, `keepalives_count` λ§€κ°λ³μλ 컀λ₯μ μ keep-alive λμμ μ μ΄ν©λλ€. μ΄λ¬ν λ§€κ°λ³μλ€μ ν΅ν΄ λ°μ΄ν°λ² μ΄μ€ μλ²λ μ ν΄ μ»€λ₯μ μ κ°μ§νκ³ λ«μ 리μμ€ κ³ κ°μ λ°©μ§ν μ μμ΅λλ€.
νμ΄μ¬μμ 컀λ₯μ νλ§ κ΅¬ννκΈ°
μ¬λ¬ νμ΄μ¬ λΌμ΄λΈλ¬λ¦¬κ° 컀λ₯μ νλ§μ λ΄μ₯ μ§μνμ¬ μ ν리μΌμ΄μ μ μ½κ² ꡬνν μ μλλ‘ ν©λλ€.
1. SQLAlchemy
SQLAlchemyλ νμ΄μ¬μμ λ리 μ¬μ©λλ SQL ν΄ν·μ΄μ κ°μ²΄-κ΄κ³ν λ§€νΌ(ORM)λ‘, λ΄μ₯λ 컀λ₯μ νλ§ κΈ°λ₯μ μ 곡ν©λλ€. μ μ , λμ , λΉλκΈ° νλ§ λ± λ€μν 컀λ₯μ νλ§ μ λ΅μ μ§μν©λλ€. μ¬μ© μ€μΈ νΉμ λ°μ΄ν°λ² μ΄μ€μ λν μΆμνκ° νμν λ μ’μ μ νμ λλ€.
μμ (SQLAlchemyμμ 컀λ₯μ νλ§ μ¬μ©):
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# Database connection details
database_url = "postgresql://user:password@host:port/database"
# Create a database engine with connection pooling
engine = create_engine(database_url, pool_size=10, max_overflow=20, pool_recycle=3600)
# Create a base class for declarative models
Base = declarative_base()
# Define a model class
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
email = Column(String)
# Create the table
Base.metadata.create_all(engine)
# Create a session factory
Session = sessionmaker(bind=engine)
# Use a session to interact with the database
with Session() as session:
# Create a new user
new_user = User(name="John Doe", email="john.doe@example.com")
session.add(new_user)
session.commit()
# Query for users
users = session.query(User).all()
for user in users:
print(f"User ID: {user.id}, Name: {user.name}, Email: {user.email}")
μ΄ μμ μμ `pool_size`λ νμ μ΄κΈ° 컀λ₯μ μλ₯Ό, `max_overflow`λ μ΅λ μΆκ° 컀λ₯μ μλ₯Ό, `pool_recycle`μ 컀λ₯μ μ΄ μ¬νμ©λμ΄μΌ νλ μκ°(μ΄)μ μ§μ ν©λλ€. μ£ΌκΈ°μ μΌλ‘ 컀λ₯μ μ μ¬νμ©νλ©΄ μ€λλ 컀λ₯μ μ΄λ 리μμ€ λμμ κ°μ΄ μ€λ μ§μλλ 컀λ₯μ μΌλ‘ μΈν΄ λ°μνλ λ¬Έμ λ₯Ό μλ°©νλ λ° λμμ΄ λ μ μμ΅λλ€.
2. Psycopg2
Psycopg2λ νμ΄μ¬μ μν μΈκΈ° μλ PostgreSQL μ΄λν°λ‘, ν¨μ¨μ μ΄κ³ μμ μ μΈ λ°μ΄ν°λ² μ΄μ€ μ°κ²°μ μ 곡ν©λλ€. SQLAlchemyμ²λΌ *λ΄μ₯λ* 컀λ₯μ νλ§ κΈ°λ₯μ μμ§λ§, `pgbouncer`λ `psycopg2-pool`κ³Ό κ°μ 컀λ₯μ νλ¬μ ν¨κ» μμ£Ό μ¬μ©λ©λλ€. `psycopg2-pool`μ μ₯μ μ νμ΄μ¬μΌλ‘ ꡬνλμ΄ λ³λμ νλ‘μΈμ€κ° νμ μλ€λ μ μ λλ€. λ°λ©΄μ `pgbouncer`λ μΌλ°μ μΌλ‘ λ³λμ νλ‘μΈμ€λ‘ μ€νλλ©°, νΉν μλͺ μ΄ μ§§μ λ§μ μ°κ²°μ μ²λ¦¬ν λ λκ·λͺ¨ λ°°ν¬ νκ²½μμ λ ν¨μ¨μ μΌ μ μμ΅λλ€.
μμ (`psycopg2-pool` μ¬μ©):
import psycopg2
from psycopg2 import pool
# Database connection details
database_url = "postgresql://user:password@host:port/database"
# Create a connection pool
pool = pool.SimpleConnectionPool(1, 10, database_url)
# Get a connection from the pool
conn = pool.getconn()
try:
# Create a cursor object
cur = conn.cursor()
# Execute a query
cur.execute("SELECT 1")
# Fetch the result
result = cur.fetchone()
print(result)
# Commit the transaction
conn.commit()
except Exception as e:
print(f"Error: {e}")
conn.rollback()
finally:
# Close the cursor
if cur:
cur.close()
# Put the connection back into the pool
pool.putconn(conn)
# Close the connection pool
pool.closeall()
μ΄ μμ μμ `SimpleConnectionPool`μ μ΅μ 1κ°, μ΅λ 10κ°μ 컀λ₯μ μ κ°μ§ 컀λ₯μ νμ μμ±ν©λλ€. `pool.getconn()`μ νμμ 컀λ₯μ μ κ°μ Έμ€κ³ , `pool.putconn()`μ 컀λ₯μ μ νλ‘ λ°νν©λλ€. `try...except...finally` λΈλ‘μ μμΈκ° λ°μνλλΌλ 컀λ₯μ μ΄ νμ νλ‘ λ°νλλλ‘ λ³΄μ₯ν©λλ€.
3. aiopgμ asyncpg
λΉλκΈ° μ ν리μΌμ΄μ μ κ²½μ° `aiopg`μ `asyncpg`κ° PostgreSQL μ°κ²°μ μν μΈκΈ° μλ μ νμ§μ λλ€. `aiopg`λ λ³Έμ§μ μΌλ‘ `asyncio`λ₯Ό μν `psycopg2` λνΌμ΄λ©°, `asyncpg`λ μ²μλΆν° μμ±λ μμ ν λΉλκΈ° λλΌμ΄λ²μ λλ€. μΌλ°μ μΌλ‘ `asyncpg`κ° `aiopg`λ³΄λ€ λ λΉ λ₯΄κ³ ν¨μ¨μ μΈ κ²μΌλ‘ κ°μ£Όλ©λλ€.
μμ (`aiopg` μ¬μ©):
import asyncio
import aiopg
async def main():
# Database connection details
database_url = "postgresql://user:password@host:port/database"
# Create a connection pool
async with aiopg.create_pool(database_url) as pool:
async with pool.acquire() as conn:
async with conn.cursor() as cur:
await cur.execute("SELECT 1")
result = await cur.fetchone()
print(result)
if __name__ == "__main__":
asyncio.run(main())
μμ (`asyncpg` μ¬μ© - μ΄μ "λΉλκΈ° 컀λ₯μ νλ§" μΉμ μ μμ μ°Έμ‘°).
μ΄ μμ λ€μ λΉλκΈ° 컨ν μ€νΈ λ΄μμ `aiopg`μ `asyncpg`λ₯Ό μ¬μ©νμ¬ μ°κ²°μ μ€μ νκ³ μΏΌλ¦¬λ₯Ό μ€ννλ λ°©λ²μ 보μ¬μ€λλ€. λ λΌμ΄λΈλ¬λ¦¬ λͺ¨λ 컀λ₯μ νλ§ κΈ°λ₯μ μ 곡νμ¬ λΉλκΈ° μ ν리μΌμ΄μ μμ λ°μ΄ν°λ² μ΄μ€ μ°κ²°μ ν¨μ¨μ μΌλ‘ κ΄λ¦¬ν μ μκ² ν΄μ€λλ€.
Djangoμμμ 컀λ₯μ νλ§
κ³ μμ€ νμ΄μ¬ μΉ νλ μμν¬μΈ Djangoλ λ°μ΄ν°λ² μ΄μ€ 컀λ₯μ νλ§μ λ΄μ₯ μ§μν©λλ€. Djangoλ `DATABASES` μ€μ μ μ μλ κ° λ°μ΄ν°λ² μ΄μ€μ λν΄ μ»€λ₯μ νμ μ¬μ©ν©λλ€. Djangoκ° μ»€λ₯μ νμ λ§€κ°λ³μ(μ: ν¬κΈ°)μ λν μ§μ μ μΈ μ μ΄λ₯Ό λ ΈμΆνμ§λ μμ§λ§, μ°κ²° κ΄λ¦¬λ₯Ό ν¬λͺ νκ² μ²λ¦¬νλ―λ‘ λͺ μμ μΈ μ½λ μμ± μμ΄λ 컀λ₯μ νλ§μ μ½κ² νμ©ν μ μμ΅λλ€.
νμ§λ§ λ°°ν¬ νκ²½ λ° λ°μ΄ν°λ² μ΄μ€ μ΄λν°μ λ°λΌ μΌλΆ κ³ κΈ κ΅¬μ±μ΄ νμν μ μμ΅λλ€.
μμ (Django `DATABASES` μ€μ ):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
Djangoλ μ΄λ¬ν μ€μ μ κΈ°λ°μΌλ‘ μλμΌλ‘ 컀λ₯μ νλ§μ μ²λ¦¬ν©λλ€. νλ‘λμ νκ²½μμ 컀λ₯μ νλ§μ λμ± μ΅μ ννκΈ° μν΄ λ°μ΄ν°λ² μ΄μ€ μμ `pgbouncer`μ κ°μ λꡬλ₯Ό μ¬μ©ν μ μμ΅λλ€. μ΄ κ²½μ°, Djangoκ° λ°μ΄ν°λ² μ΄μ€ μλ²μ μ§μ μ°κ²°νλ λμ `pgbouncer`μ μ°κ²°νλλ‘ κ΅¬μ±νκ² λ©λλ€.
컀λ₯μ νλ§μ μν λͺ¨λ² μ¬λ‘
- μ¬λ°λ₯Έ μ λ΅ μ ν: μ ν리μΌμ΄μ μ μꡬμ¬νκ³Ό μμ λΆνμ λ§λ 컀λ₯μ νλ§ μ λ΅μ μ ννμΈμ. νΈλν½ ν¨ν΄, λ°μ΄ν°λ² μ΄μ€ μλ² μ±λ₯, κΈ°λ³Έ λ°μ΄ν°λ² μ΄μ€ λλΌμ΄λ²μ κ°μ μμλ₯Ό κ³ λ €ν΄μΌ ν©λλ€.
- ν ν¬κΈ° μ‘°μ : μ°κ²° λ³λͺ© νμκ³Ό 리μμ€ λλΉλ₯Ό νΌνκΈ° μν΄ μ»€λ₯μ ν ν¬κΈ°λ₯Ό μ μ νκ² μ‘°μ νμΈμ. νμ± μ°κ²° μλ₯Ό λͺ¨λν°λ§νκ³ κ·Έμ λ°λΌ ν ν¬κΈ°λ₯Ό μ‘°μ ν΄μΌ ν©λλ€.
- μ°κ²° μ ν μ€μ : 리μμ€ κ³ κ°μ λ°©μ§νκ³ κ³΅μ ν 리μμ€ ν λΉμ 보μ₯νκΈ° μν΄ μ μ ν μ°κ²° μ νμ μ€μ νμΈμ.
- μ°κ²° νμμμ ꡬν: μ€λ λκΈ°νλ μμ²μ΄ λ€λ₯Έ μμ²μ μ°¨λ¨νλ κ²μ λ°©μ§νκΈ° μν΄ μ°κ²° νμμμμ ꡬννμΈμ.
- μ°κ²° μ€λ₯ μ²λ¦¬: μ°κ²° μ€λ₯λ₯Ό μ μμ μΌλ‘ μ²λ¦¬νκ³ μ ν리μΌμ΄μ μΆ©λμ λ°©μ§νκΈ° μν΄ κ°λ ₯ν μ€λ₯ μ²λ¦¬ λ‘μ§μ ꡬννμΈμ.
- 컀λ₯μ μ¬νμ©: μ€λλ 컀λ₯μ μ΄λ 리μμ€ λμμ κ°μ΄ μ€λ μ§μλλ 컀λ₯μ μΌλ‘ μΈν΄ λ°μνλ λ¬Έμ λ₯Ό μλ°©νκΈ° μν΄ μ£ΌκΈ°μ μΌλ‘ 컀λ₯μ μ μ¬νμ©νμΈμ.
- 컀λ₯μ ν μ±λ₯ λͺ¨λν°λ§: μ μ¬μ μΈ λ³λͺ© νμμ΄λ λ¬Έμ λ₯Ό μλ³νκ³ ν΄κ²°νκΈ° μν΄ μ κΈ°μ μΌλ‘ 컀λ₯μ ν μ±λ₯μ λͺ¨λν°λ§νμΈμ.
- μ μ ν 컀λ₯μ μ’ λ£: 리μμ€ λμλ₯Ό λ°©μ§νκΈ° μν΄ μ¬μ© νμλ νμ 컀λ₯μ μ λ«κ±°λ(λλ νμ λ°ν) ν΄μΌ ν©λλ€. μ΄λ₯Ό 보μ₯νκΈ° μν΄ `try...finally` λΈλ‘μ΄λ 컨ν μ€νΈ κ΄λ¦¬μ(`with` ꡬ문)λ₯Ό μ¬μ©νμΈμ.
μλ²λ¦¬μ€ νκ²½μμμ 컀λ₯μ νλ§
컀λ₯μ νλ§μ AWS Lambda, Google Cloud Functions, Azure Functionsμ κ°μ μλ²λ¦¬μ€ νκ²½μμ ν¨μ¬ λ μ€μν΄μ§λλ€. μ΄λ¬ν νκ²½μμλ ν¨μκ° μμ£Ό νΈμΆλκ³ μλͺ μ΄ μ§§μ΅λλ€. 컀λ₯μ νλ§μ΄ μμΌλ©΄ κ° ν¨μ νΈμΆλ§λ€ μλ‘μ΄ λ°μ΄ν°λ² μ΄μ€ μ°κ²°μ μ€μ ν΄μΌ νλ―λ‘ μλΉν μ€λ²ν€λμ μ§μ° μκ° μ¦κ°λ‘ μ΄μ΄μ§λλ€.
νμ§λ§ μ΄λ¬ν νκ²½μ μν λΉμ μ₯(stateless) νΉμ± λλ¬Έμ μλ²λ¦¬μ€ νκ²½μμ 컀λ₯μ νλ§μ ꡬννλ κ²μ μ΄λ €μΈ μ μμ΅λλ€. μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν λͺ κ°μ§ μ λ΅μ λ€μκ³Ό κ°μ΅λλ€:
- μ μ λ³μ/μ±κΈν€: ν¨μ λ²μ λ΄μμ 컀λ₯μ νμ μ μ λ³μλ μ±κΈν€μΌλ‘ μ΄κΈ°νν©λλ€. μ΄λ₯Ό ν΅ν΄ ν¨μλ λμΌν μ€ν νκ²½(μ½λ μ€ννΈ) λ΄μμ μ¬λ¬ νΈμΆμ κ±Έμ³ μ»€λ₯μ νμ μ¬μ¬μ©ν μ μμ΅λλ€. νμ§λ§ μ€ν νκ²½μ΄ νκ΄΄λκ±°λ μ¬νμ©λ μ μμΌλ―λ‘ μ»€λ₯μ νμ΄ λ¬΄νμ μ μ§λ κ²μ΄λΌκ³ μμ‘΄ν μλ μμ΅λλ€.
- 컀λ₯μ νλ¬ (pgbouncer λ±): `pgbouncer`μ κ°μ 컀λ₯μ νλ¬λ₯Ό μ¬μ©νμ¬ λ³λμ μλ²λ 컨ν μ΄λμμ μ°κ²°μ κ΄λ¦¬ν©λλ€. κ·Έλ¬λ©΄ μλ²λ¦¬μ€ ν¨μλ λ°μ΄ν°λ² μ΄μ€μ μ§μ μ°κ²°νλ λμ νλ¬μ μ°κ²°ν μ μμ΅λλ€. μ΄ μ κ·Ό λ°©μμ μ±λ₯κ³Ό νμ₯μ±μ ν₯μμν¬ μ μμ§λ§ λ°°ν¬ λ³΅μ‘μ±μ΄ μΆκ°λ©λλ€.
- λ°μ΄ν°λ² μ΄μ€ νλ‘μ μλΉμ€: μΌλΆ ν΄λΌμ°λ μ 곡μ 체λ 컀λ₯μ νλ§ λ° κΈ°ν μ΅μ νλ₯Ό μ²λ¦¬νλ λ°μ΄ν°λ² μ΄μ€ νλ‘μ μλΉμ€λ₯Ό μ 곡ν©λλ€. μλ₯Ό λ€μ΄, AWS RDS Proxyλ Lambda ν¨μμ RDS λ°μ΄ν°λ² μ΄μ€ μ¬μ΄μ μμΉνμ¬ μ°κ²°μ κ΄λ¦¬νκ³ μ°κ²° μ€λ²ν€λλ₯Ό μ€μ¬μ€λλ€.
κ²°λ‘
νμ΄μ¬ λ°μ΄ν°λ² μ΄μ€ 컀λ₯μ νλ§μ νλ μ ν리μΌμ΄μ μμ λ°μ΄ν°λ² μ΄μ€ μ±λ₯κ³Ό νμ₯μ±μ μ΅μ ννκΈ° μν μ€μν κΈ°μ μ λλ€. κΈ°μ‘΄ 컀λ₯μ μ μ¬μ¬μ©ν¨μΌλ‘μ¨ μ»€λ₯μ νλ§μ μ°κ²° μ€λ²ν€λλ₯Ό μ€μ΄κ³ , μλ΅ μκ°μ κ°μ νλ©°, μ ν리μΌμ΄μ μ΄ λ λ§μ λμ μμ²μ μ²λ¦¬ν μ μκ² ν΄μ€λλ€. μ΄ κΈμμλ λ€μν 컀λ₯μ νλ§ μ λ΅, μΈκΈ° μλ νμ΄μ¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©ν μ€μ ꡬν μμ , κ·Έλ¦¬κ³ μ°κ²° κ΄λ¦¬λ₯Ό μν λͺ¨λ² μ¬λ‘λ₯Ό μ΄ν΄λ³΄μμ΅λλ€. 컀λ₯μ νλ§μ ν¨κ³Όμ μΌλ‘ ꡬνν¨μΌλ‘μ¨ νμ΄μ¬ λ°μ΄ν°λ² μ΄μ€ μ ν리μΌμ΄μ μ μ±λ₯κ³Ό νμ₯μ±μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€.
컀λ₯μ νλ§μ μ€κ³νκ³ κ΅¬νν λλ μ ν리μΌμ΄μ μꡬμ¬ν, λ°μ΄ν°λ² μ΄μ€ μλ²μ μ±λ₯, κΈ°λ³Έ λ°μ΄ν°λ² μ΄μ€ λλΌμ΄λ²μ κ°μ μμλ₯Ό κ³ λ €ν΄μΌ ν©λλ€. μ¬λ°λ₯Έ 컀λ₯μ νλ§ μ λ΅μ μ ννκ³ , ν ν¬κΈ°λ₯Ό μ‘°μ νλ©°, μ°κ²° μ νμ μ€μ νκ³ , μ°κ²° νμμμμ ꡬννκ³ , μ°κ²° μ€λ₯λ₯Ό μ μ ν μ²λ¦¬ν΄μΌ ν©λλ€. μ΄λ¬ν λͺ¨λ² μ¬λ‘λ₯Ό λ°λ¦μΌλ‘μ¨ μ»€λ₯μ νλ§μ μ μ¬λ ₯μ μ΅λν νμ©νκ³ κ°λ ₯νλ©° νμ₯ κ°λ₯ν λ°μ΄ν°λ² μ΄μ€ μ ν리μΌμ΄μ μ ꡬμΆν μ μμ΅λλ€.