성능을 위한 모범 사례
이 정보를 사용하여 IBM Cloud 에서 실행 중인 Databases for MongoDB 배포에 모범 사례를 적용하세요.
성능 문제 해결 순서도
순서도를 사용하여 성능 문제를 해결하는 방법과 다음에 수행할 단계를 결정하세요.
┌─────────────────────────────────┐
│ Performance issue detected │
└────────────┬────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Check IBM Cloud Monitoring │
│ - CPU > 80%? │
│ - Memory > 80%? │
│ - Disk latency high? │
└────────────┬────────────────────┘
│
┌────┴────┐
│ YES │
▼ │
┌──────────────┐ │
│ Scale │ │
│ resources │ │
└──────────────┘ │
│ NO
▼
┌─────────────────────┐
│ Check slow queries │
│ db.system.profile │
└─────────┬───────────┘
│
┌────┴────┐
│ Found? │
▼ │
┌─────────┐ │
│ Optimize│ │
│ queries │ │
│ & indexes│ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check Locks │
│ currentOp() │
└────────┬───────┘
│
┌────┴────┐
│ Locked? │
▼ │
┌─────────┐ │
│ Kill or │ │
│ optimize│ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check cache │
│ hit ratio │
└────────┬───────┘
│
┌────┴────┐
│ < 95%? │
▼ │
┌─────────┐ │
│ Scale │ │
│ memory │ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check │
│ replication │
└────────┬───────┘
│
┌────┴────┐
│ Lagging?│
▼ │
┌─────────┐ │
│ Scale │ │
│ or fix │ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Contact IBM │
│ Support │
└────────────────┘
일반적인 안티 패턴
성능 문제를 유발하는 이러한 일반적인 실수를 피하세요.
쿼리 안티 패턴
1. 누락된 인덱스
문제점:
// No index on 'email' field
db.users.find({ email: "user@example.com" })
해결 방법:
// Create index
db.users.createIndex({ email: 1 })
2. 비효율적인 정규식 쿼리
문제점:
// Case-insensitive regex without index
db.users.find({ name: /john/i })
해결 방법:
// Use text index or exact match
db.users.createIndex({ name: "text" })
db.users.find({ $text: { $search: "john" } })
3. 대규모 스킵() 연산
문제점:
// Skipping thousands of documents
db.collection.find().skip(10000).limit(10)
해결 방법:
// Use range queries with indexed field
db.collection.find({ _id: { $gt: lastSeenId } }).limit(10)
4. 불필요한 필드 선택
문제점:
// Fetching entire documents
db.users.find({ status: "active" })
해결 방법:
// Use projection
db.users.find({ status: "active" }, { name: 1, email: 1 })
5. 비효율적인 집계 파이프라인
문제점:
// $match after $lookup
db.orders.aggregate([
{ $lookup: { ... } },
{ $match: { status: "completed" } }
])
해결 방법:
// $match first to reduce documents
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $lookup: { ... } }
])
스키마 설계 문제
1. 무제한 배열
문제점:
// Array grows indefinitely
{
userId: 123,
activities: [/* thousands of items */]
}
해결 방법:
// Use separate collection or bucketing
{
userId: 123,
month: "2024-01",
activities: [/* limited items */]
}
2. 과도한 임베딩
문제점:
// Deeply nested documents
{
user: {
profile: {
settings: {
preferences: {
// many levels deep
}
}
}
}
}
해결 방법:
// Flatten or use references
{
userId: 123,
profileId: 456
}
3. 대용량 문서
문제점:
// Documents approaching 16MB limit
{
data: "very large string...",
attachments: [/* large binary data */]
}
해결 방법:
// Store large data separately (GridFS or object storage)
{
dataRef: "s3://bucket/key",
attachments: [{ ref: "gridfs://id" }]
}
연결 관리 실수
1. 연결 풀링을 사용하지 않음
문제점:
// Creating new connection per request
app.get('/api/users', async (req, res) => {
const client = await MongoClient.connect(uri);
// ...
await client.close();
});
해결 방법:
// Reuse connection pool
const client = new MongoClient(uri, { maxPoolSize: 50 });
await client.connect();
app.get('/api/users', async (req, res) => {
const db = client.db();
// ...
});
2. 커서를 닫지 않음
문제점:
// Cursor left open
const cursor = db.collection.find();
// Never closed
해결 방법:
// Always close cursors
const cursor = db.collection.find();
try {
await cursor.forEach(doc => { /* process */ });
} finally {
await cursor.close();
}
3. 너무 많은 연결
문제점:
// One connection per user session
const connections = new Map();
users.forEach(user => {
connections.set(user.id, new MongoClient(uri));
});
해결 방법:
// Share connection pool across application
const client = new MongoClient(uri);
// All users share the same pool
인덱싱의 함정
1. 인덱스가 너무 많습니다
문제점:
// Index on every field
db.collection.createIndex({ field1: 1 })
db.collection.createIndex({ field2: 1 })
db.collection.createIndex({ field3: 1 })
// ... 20+ indexes
Impact: 쓰기 속도가 느려지고 저장 공간이 증가합니다.
해결책: 필요한 인덱스만 유지하고 복합 인덱스를 사용하세요.
2. 복합 인덱스의 잘못된 인덱스 순서
문제점:
// Query: { status: "active", createdAt: { $gt: date } }
// Index: { createdAt: 1, status: 1 } // Wrong order
해결 방법:
// Correct order: equality first, range second
db.collection.createIndex({ status: 1, createdAt: 1 })
3. 적용 대상 쿼리를 사용하지 않음
문제점:
// Index exists but query not covered
db.users.createIndex({ email: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1 })
// Still fetches documents
해결 방법:
// Include all projected fields in index
db.users.createIndex({ email: 1, name: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1, _id: 0 })
부록: 메트릭 임계값
주요 성과 지표에 대한 권장 임계값입니다.
| 메트릭 | 경고 임계값 | 위험 임계값 | 권장 조치 |
|---|---|---|---|
| CPU 이용률 | 75% | 90% | CPU 코어 확장 |
| 메모리 사용률 | 80% | 95% | 메모리 할당 규모 조정 |
| 디스크 활용도 | 80% | 90% | 디스크 공간 확장 |
| 디스크 IOPS | 한도의 80% | 한도의 95% | 디스크 크기를 늘려 IOPS 향상 |
| 활성 연결 수 | 한도의 80% | 한도의 95% | 계획 확장 또는 연결 풀링 최적화 |
| 복제 지연 | 5초 | 30초 | 필요한 경우 조사 및 확장 |
| 캐시 적중률 | < 95% | < 90% | 메모리 확장 또는 쿼리 최적화 |
| 쿼리 실행 시간 | 100ms (평균) | 1000ms (평균) | 쿼리 및 인덱스 최적화 |
| 잠금 대기 시간 |
|
|
운영 최적화 및 장기 실행 쿼리 종료 |
| 페이지 결함 |
|
|
메모리 확장 |
| 네트워크 대기 시간 |
|
|
네트워크 구성 확인 |
| 백업 지속 기간 | 1시간 | 4시간 | 확장 또는 최적화 고려 |
모니터링 빈도 권장 사항
| 지표 범주 | 확인 빈도 | 보존 기간 |
|---|---|---|
| 자원 활용도 | 1분마다 | 30일 |
| 쿼리 성능 | 5분마다 | 14일 |
| 복제 상태 | 1분마다 | 30일 |
| 연결 통계 | 5분마다 | 14일 |
| 백업 상태 | 1시간마다 | 90일 |
| 디스크 증가 | 1시간마다 | 90일 |
알림 구성 예시
CPU 경고
Condition: CPU > 80% for 10 consecutive minutes
Action: Send notification to ops team
Escalation: Page on-call if > 90% for 15 minutes
메모리 경고
Condition: Memory > 85% for 15 consecutive minutes
Action: Send notification to ops team
Escalation: Auto-scale if > 95% for 10 minutes
복제 지연 경고
Condition: Lag > 10 seconds
Action: Send notification immediately
Escalation: Page on-call if > 60 seconds
디스크 공간 경고
Condition: Disk > 80%
Action: Send notification to ops team
Escalation: Create incident if > 90%
모범 사례 요약
| 영역 | 권장사항 |
|---|---|
| 색인화 | 사용하지 않는 인덱스를 정기적으로 검토하고 제거 |
| 모니터링 | CPU, 메모리, 디스크 및 복제 지연에 대한 알림을 구성하세요 |
| 용량 계획 | 디스크 사용량을 80% 미만으로 유지하고 선제적으로 확장하기 |
| 쿼리 디자인 | 개발 중 계획 설명 사용 |
| 스케일링 | 포화 전에 선제적으로 확장 |
| 연결 풀링 | 연결 풀을 사용하고 요청별 연결을 피하세요 |
| 읽기 환경설정 | 읽기량이 많은 워크로드에 보조 스토리지 사용 |
| 우려 사항 작성 | 내구성과 성능 요구 사항의 균형 |
| 스키마 디자인 | 무제한 배열 및 과도한 임베딩 방지 |
| 백업 계획 | 트래픽이 적은 기간의 일정 |
| 네트워크 | IBM Cloud 워크로드에 비공개 엔드포인트 사용 |
| 보안 | 자격 증명을 정기적으로 교체하고 IP 허용 목록 사용 |
| 문서 | 기준 지표 및 일반 패턴 문서화 |
| 테스트 | 비프로덕션 환경에서 먼저 성능 변경 사항 테스트 |
| 지원 | 지원팀에 문의하기 전에 진단 정보 수집 |