๋์ฉ๋ ํธ๋ํฝ ์ฒ๋ฆฌ ์ํคํ ์ฒ๋ ๋ฌด์์ธ๊ฐ
์๋น์ค๋ฅผ ์ด์ํ๋ค ๋ณด๋ฉด ๊ฐ์๊ธฐ ์ฌ์ฉ์๊ฐ ํญ์ฆํ๋ ์๊ฐ์ด ์จ๋ค.
์ผํ๋ชฐ์ ๋ธ๋ํ๋ผ์ด๋ฐ์ด, ํฐ์ผ ์๋งค ์คํ, ์ด๋ฒคํธ ์์ ์์ ์ฒ๋ผ
ํ์๋ณด๋ค ์์ญ ๋ฐฐ, ์๋ฐฑ ๋ฐฐ์ ํธ๋ํฝ์ด ๋ชฐ๋ฆฌ๋ ์ํฉ ๋ง์ด๋ค.
์ด๋ ๋ง์น ์์ ๊ณจ๋ชฉ๊ธธ์ ๊ฐ์๊ธฐ ์์ฒ ๋ช
์ด ๋ชฐ๋ ค๋๋ ๊ฒ๊ณผ ๊ฐ๋ค.
์๋ฌด๋ฆฌ ์ข์ ๊ฐ๊ฒ๋ผ๋ ๋ฌธ์ด ํ๋๋ฐ์ ์๊ณ ,
๊ณ์ฐ์์ด ํ ๋ช
์ด๋ฉด ๊ธด ์ค์ด ์๊ธฐ๊ณ
๊ฒฐ๊ตญ ์๋๋ค์ ๊ธฐ๋ค๋ฆฌ๋ค ์ง์ณ ๋ ๋๋ฒ๋ฆฐ๋ค.
๋์ฉ๋ ํธ๋ํฝ ์ฒ๋ฆฌ ์ํคํ
์ฒ๋ ๋ฐ๋ก
์ด๋ฐ ์ํฉ์์๋ ์๋น์ค๊ฐ ๋ฉ์ถ์ง ์๊ณ
๋ชจ๋ ์ฌ์ฉ์์๊ฒ ๋น ๋ฅด๊ณ ์์ ์ ์ธ ๊ฒฝํ์ ์ ๊ณตํ๊ธฐ ์ํ
์์คํ
์ค๊ณ ๋ฐฉ๋ฒ์ด๋ค.
์ ๋์ฉ๋ ํธ๋ํฝ ๋๋น๊ฐ ํ์ํ ๊น?
๋์ฉ๋ ํธ๋ํฝ์ ๋๋นํ์ง ์์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๋ฌธ์ 1: ์๋ฒ ๋ค์ด
ํ ๋์ ์๋ฒ๊ฐ ๊ฐ๋นํ ์ ์๋ ์์ฒญ์๋ ํ๊ณ๊ฐ ์๋ค.
์ด๊ณผํ๋ฉด ์๋ฒ๊ฐ ๋ฉ์ถ๊ณ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ์ ์ ๋ถ๊ฐ ์ํ๊ฐ ๋๋ค.
๋ฌธ์ 2: ๋๋ฆฐ ์๋ต ์๋
์์ฒญ์ด ๋ชฐ๋ฆฌ๋ฉด ์ฒ๋ฆฌ ๋๊ธฐ ์๊ฐ์ด ๊ธธ์ด์ง๋ค.
์ฌ์ฉ์๋ 3์ด๋ง ๊ธฐ๋ค๋ ค๋ ์ดํ๋ฅ ์ด ๊ธ์ฆํ๋ค.
๋ฌธ์ 3: ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณผ๋ถํ
๋ชจ๋ ์์ฒญ์ด DB์ ์ง์ ์ ๊ทผํ๋ฉด
DB๊ฐ ๋ณ๋ชฉ ์ง์ ์ด ๋์ด ์ ์ฒด ์์คํ
์ด ๋๋ ค์ง๋ค.
๋ฌธ์ 4: ๋น์ฆ๋์ค ์์ค
์๋น์ค ๋ค์ด์ ๊ณง ๋งค์ถ ์์ค๊ณผ ์ ๋ขฐ๋ ํ๋ฝ์ผ๋ก ์ด์ด์ง๋ค.
๊ธฐ๋ณธ ๊ฐ๋ ์์ฝ
๋์ฉ๋ ํธ๋ํฝ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ํต์ฌ ์ ๋ต์
๋ถ์ฐ(Distribution)๊ณผ ํจ์จํ(Optimization)์ด๋ค.
๐ท๏ธ ํต์ฌ ๊ตฌ์ฑ ์์
1. ๋ก๋ ๋ฐธ๋ฐ์ฑ (Load Balancing)
๊ฐ๋
: ๋ค์ด์ค๋ ์์ฒญ์ ์ฌ๋ฌ ์๋ฒ์ ๊ท ๋ฑํ๊ฒ ๋ถ์ฐ์ํจ๋ค.
๋น์ :
์ํ ์ฐฝ๊ตฌ๋ฅผ ์๊ฐํด๋ณด์.
์ฐฝ๊ตฌ๊ฐ ํ๋๋ฉด ์ค์ด ๊ธธ์ง๋ง,
์ฐฝ๊ตฌ๋ฅผ 10๊ฐ๋ก ๋๋ฆฌ๊ณ ์
๊ตฌ์์ ๋ฒํธํ๋ฅผ ๋๋ ์ฃผ๋ฉด
๋๊ธฐ ์๊ฐ์ด 1/10๋ก ์ค์ด๋ ๋ค.
์ฃผ์ ์๊ณ ๋ฆฌ์ฆ:
- Round Robin: ์์๋๋ก ๋์๊ฐ๋ฉฐ ๋ถ๋ฐฐ
- Least Connections: ํ์ฌ ์ฐ๊ฒฐ์ด ๊ฐ์ฅ ์ ์ ์๋ฒ๋ก ๋ถ๋ฐฐ
- IP Hash: ๊ฐ์ ์ฌ์ฉ์๋ ํญ์ ๊ฐ์ ์๋ฒ๋ก ์ฐ๊ฒฐ
- Weighted: ์๋ฒ ์ฑ๋ฅ์ ๋ฐ๋ผ ๊ฐ์ค์น๋ฅผ ๋๊ณ ๋ถ๋ฐฐ
2. ์บ์ฑ (Caching)
๊ฐ๋
: ์์ฃผ ์ฌ์ฉ๋๋ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅธ ์ ์ฅ์์ ๋ฏธ๋ฆฌ ์ ์ฅํด๋๋ค.
๋น์ :
๋์๊ด์์ ์ฑ
์ ์ฐพ์ ๋๋ง๋ค ์๊ณ ๊น์ง ๊ฐ๋ ๊ฒ๋ณด๋ค,
์ธ๊ธฐ ๋์๋ ๋์ถ ์นด์ดํฐ ๊ทผ์ฒ์ ๋ฏธ๋ฆฌ ์์๋๋ฉด
์ฐพ๋ ์๊ฐ์ด ํ๊ธฐ์ ์ผ๋ก ์ค์ด๋ ๋ค.
์บ์ฑ ๊ณ์ธต:
- CDN(Content Delivery Network) ์บ์ฑ: ์ ์ ํ์ผ์ ์ ์ธ๊ณ์ ๋ถ์ฐ ์ ์ฅ
- ์ ํ๋ฆฌ์ผ์ด์ ์บ์ฑ: Redis, Memcached๋ก API ์๋ต ์ ์ฅ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์บ์ฑ: ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ
- ๋ธ๋ผ์ฐ์ ์บ์ฑ: ์ฌ์ฉ์ ๋ธ๋ผ์ฐ์ ์ ์ ์ฅ
3. ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ฅ
Replication (๋ณต์ ):
- Master DB: ์ฐ๊ธฐ ์ ๋ด
- Slave DB: ์ฝ๊ธฐ ์ ๋ด
- ์ฝ๊ธฐ ์์ฒญ์ด 80% ์ด์์ธ ์๋น์ค์ ํจ๊ณผ์
Sharding (์ค๋ฉ):
- ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ DB๋ก ์ํ ๋ถํ
- ์: ์ฌ์ฉ์ ID ๋ฒ์๋ณ๋ก ๋ถ์ฐ
4. ๋น๋๊ธฐ ์ฒ๋ฆฌ
๊ฐ๋
: ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์
์ ๋์ค์ ์ฒ๋ฆฌํ๋ค.
๋น์ :
์์์ ์์ ์ฃผ๋ฌธ์ ๋ฐ์ ๋,
๋ชจ๋ ์๋ฆฌ๊ฐ ์์ฑ๋ ๋๊น์ง ์๋์ ์ธ์๋์ง ์๊ณ
์ฃผ๋ฌธ๋ง ๋ฐ๊ณ ์๋ฆฌ๋ก ์๋ดํ ๋ค ๋์ค์ ์์์ ๊ฐ์ ธ๋ค์ค๋ค.
ํ์ฉ ์ฌ๋ก: ์ด๋ฉ์ผ ๋ฐ์ก, ์ด๋ฏธ์ง ์ฒ๋ฆฌ, ๋ฐ์ดํฐ ์ง๊ณ, ์๋ฆผ ๋ฐ์ก
5. CDN (Content Delivery Network)
๊ฐ๋
: ์ ์ ์ฝํ
์ธ ๋ฅผ ์ฌ์ฉ์์ ๊ฐ๊น์ด ๊ณณ์์ ์ ๊ณตํ๋ค.
ํจ๊ณผ: ์๋ต ์๋ ํฅ์, ์๋ณธ ์๋ฒ ๋ถํ ๊ฐ์, DDoS ๋ฐฉ์ด
๐ท๏ธ ํ์ฅ์ฑ์ ๋ ๊ฐ์ง ๋ฐฉํฅ
์์ง ํ์ฅ (Scale Up)
๋ฐฉ๋ฒ: ์๋ฒ์ ์ฑ๋ฅ์ ๋์ธ๋ค. (CPU, ๋ฉ๋ชจ๋ฆฌ ์ฆ์ค)
์ฅ์ : ๊ตฌํ ๊ฐ๋จ, ์ฝ๋ ์์ ๋ถํ์
๋จ์ : ๋น์ฉ ๊ธ์ฆ, ๋ฌผ๋ฆฌ์ ํ๊ณ ์กด์ฌ, ์ฅ์ ์ ์ ์ฒด ์ค๋จ
์ํ ํ์ฅ (Scale Out)
๋ฐฉ๋ฒ: ์๋ฒ์ ๊ฐ์๋ฅผ ๋๋ฆฐ๋ค.
์ฅ์ : ๋น์ฉ ํจ์จ์ , ๋ฌดํ ํ์ฅ ๊ฐ๋ฅ, ์ฅ์ ์ ์ผ๋ถ๋ง ์ํฅ
๋จ์ : ์ค๊ณ ๋ณต์ก, ์ธ์
๊ด๋ฆฌ ๋ฌธ์ ๋ฐ์
๊ฒฐ๋ก : ๋๋ถ๋ถ์ ๋๊ท๋ชจ ์๋น์ค๋ ์ํ ํ์ฅ์ ๊ธฐ๋ณธ์ผ๋ก ํ๋ค.
์ค์ ์ํคํ ์ฒ ๊ตฌ์ฑ
๋จ๊ณ 1: ๊ธฐ๋ณธ ๊ตฌ์ฑ
[์ฌ์ฉ์] โ [์น ์๋ฒ] โ [๋ฐ์ดํฐ๋ฒ ์ด์ค]
๋ฌธ์ ์ : ๋์ ์ ์์ 1,000๋ช
์ด์์ด๋ฉด ๋ฒ๊ฑฐ์
๋จ๊ณ 2: ๋ก๋ ๋ฐธ๋ฐ์ ์ถ๊ฐ
โโโ [์น ์๋ฒ 1] โโ
[์ฌ์ฉ์] โ [๋ก๋ ๋ฐธ๋ฐ์] โโผโโ [์น ์๋ฒ 2] โโผโ [DB]
โโโ [์น ์๋ฒ 3] โโ
๊ฐ์ : ์ฒ๋ฆฌ๋ 3๋ฐฐ, ๋ฌด์ค๋จ ๋ฐฐํฌ ๊ฐ๋ฅ
๋จ๊ณ 3: DB ๋ณต์ ์ถ๊ฐ
โโ [Master DB] (์ฐ๊ธฐ)
[์ฌ์ฉ์] โ [๋ก๋ ๋ฐธ๋ฐ์] โ [์น ์๋ฒ๋ค] โผโ [Slave DB 1] (์ฝ๊ธฐ)
โโ [Slave DB 2] (์ฝ๊ธฐ)
๊ฐ์ : ์ฝ๊ธฐ ๋ถํ ๋ถ์ฐ, ์ฝ๊ธฐ ์ฑ๋ฅ ๋ํญ ํฅ์
๋จ๊ณ 4: ์บ์ ์ถ๊ฐ
[์ฌ์ฉ์] โ [๋ก๋ ๋ฐธ๋ฐ์] โ [์น ์๋ฒ๋ค] โ [Redis ์บ์] โ [DB]
๊ฐ์ : DB ๋ถํ 80% ๊ฐ์, ์๋ต ์๊ฐ 10๋ฐฐ ๋จ์ถ
๋จ๊ณ 5: ์์ฑํ
[์ฌ์ฉ์] โ [CDN] โ [๋ก๋ ๋ฐธ๋ฐ์] โ [์น ์๋ฒ๋ค] โ [Redis] โ [DB]
โ
[๋ฉ์์ง ํ]
โ
[Worker ์๋ฒ๋ค]
๊ฐ์ : ์ ์ ํ์ผ CDN ์ ๊ณต, ๋ฌด๊ฑฐ์ด ์์
๋น๋๊ธฐ ์ฒ๋ฆฌ
Nginx ๋ก๋ ๋ฐธ๋ฐ์ ์ค์ ์์
Round Robin ๋ฐฉ์
http {
upstream backend {
server 10.0.1.101:8080;
server 10.0.1.102:8080;
server 10.0.1.103:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
Least Connections ๋ฐฉ์
upstream backend {
least_conn;
server 10.0.1.101:8080;
server 10.0.1.102:8080;
server 10.0.1.103:8080;
}
๊ฐ์ค์น ์ค์
upstream backend {
server 10.0.1.101:8080 weight=3;
server 10.0.1.102:8080 weight=2;
server 10.0.1.103:8080 weight=1;
}
ํฌ์ค ์ฒดํฌ
upstream backend {
server 10.0.1.101:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.102:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.103:8080 backup;
}
Redis ์บ์ฑ ์์
๊ธฐ๋ณธ ์บ์ฑ ํจํด
import redis
import json
cache = redis.Redis(host='localhost', port=6379)
def get_user_profile(user_id):
# 1. ์บ์ ํ์ธ
cache_key = f"user:{user_id}"
cached = cache.get(cache_key)
if cached:
return json.loads(cached)
# 2. DB ์กฐํ
data = db.query(f"SELECT * FROM users WHERE id={user_id}")
# 3. ์บ์ ์ ์ฅ (1์๊ฐ)
cache.setex(cache_key, 3600, json.dumps(data))
return data
์ธ๊ธฐ ๊ฒ์๋ฌผ ์บ์ฑ
def get_popular_posts():
cached = cache.get("posts:popular")
if cached:
return json.loads(cached)
posts = db.query("SELECT * FROM posts ORDER BY views DESC LIMIT 10")
cache.setex("posts:popular", 300, json.dumps(posts))
return posts
์บ์ ๋ฌดํจํ
def update_user(user_id, data):
db.update(f"UPDATE users SET ... WHERE id={user_id}")
cache.delete(f"user:{user_id}") # ์บ์ ์ญ์
๋ฉ์์ง ํ ๋น๋๊ธฐ ์ฒ๋ฆฌ
Producer (์์ ์์ฒญ)
import pika
import json
def send_email_async(user_email):
connection = pika.BlockingConnection()
channel = connection.channel()
channel.queue_declare(queue='email_queue')
message = {'email': user_email, 'type': 'welcome'}
channel.basic_publish(
exchange='',
routing_key='email_queue',
body=json.dumps(message)
)
print("์ด๋ฉ์ผ ์์
ํ์ ์ถ๊ฐ")
# ์ฆ์ ๋ฆฌํด!
Consumer (์์ ์ฒ๋ฆฌ)
def process_email(ch, method, properties, body):
message = json.loads(body)
send_email(message['email']) # ์ค์ ์ด๋ฉ์ผ ๋ฐ์ก
ch.basic_ack(delivery_tag=method.delivery_tag)
connection = pika.BlockingConnection()
channel = connection.channel()
channel.basic_consume(queue='email_queue', on_message_callback=process_email)
channel.start_consuming()
์ฑ๋ฅ ๋ชจ๋ํฐ๋ง
์ฃผ์ ์งํ
์๋ฒ ์งํ:
- CPU ์ฌ์ฉ๋ฅ (80% ์ด์ โ Scale Out)
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ (90% ์ด์ โ ์ํ)
- ๋์คํฌ I/O
- ๋คํธ์ํฌ ๋์ญํญ
์ ํ๋ฆฌ์ผ์ด์ ์งํ:
- ์๋ต ์๊ฐ (ํ๊ท , p95, p99)
- ์ฒ๋ฆฌ๋ (RPS)
- ์๋ฌ์จ (5xx)
- ๋์ ์ ์์ ์
๋ฐ์ดํฐ๋ฒ ์ด์ค ์งํ:
- ์ฟผ๋ฆฌ ์คํ ์๊ฐ
- ์ปค๋ฅ์ ํ ์ฌ์ฉ๋ฅ
- Replication Lag
- ๋ฝ ๋๊ธฐ ์๊ฐ
์บ์ ์งํ:
- ์บ์ ํํธ์จ (80% ์ด์ ๋ชฉํ)
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ
์ค์ ์ฒดํฌ๋ฆฌ์คํธ
โ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ต์ ํ
- ์ธ๋ฑ์ค ์ถ๊ฐ
- N+1 ์ฟผ๋ฆฌ ์ ๊ฑฐ
- ์ปค๋ฅ์ ํ ์กฐ์
- Replica ๋ถ๋ฆฌ
โ ์บ์ฑ ์ ์ฉ
- API ์๋ต ์บ์ฑ
- ์ ์ ํ์ผ CDN
- ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์บ์ฑ
โ ๋ก๋ ๋ฐธ๋ฐ์ฑ
- Nginx/HAProxy ์ค์
- ํฌ์ค ์ฒดํฌ ๊ตฌ์ฑ
- ์ธ์ ๊ด๋ฆฌ ์ ๋ต
โ ๋น๋๊ธฐ ์ฒ๋ฆฌ
- ๋ฉ์์ง ํ ๋์
- Worker ์๋ฒ ๊ตฌ์ฑ
- ์ฌ์๋ ๋ก์ง
โ ๋ชจ๋ํฐ๋ง
- Prometheus/Grafana ๊ตฌ์ถ
- ์๋ฆผ ์ค์
- ๋ก๊ทธ ์์ง (ELK)
์์ฝ
๋์ฉ๋ ํธ๋ํฝ์ ์ฒ๋ฆฌํ๋ ํต์ฌ์ ๋ถ์ฐ๊ณผ ํจ์จํ๋ค.
๐ ํต์ฌ ํฌ์ธํธ:
- ๋ก๋ ๋ฐธ๋ฐ์๋ก ์์ฒญ์ ์ฌ๋ฌ ์๋ฒ์ ๋ถ์ฐ
- ์บ์ฑ์ผ๋ก DB ๋ถํ๋ฅผ 80% ์ด์ ๊ฐ์
- DB Replication์ผ๋ก ์ฝ๊ธฐ ์ฑ๋ฅ ํฅ์
- ๋ฉ์์ง ํ๋ก ๋ฌด๊ฑฐ์ด ์์ ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ
- CDN์ผ๋ก ์ ์ ํ์ผ์ ๋น ๋ฅด๊ฒ ์ ๊ณต
- ๋ชจ๋ํฐ๋ง์ผ๋ก ๋ณ๋ชฉ ์ง์ ์ ์ค์๊ฐ ํ์
๐ ๋จ๊ณ๋ณ ์ ์ฉ:
1๋จ๊ณ: ๋ก๋ ๋ฐธ๋ฐ์ + ์๋ฒ ์ฆ์ค
2๋จ๊ณ: Redis ์บ์ฑ ์ ์ฉ
3๋จ๊ณ: DB Replication ๊ตฌ์ฑ
4๋จ๊ณ: ๋ฉ์์ง ํ ๋์
5๋จ๊ณ: CDN ์ ์ฉ
์ฒ์๋ถํฐ ์๋ฒฝํ ์ํคํ
์ฒ๋ฅผ ๋ง๋ค ํ์๋ ์๋ค.
ํธ๋ํฝ์ด ์ฆ๊ฐํ๋ฉด์ ๋จ๊ณ์ ์ผ๋ก ๊ฐ์ ํด๋๊ฐ๋ ๊ฒ์ด ํ์ค์ ์ด๋ค.
์ค์ํ ๊ฒ์ ๋ณ๋ชฉ ์ง์ ์ ํ์
ํ๊ณ ์ฐ์ ์์๋ฅผ ์ ํด ํด๊ฒฐํ๋ ๊ฒ์ด๋ค.