오늘도 공부
대규모 시스템 설계 블루프린트: 완벽 가이드 본문

안녕하세요! 오늘은 대규모 웹 서비스를 설계할 때 필요한 핵심 컴포넌트들을 하나하나 살펴보겠습니다. 실제 서비스에서 사용되는 아키텍처 패턴과 구체적인 예제를 함께 알아보죠.
1. DNS (Domain Name System)
구조
사용자가 www.example.com을 입력하면 다음과 같은 과정을 거칩니다:
- 권한있는 네임서버 (Authoritative Nameserver)
- 도메인의 실제 IP 주소를 관리
- 예: example.com → 12.34.56.78
- 최상위 도메인 네임서버 (TLD NS)
- .com, .net, .org 등의 TLD 관리
- AWS의 경우 Route 53이 이 역할 수행
- 루트 네임서버 (Root NS)
- DNS 계층 구조의 최상위
- 전 세계 13개의 루트 서버 클러스터 운영
실제 예제
# DNS 조회 과정
$ dig example.com
;; ANSWER SECTION:
example.com. 3600 IN A 93.184.216.34
2. 로드 밸런싱 (Load Balancing)
대용량 트래픽을 여러 서버로 분산시키는 핵심 컴포넌트입니다.
API Gateway
요청의 진입점 역할을 수행합니다.
주요 기능:
- 접근 로그 기록
- 인증/인가 처리
- WebSocket 및 Blacklisting
- Rate Control (속도 제한)
- 요청/응답 변환
- IP/헤더 검증
- TLS 종료
예제: Nginx 설정
upstream backend {
least_conn; # 최소 연결 알고리즘
server backend1.example.com weight=5;
server backend2.example.com weight=3;
server backend3.example.com;
}
server {
location /api/ {
proxy_pass http://backend;
proxy_set_header X-Real-IP $remote_addr;
}
}
Load Balancer (Main/Primary)
실제 트래픽 분산을 담당합니다.
라우팅 방식:
- Round Robin (순차 분산)
- Weighted Round Robin (가중치 기반)
- Least Connections (최소 연결)
- IP Hash (IP 기반 해싱)
예제 시나리오:
1분당 10,000개 요청 → Load Balancer
├─ Frontend Server 1: 3,000 requests
├─ Frontend Server 2: 3,500 requests
└─ Frontend Server 3: 3,500 requests
Frontend Servers
실제 웹/앱 서비스를 제공하는 서버입니다.
연결 방식:
- TCP/IP Connection
- HTTP/HTTPS
- WebSocket (실시간 통신)
- gRPC (마이크로서비스 간 통신)
3. CDN / Edge Servers
콘텐츠를 사용자와 가까운 위치에서 제공하여 속도를 향상시킵니다.
캐시 정책
Cache Miss:
- 원본 서버에서 콘텐츠 가져오기
- CDN 서버에 캐싱
- 사용자에게 전달
예제: CloudFlare 설정
// Cache-Control 헤더 설정
app.use((req, res, next) => {
// 정적 파일은 1일 캐싱
if (req.url.match(/\.(jpg|jpeg|png|css|js)$/)) {
res.setHeader('Cache-Control', 'public, max-age=86400');
}
next();
});
글로벌 배포 예제
서울 사용자 → 서울 Edge Server (지연시간: 10ms)
뉴욕 사용자 → 뉴욕 Edge Server (지연시간: 15ms)
런던 사용자 → 런던 Edge Server (지연시간: 12ms)
vs.
모든 사용자 → 서울 Origin Server
뉴욕: 180ms, 런던: 250ms
4. 스트리밍 및 채팅 서비스
실시간 스트리밍 아키텍처
Dispatcher (분배기)
- 사용자를 적절한 서버로 연결
- 서버 부하 모니터링
- 자동 스케일링 트리거
Frontend Server (앱/웹 UI)
- setRTCPeerConnection과 같은 WebRTC API 사용
- 실시간 통신 설정
예제: WebRTC 연결
// 스트리밍 시작
const peerConnection = new RTCPeerConnection(config);
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
stream.getTracks().forEach(track => {
peerConnection.addTrack(track, stream);
});
스트리밍 메타데이터 테이블
CREATE TABLE streaming_chunk_metadata (
chunk_id VARCHAR(50) PRIMARY KEY,
user_id VARCHAR(50),
timestamp BIGINT,
checksum VARCHAR(64)
);
-- 예제 데이터
INSERT INTO streaming_chunk_metadata VALUES
('chunk_1', 'user123', 1633072653, 'a8f7d...');
5. 메시지 큐 시스템
Dispatcher의 역할
서버 간 메시지를 효율적으로 전달합니다.
메시지 흐름:
User A (채팅) → Frontend Server
→ Dispatcher
→ Obj1, Obj2, Obj3 (분산 저장)
→ 타 Frontend Servers
→ User B, C, D (수신)
6. 객체 스토리지
업로드 프로세스
사용자 업로드 → Frontend Server
→ Object Storage (S3/Cloud)
→ 처리 완료 후 URL 반환
예제: AWS S3 업로드
import boto3
s3 = boto3.client('s3')
# 파일 업로드
s3.upload_file(
'local_image.jpg',
'my-bucket',
'uploads/user123/image.jpg'
)
# Public URL 생성
url = f"https://my-bucket.s3.amazonaws.com/uploads/user123/image.jpg"
이미지/비디오 처리 파이프라인
- 업로드 검증
- 파일 크기 확인
- 포맷 검증
- 바이러스 스캔
- 처리 워커
- 이미지 압축
- 썸네일 생성
- 메타데이터 추출
- 로그 처리
- 업로드 이벤트 기록
- 분석 데이터 수집
예제: 이미지 처리 워커
from PIL import Image
def process_image(input_path, output_path):
# 이미지 열기
img = Image.open(input_path)
# 리사이징 (최대 1920x1080)
img.thumbnail((1920, 1080))
# 압축하여 저장
img.save(output_path, optimize=True, quality=85)
# 썸네일 생성 (300x300)
img.thumbnail((300, 300))
img.save(output_path.replace('.jpg', '_thumb.jpg'))
7. 데이터베이스 전략
Primary Database
저장 데이터:
- RDBMS (MySQL, PostgreSQL)
- Column-store (Cassandra)
- Document DB (MongoDB)
- Key-Value (Redis)
- Graph (Neo4j)
- Time-series (InfluxDB)
샤딩 전략
Range-based Sharding (범위 기반)
User ID 1-100,000 → Shard 1
User ID 100,001-200,000 → Shard 2
User ID 200,001-300,000 → Shard 3
Hash-based Sharding (해시 기반)
def get_shard(user_id, num_shards=4):
return hash(user_id) % num_shards
# 예제
get_shard('user_12345', 4) # → Shard 2
Directory-based Sharding
{
"user_12345": "shard_2",
"user_67890": "shard_1",
"user_11111": "shard_3"
}
데이터베이스 예제
-- 사용자 테이블 (Shard 1)
CREATE TABLE users_shard_1 (
user_id VARCHAR(50) PRIMARY KEY,
username VARCHAR(100),
email VARCHAR(255),
created_at TIMESTAMP
);
-- 인덱스 생성
CREATE INDEX idx_email ON users_shard_1(email);
CREATE INDEX idx_created ON users_shard_1(created_at);
8. 캐시 시스템
캐시 전략
1. Eviction Policies (제거 정책)
- LRU (Least Recently Used): 가장 오래 사용되지 않은 항목 제거
- LFU (Least Frequently Used): 가장 적게 사용된 항목 제거
- FIFO: 먼저 들어온 항목 제거
- Random: 무작위 제거
예제: Redis 캐싱
import redis
cache = redis.Redis(host='localhost', port=6379)
# 캐시 설정 (10분 TTL)
cache.setex('user:12345', 600, json.dumps(user_data))
# 캐시 조회
cached = cache.get('user:12345')
if cached:
user_data = json.loads(cached)
else:
# DB에서 조회
user_data = db.query('SELECT * FROM users WHERE id=12345')
cache.setex('user:12345', 600, json.dumps(user_data))
Write-Through vs Write-Around
Write-Through:
데이터 쓰기 → Cache → Database
(캐시와 DB 동시 업데이트)
Write-Around:
데이터 쓰기 → Database만 업데이트
캐시는 읽을 때 업데이트
예제 코드:
def write_through(key, value):
# 캐시에 먼저 쓰기
cache.set(key, value)
# DB에 쓰기
db.write(key, value)
def write_around(key, value):
# DB에만 쓰기
db.write(key, value)
# 캐시는 무효화
cache.delete(key)
9. 시스템 확장 서비스
Distributed ID Generator
고유 ID를 생성하는 서비스입니다.
예제: Snowflake ID
64비트 구조:
- 1비트: 부호 (항상 0)
- 41비트: 타임스탬프
- 10비트: 워커 ID
- 12비트: 시퀀스 번호
예: 1234567890123456789
def generate_snowflake_id(worker_id, sequence):
timestamp = int(time.time() * 1000)
id = (timestamp << 22) | (worker_id << 12) | sequence
return id
# 사용 예
user_id = generate_snowflake_id(worker_id=5, sequence=100)
Backend Servers (클러스터/마이크로서비스)
Load/Time/Queries 처리:
- 스케일 아웃으로 서버 추가
- Leader + Follower 구조
- Consensus 알고리즘 (Raft, Paxos)
예제: 마이크로서비스 구조
User Service (Port 8001)
├─ GET /users/:id
└─ POST /users
Order Service (Port 8002)
├─ GET /orders/:id
└─ POST /orders
Payment Service (Port 8003)
├─ POST /payments
└─ GET /payments/:id
10. 공통 팬아웃 서비스
Payment / Charge Service
제3자 결제 서비스 연동:
- 결제 게이트웨이 통합
- PG사 API 연동
- 환불/취소 처리
예제: 결제 플로우
// 결제 요청
async function processPayment(orderId, amount) {
try {
// 1. 결제 정보 검증
const order = await validateOrder(orderId);
// 2. PG사 결제 요청
const payment = await pgGateway.charge({
amount: amount,
orderId: orderId,
method: 'card'
});
// 3. 결제 결과 저장
await savePayment(payment);
// 4. 주문 상태 업데이트
await updateOrderStatus(orderId, 'paid');
return { success: true, paymentId: payment.id };
} catch (error) {
// 에러 처리 및 로깅
logger.error('Payment failed', { orderId, error });
return { success: false, error: error.message };
}
}
Analytics Service
사용자 행동 분석 및 비즈니스 인텔리전스를 제공합니다.
수집 데이터:
- 페이지 뷰
- 클릭 이벤트
- 구매 전환율
- 사용자 세션
예제: 이벤트 트래킹
// 프론트엔드 이벤트 전송
analytics.track('Product Viewed', {
productId: 'prod_123',
productName: 'Wireless Headphones',
price: 99.99,
category: 'Electronics'
});
// 백엔드 처리
app.post('/api/analytics/track', async (req, res) => {
const event = req.body;
// 실시간 처리
await kafka.send('analytics-events', event);
// 배치 처리를 위해 저장
await analyticsDB.insert(event);
res.status(200).send({ tracked: true });
});
Search Service (검색)
효율적인 검색 기능을 제공합니다.
검색 엔진:
- Elasticsearch
- Apache Solr
- Algolia
예제: Elasticsearch 검색
from elasticsearch import Elasticsearch
es = Elasticsearch(['localhost:9200'])
# 인덱스 생성
es.indices.create(index='products', body={
'mappings': {
'properties': {
'name': {'type': 'text'},
'description': {'type': 'text'},
'price': {'type': 'float'},
'category': {'type': 'keyword'}
}
}
})
# 검색 쿼리
results = es.search(index='products', body={
'query': {
'multi_match': {
'query': '무선 이어폰',
'fields': ['name', 'description']
}
}
})
for hit in results['hits']['hits']:
print(f"상품: {hit['_source']['name']}")
print(f"가격: {hit['_source']['price']}원")
Notification Service
다양한 채널로 알림을 전송합니다.
알림 채널:
- 이메일
- SMS
- 푸시 알림 (FCM, APNs)
- 인앱 메시지
예제: 푸시 알림 전송
from firebase_admin import messaging
def send_push_notification(user_token, title, body):
message = messaging.Message(
notification=messaging.Notification(
title=title,
body=body
),
token=user_token,
data={
'type': 'order_update',
'order_id': '12345'
}
)
response = messaging.send(message)
return response
# 사용 예
send_push_notification(
user_token='device_token_abc123',
title='주문 완료',
body='주문이 성공적으로 완료되었습니다!'
)
Recommendation Service
개인화된 추천을 제공합니다.
추천 알고리즘:
- 협업 필터링 (Collaborative Filtering)
- 콘텐츠 기반 필터링
- 하이브리드 방식
예제: 간단한 추천 시스템
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
def get_recommendations(user_id, user_item_matrix):
# 사용자 간 유사도 계산
user_similarity = cosine_similarity(user_item_matrix)
# 현재 사용자와 유사한 사용자 찾기
similar_users = user_similarity[user_id].argsort()[-5:]
# 추천 아이템 생성
recommendations = []
for similar_user in similar_users:
# 유사 사용자가 좋아한 아이템 중
# 현재 사용자가 보지 않은 것 추천
items = user_item_matrix[similar_user]
recommendations.extend(items)
return recommendations[:10] # 상위 10개 추천
11. 보안 및 모니터링
Third-Party Banking Service
기능:
- 계좌 인증
- 송금 처리
- 거래 내역 조회
보안 체크리스트:
- TLS/SSL 암호화
- API 키 관리
- IP 화이트리스트
- 거래 한도 설정
로그 처리 파이프라인
Application Logs
↓
Log Collector (Fluentd/Logstash)
↓
Message Queue (Kafka)
↓
Processing (Spark/Flink)
↓
Storage (Elasticsearch)
↓
Visualization (Kibana/Grafana)
예제: 로그 수집 설정
# Fluentd 설정
<source>
@type tail
path /var/log/app/*.log
pos_file /var/log/td-agent/app.log.pos
tag app.logs
<parse>
@type json
</parse>
</source>
<match app.logs>
@type elasticsearch
host elasticsearch.local
port 9200
index_name app-logs
type_name _doc
</match>
마치며
이 블루프린트는 대규모 시스템을 설계할 때 고려해야 할 핵심 컴포넌트들을 포괄적으로 다루고 있습니다. 실제 서비스를 구축할 때는 다음을 기억하세요:
핵심 원칙
- 확장성 (Scalability): 수평 확장이 가능한 구조
- 가용성 (Availability): 장애 시에도 서비스 유지
- 성능 (Performance): 빠른 응답 속도
- 보안 (Security): 데이터 보호 및 접근 제어
- 모니터링 (Monitoring): 실시간 시스템 상태 파악
시작 단계별 가이드
MVP 단계 (사용자 < 1,000)
- 단일 서버 + DB
- 기본 캐싱 (Redis)
- CDN 설정
성장 단계 (사용자 10,000+)
- 로드 밸런서 추가
- DB 리플리케이션
- 객체 스토리지 분리
대규모 단계 (사용자 100,000+)
- 마이크로서비스 전환
- DB 샤딩
- 다중 리전 배포
- 고급 캐싱 전략
각 단계에서 비즈니스 요구사항과 기술적 제약사항을 고려하여 점진적으로 시스템을 발전시켜 나가세요!
참고 자료:
- AWS Architecture Center
- Google Cloud Architecture Framework
- Microsoft Azure Well-Architected Framework
- System Design Primer (GitHub)
'개발상식' 카테고리의 다른 글
| 2025년 기준 주요 Vercel 대체 플랫폼들의 장단점 (0) | 2025.10.25 |
|---|---|
| 프로그래밍 기본기가 주는 불공평한 경쟁력 (0) | 2025.10.01 |
| 시리즈 5편 – Git에서 자주 보는 기호와 패턴 (0) | 2025.08.19 |
| 시리즈 4편 – 리눅스 터미널에서 자주 쓰이는 기호들 (0) | 2025.08.19 |
| 시리즈 3편 – 정규표현식(RegExp)의 핵심 기호들 (1) | 2025.08.19 |
