MongoDB in Action – My AI Smarteasy 코파일럿 에이전트 – 일타 저스틴과 책 읽기
📖 1강: 차세대 데이터베이스 세계 이해하기! 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 1장 “Understanding the world of MongoDB”를 함께 공부하는 1강입니다. 저자분께서 MongoDB의 세계로 여러분을 안내해주시는 이 장은, 데이터베이스 기술의 혁명적인 변화를 이해하는 출발점이에요. 책을 펼치고 함께 따라오시면서 핵심을 체크하시죠!
🎯 저자분의 핵심 메시지: 차세대 데이터베이스의 등장
“The landscape of database technology is undergoing a significant transformation, ushering in an era of next-generation databases designed to meet the evolving demands of modern applications.”
저자분께서 말씀하시는 핵심은 ‘다음 세대 데이터베이스’의 등장인데요! 전통적인 데이터베이스가 한계를 보이는 가운데, 유연성, 확장성, 성능에서 압도적인 MongoDB가 등장했다는 거예요. 제가 쉽게 풀어보면, 마치 스마트폰이 피처폰을 대체한 것처럼 데이터베이스도 NoSQL 문서 데이터베이스로 진화하고 있는 거죠. 전자상거래, 채팅 앱, 실시간 주식 앱 등 현대 애플리케이션의 요구사항을 충족하는 강력한 무기랍니다!
💡 1.1 문서 지향 데이터 모델 탐구하기
저자분은 이렇게 강조하셨어요:
“Document databases cater to this need by enabling direct storage of objects without significant data transformation, simplifying the persistence process.”
여기서 포인트! 현대 개발에서 ‘지속성(Persistence)’이 핵심인데, 객체(고객, 송장 등)를 변환 없이 그대로 저장할 수 있다는 거예요. 전통 RDB는 테이블로 바꿔야 하지만, MongoDB는 BSON(Binary JSON)으로 객체를 그대로 보관하죠. JSON에 없는 날짜, 이진 데이터까지 지원해서 더 강력해요!
| RDB (관계형) | MongoDB (문서형) |
|---|---|
| 고정 스키마 | 유연 스키마 |
| 복잡한 조인 필요 | 중첩 문서로 한 번에 |
| 느린 개발속도 | 빠른 개발 + 확장 |
|
1 2 3 4 5 6 7 8 |
// 책 Listing 1.1 예시 문서 { "_id": 1, "title": "MongoDB 8.0 in Action", "focusAreas": ["MongoDB Database System", "Atlas Platform"], "additionalDetails": { "embeddedDocument": { "description": "..." } } } |
이런 구조로 관련 데이터를 한 곳에 모아 읽기 작업을 줄이고 성능을 높이는 거예요!
MQL 쿼리 예시 (책 참고):
|
1 2 3 4 5 6 7 |
// 책 찾기 db.books.find({ "title": "MongoDB 8.0 in Action" }) // 출판사 업데이트 db.books.updateOne({ "title": "MongoDB 8.0 in Action" }, { $set: { "publisher": "Manning Publications Co" } }) |
💡 1.2 수평 확장: 샤딩 클러스터 이해하기
“MongoDB is optimized for scaling out, using its document-oriented model to efficiently distribute data across multiple servers.”
저자분의 주장! 데이터가 TB급으로 커질 때 ‘스케일 아웃(Scale Out)’이 답입니다. MongoDB는 샤딩(Sharding)으로 데이터를 여러 서버에 자동 분산해요. 문서가 독립적이어서 조인 걱정 없이 빠르게 처리하죠.
샤딩 아키텍처 핵심 구성요소:
- 몽고스(Mongos): 쿼리 라우터 (30개 이하 권장)
- 설정 서버(Config Servers): 메타데이터 관리 (Replica Set)
- 샤드(Shard): 실제 데이터 저장 (각각 Replica Set)
- MongoDB 8.0 신기능: 설정 서버를 샤드와 통합 가능!
Figure 1.1을 보시면 명확해질 거예요. 데이터가 커질수록 서버만 추가하면 자동 균형!
💡 1.3 MongoDB 생태계: 서버 + Atlas 완전 분석
저자분이 소개하는 MongoDB 에디션:
- Community Edition: 무료, 기본 기능 완벽
- Enterprise Advanced: 보안 강화, Ops Manager 등
핵심 서버 기능 TOP 6:
- 인덱스: 복합, 지리공간, 텍스트 등
- 집계 프레임워크: GROUP BY 비슷
- 변경 스트림: 실시간 데이터 변화 감지
- TTL 인덱스: 자동 만료
- 특수 컬렉션: Capped, Partial
- 시계열 컬렉션: 로그/메트릭스 최적화
Atlas 독점 기능 (Figure 1.2):
- Atlas Search: Lucene 기반 풀텍스트
- Vector Search: AI RAG 필수!
- Stream Processing: 실시간 스트림
- SQL Interface: 익숙한 SQL 사용
📌 저스틴의 1장 정리
첫째, 저자분의 주장대로 문서 모델 + BSON + 유연 스키마로 개발 효율성과 성능을 극대화합니다.
둘째, 샤딩 클러스터로 TB급 데이터도 문제없이 수평 확장, MongoDB 8.0 통합 기능까지!
셋째, Community/Enterprise + Atlas 플랫폼으로 단순 DB를 넘어 개발 생애주기 전체 지원.
💪 오늘의 실천 과제
책 22페이지 Listing 1.1 문서를 복사해서 MongoDB Atlas Free Tier에 넣어보고, 책의 3가지 쿼리(find, updateOne, deleteMany)를 직접 실행해보세요! “db.books.find()” 한 번만!
윈도우에 MongoDB 설치:
- 단계 1: 공식 다운로드 페이지 방문
브라우저에서 https://www.mongodb.com/try/download/community 접속. MongoDB Community Server Download에서 플롯폼을 Windows x64 선택하고 설치 프로그램 실 - 단계 2: MSI 설치 프로그램 실행
다운로드한 설치 파일 더블 클릭.
설치 마법사에서 “Next” 진행.- License Agreement 동의.
- Installation Type: “Complete” 선택 (기본 설치 권장).
- Service Configuration: “Install MongoDB as a Service” 체크 (자동 시작 설정).
- MongoDB 사용자 생성 또는 기존 사용자 선택.
- “Install MongoDB Compass” 체크 (GUI 도구 옵션, 선택사항).
“Install” 클릭하여 설치 완료 (관리자 권한 필요).
- 단계 3: 환경 변수 PATH 추가
설치 경로 확인 (기본: C:\Program Files\MongoDB\Server\8.2\bin).
Windows 검색에서 “환경 변수 편집” 입력 → 시스템 환경 변수 편집.
Path 변수 선택 → 편집 → 새로 추가: C:\Program Files\MongoDB\Server\8.2\bin.
확인 후 명령 프롬프트 재시작. - 단계 4: MongoDB 서비스 시작 및 테스트
명령 프롬프트(관리자) 열기.
services.msc 실행하여 “MongoDB” 서비스 확인 및 시작.
또는 명령어: net start MongoDB.
테스트: mongod –version (버전 확인), mongosh (셸 실행, exit로 종료). - Required resources:
- Windows 10/11 (64-bit).
- 인터넷 연결 (다운로드용).
- 관리자 권한.
- 약 500MB 디스크 공간.
📖 MongoDB in Action 2강: Atlas 첫 클러스터 만들기 + 데이터 관리 완전 정복! 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 2장 “Getting started with Atlas and MongoDB data”를 함께 공부하는 2강입니다. 저자분께서 여러분의 손으로 첫 Atlas 클러스터를 만드는 실습 가이드를 제공해 주셨어요! 책을 펼치고 터미널을 열어두시고 함께 따라오세요. 이 강의를 끝내면 여러분도 실제 MongoDB Atlas에서 데이터를 다룰 수 있게 됩니다!
🎯 저자분의 핵심 메시지: 실습으로 배우는 Atlas 플랫폼
“The quickest approach to establish a MongoDB Atlas database cluster is by leveraging the Atlas Command Line Interface (CLI).”
저자분께서 말씀하시는 핵심은 Atlas CLI로 5분만에 클러스터 완성이라는 거예요! 웹 UI보다 빠르고 강력한 CLI를 통해 조직, 프로젝트, 클러스터를 순서대로 만들고 샘플 데이터를 로드하는 실습 과정이죠. 제가 쉽게 풀어보면, 마치 레고 블록 쌓기처럼 단계별로 Atlas 환경을 구축하는 과정입니다!
💡 2.1 Atlas CLI로 첫 클러스터 만들기 (핵심 실습 순서)
저자분이 제시한 단계별 명령어 순서를 따라가 보세요:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 1️⃣ Atlas CLI 설치 (Homebrew) brew install mongodb-atlas # 2️⃣ 계정 등록 & 로그인 atlas auth register atlas login # 3️⃣ 조직 만들기 (회사명처럼) atlas organizations create "Manning Publications" atlas config set org_id [ORGANIZATION_ID] # 4️⃣ 프로젝트 만들기 atlas project create "MongoDB 8.0 in Action" atlas config set project_id [PROJECT_ID] # 5️⃣ 무료 클러스터 생성 (5분 소요!) atlas cluster create "MongoDB-in-Action" --provider GCP --region CENTRAL_US --tier M0 |
핵심 팁! atlas config describe default로 설정 확인하고, Figure 2.1처럼 Atlas UI에서 클러스터 상태를 실시간 모니터링하세요!
💡 2.2 샘플 데이터 로드 + 네트워크/사용자 설정
|
1 2 3 4 5 6 7 8 9 |
# 샘플 데이터 로드 (연습용 10개 DB 생성) atlas clusters sampleData load "MongoDB-in-Action" # IP 주소 추가 (연결 허용) atlas accessList create --currentIp # 관리자 사용자 생성 atlas dbusers create --role atlasAdmin --username manning |
| Database | 내용 |
|---|---|
| sample_airbnb | 에어비앤비 숙소 정보 |
| sample_mflix | 영화 데이터 |
| sample_training | MongoDB 연습용 |
Figure 2.2에서 Data Explorer로 확인해보세요!
💡 2.5 mongosh 연결 & 데이터 구조 이해하기
|
1 2 3 4 5 6 7 8 9 10 |
# mongosh 설치 brew install mongosh # 연결 문자열 가져오기 atlas clusters connectionStrings describe "MongoDB-in-Action" # 연결 (Listing 2.1) mongosh "mongodb+srv://mongodb-in-action.fpomkk.mongodb.net" \ --apiVersion 1 --username 'manning' |
연결 후 바로 실행:
|
1 2 3 4 5 |
show dbs // 10개 샘플 DB 확인 use sample_mflix // DB 전환 show collections // 컬렉션 목록 db.movies.findOne() // 첫 문서 확인 |
💡 2.6 데이터 관리 3단계 계층 완전 분석
저자분의 구조 설명:
“MongoDB structures data into a hierarchy consisting of three levels: databases → collections → documents.”
| RDB | MongoDB |
|---|---|
| Database → Table → Row → Column | Database → Collection → Document |
🔹 동적 스키마의 장단점
|
1 2 3 4 |
// 같은 컬렉션에 다른 구조 가능 { "title": "MongoDB 8.0 in Action" } { "name": "MongoDB 8.0 in Action", "author": "저자" } |
베스트 프랙티스: 비슷한 구조끼리 같은 컬렉션에 저장!
🔹 특별 컬렉션들
1. Capped Collection (고정 크기 원형 버퍼)
|
1 2 |
db.createCollection("logs", { capped: true, size: 1000000 }) |
로그, 캐시용 최적! 오래된 데이터 자동 삭제.
2. Time Series Collection (시계열 데이터 특화)
|
1 2 3 4 5 6 7 8 |
// Listing 2.4 db.createCollection("weather", { timeseries: { timeField: "timestamp", metaField: "sensor_id" } }) |
IoT, 주식, 로그에 딱! 디스크 50% 절약.
3. View (가상 읽기 전용 컬렉션)
|
1 2 3 4 5 |
// Listing 2.6 db.createView("aerocondorRoutesView", "routes", [ { $match: { "airline.id": 410 } } ]) |
📌 저스틴의 2장 정리
첫째, 저자분의 CLI 실습대로 Atlas 계정 → 조직 → 프로젝트 → M0 무료 클러스터를 5분만에 완성하고 샘플 데이터 로드!
둘째, mongosh 연결로 show dbs, use, show collections 기본 명령어 익히고 3단계 계층(Database→Collection→Document) 완벽 이해.
셋째, Capped/Time Series/View 등 특별 컬렉션으로 로그, 시계열, 가상 뷰까지 MongoDB의 진짜 힘을 경험!
💪 오늘의 실천 과제
지금 바로 2.1~2.5 순서대로 실행해서 “MongoDB-in-Action” 클러스터를 만들고, mongosh 접속 후 sample_mflix.movies.findOne() 실행! 스크린샷 찍어서 다음 강의 전 공유 부탁드려요!
📖 MongoDB in Action 3강: mongosh 커스터마이징 + Node/Python/Ruby 드라이버 완전 마스터! 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 3장 “Communicating with MongoDB”를 함께 공부하는 3강입니다. 저자분께서 MongoDB와 소통하는 모든 방법을 알려주셨어요! mongosh 고급 설정부터 Node.js, Python, Ruby 드라이버까지 실습하며 어떤 언어로도 MongoDB 연결하는 법을 완벽히 익히세요. 책 펼치고 터미널 열어두시고 따라오세요!
🎯 저자분의 핵심 메시지: Wire Protocol이 모든 소통의 기반
“MongoDB communication relies on the MongoDB Wire Protocol, which serves as the backbone for data exchange between MongoDB clients and servers.”
저자분께서 말씀하시는 핵심은 MongoDB Wire Protocol(OP_MSG)이 모든 클라이언트-서버 소통의 뼈대라는 거예요! TCP/IP 27017 포트를 통해 little-endian 바이트 순서로 데이터를 주고받죠. 제가 쉽게 풀어보면, 마치 우체국 배달 시스템처럼 구조화된 메시지(헤더+플래그+섹션+체크섬)로 효율적으로 데이터를 전달하는 거예요!
💡 3.2 mongosh 완전 정복: 커스터마이징 & 스크립팅
저자분이 강조한 mongosh의 강력함:
- 문법 하이라이팅 + 자동완성 + 컨텍스트 헬프
- JavaScript REPL + Node.js API 완전 지원
🔹 연결 명령어 (2장 클러스터 사용)
|
1 2 3 4 5 6 7 |
# Atlas 연결 (SRV 문자열) mongosh "mongodb+srv://manning@mongodb-in-action.xxx.mongodb.net/" \ --apiVersion 1 # 로컬 연결 mongosh "mongodb://localhost:27017" --username book --authenticationDatabase admin |
🔹 기본 명령어 (Listing 3.1)
|
1 2 3 4 5 6 |
db // 현재 DB show dbs // DB 목록 use sample_training // DB 전환 show collections // 컬렉션 목록 db.help() // DB 메서드 도움말 |
🔹 고급 스크립팅 (Listing 3.2)
|
1 2 3 4 5 6 7 8 |
// mongodb-script.js 저장 후 실행 load("/scripts/mongodb-script.js") // 결과 예시 MongoDB Version: 8.0.3 Uptime: 11 hours Currently open connections: 5 |
🔹 mongosh 설정 변경 (Listing 3.3)
|
1 2 3 4 |
config.get("historyLength") // 현재값 확인 config.set("historyLength", 3000) // 3000개로 변경 config.set("editor", "vi") // 에디터 설정 |
🔹 .mongoshrc.js로 프롬프트 커스터마이징 (Listing 3.4)
|
1 2 3 4 5 |
// ~/.mongoshrc.js에 추가 prompt = function() { return "Ver:" + db.version() + " | Cols:" + db.getCollectionNames().length + " > "; }; |
💡 3.3 MongoDB Compass: GUI로 데이터 시각화
Figure 3.1, 3.2 핵심 기능:
- 쿼리 빌더 + 집계 파이프라인 빌더
- 스키마 분석 + 성능 프로파일링 + 인덱스 관리
- GenAI 쿼리 생성 (자연어로 쿼리 자동 생성!)
연결 방법: 2장의 Atlas 연결문자열 그대로 사용 → “MongoDB-in-Action” 저장
💡 3.4~3.7 드라이버 실습: Node.js/Python/Ruby
저자분이 제공한 JFK 출발 항공편 쿼리를 각 언어로 실행해보세요!
🔹 Node.js 드라이버 (Listing 3.6)
|
1 2 3 |
mkdir mongodb_book_project && cd mongodb_book_project npm init -y && npm install mongodb@6.5 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// index.js (연결문자열 교체 후) const { MongoClient } = require("mongodb"); const uri = "mongodb+srv://manning:..."; // Atlas 연결문자열 const client = new MongoClient(uri); async function run() { const database = client.db("sample_training"); const routes = database.collection("routes"); const route = await routes.findOne({ src_airport: "JFK", "airline.id": 3201 }); console.log(route); } run().finally(() => client.close()); |
|
1 2 |
node index.js |
🔹 Python PyMongo (동기, Listing 3.8)
|
1 2 |
pip install pymongo |
|
1 2 3 4 5 6 7 8 9 10 |
# mongodb-pymongo.py from pymongo import MongoClient from pymongo.server_api import ServerApi client = MongoClient(uri, server_api=ServerApi('1')) routes = client['sample_training']['routes'] route = routes.find_one({"src_airport": "JFK", "airline.id": 3201}) print(route) client.close() |
🔹 Python Motor (비동기, Listing 3.10)
|
1 2 |
pip install motor |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# mongodb-motor.py import asyncio from motor.motor_asyncio import AsyncIOMotorClient async def find_route(): client = AsyncIOMotorClient(uri, server_api=ServerApi('1')) route = await client['sample_training']['routes'].find_one( {"src_airport": "JFK", "airline.id": 3201} ) print(route) client.close() asyncio.run(find_route()) |
🔹 Ruby 드라이버 (Listing 3.11)
|
1 2 |
gem install mongo |
|
1 2 3 4 5 6 7 8 |
# mongodb-ruby.rb require 'mongo' client = Mongo::Client.new(uri) routes = client[:sample_training][:routes] route = routes.find('src_airport' => 'JFK').first puts route client.close |
|
1 2 |
ruby mongodb-ruby.rb |
| PyMongo | Motor |
|---|---|
| 동기(Blocking) | 비동기(Non-blocking) |
| 간단한 스크립트 | 웹서버/고부하 |
📌 저스틴의 3장 정리
첫째, 저자분의 Wire Protocol + mongosh 완전 커스터마이징(.mongoshrc.js, config.set)으로 효율적인 CLI 환경 구축!
둘째, Compass GUI로 시각적 데이터 탐색 + 집계 파이프라인 빌더 체험!
셋째, Node.js/PyMongo/Motor/Ruby 4개 드라이버 실습으로 JFK 쿼리 성공 → 어떤 언어든 MongoDB 연결 가능!
💪 오늘의 실천 과제
Node.js 프로젝트 생성 → JFK 쿼리 실행 → 결과 스크린샷! 추가로 mongosh에서 .mongoshrc.js 만들어서 커스텀 프롬프트 적용해보세요. 다음 강의 전 공유 부탁드려요!
📖 MongoDB in Action 5강: 스키마 디자인 완전 가이드! 패턴 13가지 + 검증 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 5장 “Designing MongoDB schema”를 함께 공부하는 5강입니다. 저자분께서 MongoDB의 유연한 스키마 철학부터 13가지 디자인 패턴, 스키마 검증까지 완벽한 로드맵을 제시해 주셨어요! RDB와 완전히 다른 ‘읽기 최적화 설계’ 원리를 익히고 실제 적용해보세요. 책 펼치고 노트 준비하세요!
🎯 저자분의 핵심 메시지: 읽기 패턴에 맞춘 스키마 설계
“MongoDB’s data model should be designed based on how the data will be displayed and accessed, rather than how it is logically connected.”
저자분께서 말씀하시는 핵심은 RDB ≠ MongoDB 설계법이라는 거예요! RDB는 ‘정규화+조인’, MongoDB는 ‘읽기 패턴 최적화+임베딩’이 답입니다. 제가 쉽게 풀어보면, 마치 자주 보는 옷은 옷장 앞자리에, 덜 입는 옷은 뒤로 정리하는 것처럼 데이터도 자주 조회하는 패턴에 맞춰 구조화하는 거죠!
💡 5.1 스키마 설계 4단계 프로세스
저자분의 항공편 관리 시스템 예시로 실습:
🔹 1단계: 워크로드 분석 (Table 5.1)
| 액션 | 타입 | 정보 | 빈도 | 우선순위 |
|---|---|---|---|---|
| 새 노선 추가 | Write | airline, airports | 150/일 | High |
| 노선 검색 | Read | src/dst_airport | 22,000/일 | High |
| 노선 정보 확인 | Read | airplane, stops | 40,000/일 | High |
핵심: 읽기 99% → 읽기 최적화 설계!
🔹 2단계: 관계 매핑
|
1 2 3 |
항공사 1:N 노선 → 임베딩 (항공사 정보 routes에 포함) 공항 M:N 노선 → 참조 (별도 airports 컬렉션) |
샘플 문서:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// routes 컬렉션 (임베딩) { airline: { id: 410, name: "Delta", alias: "2B" }, // 자주 조회 → 임베딩 src_airport: "JFK", dst_airport: "LAX" } // airports 컬렉션 (참조) { _id: "JFK", name: "JFK International Airport", facilities: ["Wi-Fi", "Lounge"] } |
💡 5.3 13가지 스키마 디자인 패턴 완전 분석
저자분이 제시한 Figure 5.3 핵심 패턴들:
🔥 TOP 5 필수 패턴
1. Subset 패턴 (공항 이름만 임베딩)
|
1 2 3 4 5 6 7 |
{ src_airport: { code: "JFK", name: "JFK International Airport" // 자주 조회되는 부분만 } } |
2. Computed 패턴 (사전 계산)
|
1 2 3 4 5 6 |
{ _id: "JFK", total_flights: 3500, // 실시간 계산X → 쓰기시 계산 facilities: ["Wi-Fi"] } |
3. Bucket 패턴 (시계열 버킷)
|
1 2 3 4 5 6 7 8 9 |
{ sensor_id: "abc123", date: "2024-04-20", readings: [ // 하루치 데이터 묶음 {"time": "08:00", "value": 22.5}, {"time": "08:05", "value": 22.7} ] } |
4. Attribute 패턴 (희귀 속성 배열화)
|
1 2 3 4 5 6 7 8 |
{ common: { name: "Laptop", price: 1200 }, rare_attributes: [ // 드문 속성만 배열 {key: "rgb_lighting", value: true}, {key: "military_cert", value: "MIL-STD"} ] } |
5. Extended Reference (참조+필요 필드 임베딩)
|
1 2 3 4 5 6 7 |
{ post_id: "789", user: { // 참조하면서 핵심 정보만 임베딩 user_id: "555", name: "Alex", role: "admin" } } |
💡 5.4 스키마 검증: 데이터 품질 보장 실습
🔹 JSON Schema 적용 (Listing 5.1)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
db.runCommand({ collMod: "routes", validator: { $jsonSchema: { bsonType: "object", required: ["flight_id", "airline", "src_airport", "dst_airport"], properties: { flight_id: { bsonType: "string", pattern: "^FL\\d+$", // FL123 형식 강제 description: "FL로 시작하는 숫자" }, "airline.id": { bsonType: "int", minimum: 1 // 양수만 허용 } } } }, validationLevel: "moderate", // 기존 문서 무시 validationAction: "error" // 위반시 차단 }) |
🔹 테스트: 잘못된 데이터 차단
|
1 2 3 4 5 6 7 |
// 이건 실패! db.routes.insertOne({ flight_id: "XYZ123", // ❌ FL로 시작해야 "airline.id": -410 // ❌ 양수만 허용 }) // 결과: "Document failed validation" |
🔹 우회: bypassDocumentValidation
|
1 2 |
db.routes.insertOne({...}, { bypassDocumentValidation: true }) |
💡 5.5 반드시 피해야 할 Anti-Patterns
| Anti-Pattern | 문제 | 해결책 |
|---|---|---|
| 거대 배열 | 조회 느림 | 별도 컬렉션 분리 |
| 뚱뚱한 문서 | 16MB 초과 | Subset 패턴 |
| 컬렉션 과다 | 메모리 낭비 | 통합 |
| 불필요 인덱스 | 쓰기 느림 | Performance Advisor |
📌 저스틴의 5장 정리
첫째, 저자분의 4단계(워크로드→관계→패턴→인덱스)로 읽기 최적화 스키마 설계!
둘째, 13가지 패턴 중 Subset/Computed/Bucket/Attribute/Extended Reference가 필수!
셋째, JSON Schema 검증으로 데이터 품질 보장 + bypassDocumentValidation으로 유연성 확보!
💪 오늘의 실천 과제
routes 컬렉션에 스키마 검증 적용 → 잘못된 데이터 삽입 테스트 → 에러 확인!
|
1 2 3 4 |
// 1. Listing 5.1 validator 실행 // 2. 잘못된 flight_id로 insertOne 시도 // 3. 에러 메시지 스크린샷 |
📖 MongoDB in Action 6강: 집계 파이프라인 완전 마스터! $lookup + $unwind 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 6장 “Building aggregation pipelines”를 함께 공부하는 6강입니다. 저자분께서 MongoDB의 공장 생산라인 같은 집계 파이프라인을 완벽히 설명해 주셨어요! find()의 100배 강력한 데이터 변환/분석 도구를 sample_analytics에서 실습하며 익히세요. 책 펼치고 mongosh 접속하세요!
🎯 저자분의 핵심 메시지: 공장 컨베이어 벨트 같은 파이프라인
“In a factory, each station performs a specific task… Similarly, in the aggregation pipeline, each stage performs a specific operation.”
저자분께서 말씀하시는 핵심은 집계 파이프라인 = 데이터 공장이라는 거예요! 각 스테이지($match→$group→$sort)가 순서대로 데이터를 가공하며, 최종 결과물을 생산하죠. 제가 쉽게 풀어보면, 마치 철판→절단→용접→도장→완제품처럼 데이터도 단계별 변환입니다!
💡 6.1 집계 파이프라인 기본 + SQL 비교표
실행 방법:
|
1 2 3 |
use sample_training db.routes.aggregate([...]) // 파이프라인 배열 전달 |
| SQL | MongoDB |
|---|---|
WHERE |
$match |
GROUP BY |
$group |
JOIN |
$lookup |
SUM() |
$sum |
🔹 Listing 6.1 실습: CR2 비행기 출발지 TOP5
|
1 2 3 4 5 6 7 8 |
db.routes.aggregate([ { $match: { airplane: "CR2" } }, // 1. 필터링 { $group: { _id: "$src_airport", totalRoutes: { $sum: 1 } } }, // 2. 그룹화+집계 { $sort: { totalRoutes: -1 } }, // 3. 내림차순 정렬 { $limit: 5 } // 4. 상위 5개 ]) // 결과: DME(19), SVX(17), OVB(12)... |
💡 6.1.2 TOP 7 스테이지 + 최적화 팁
| 스테이지 | 용도 |
|---|---|
$match |
필터링 (맨 앞에!) |
$group |
그룹화+합계/평균 |
$set/$unset |
필드 추가/제거 |
$sort |
정렬 (인덱스 필수) |
$lookup |
조인 |
$unwind |
배열 펼치기 |
$limit/$skip |
페이징 |
저자분 최적화 팁:
$match은 맨 앞 → 불필요 데이터 조기 제거$set/$unset>$project→ 직관적+간결$sort필드 인덱싱 → 성능 10배
💡 6.2 $lookup: 컬렉션 조인 실습
🔹 뷰 생성 (Listing 6.6)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
use sample_analytics db.createView("enriched_transactions", "transactions", [ { $lookup: { from: "customers", localField: "account_id", foreignField: "accounts", as: "customer_details" } }, { $set: { "Customer Name": { $arrayElemAt: ["$customer_details.name", 0] }, "Customer Email": { $arrayElemAt: ["$customer_details.email", 0] } } }, { $unset: "customer_details" } ]) |
사용:
|
1 2 |
db.enriched_transactions.find().limit(3) |
🔹 $lookup + $mergeObjects: 플랫 문서화
|
1 2 3 4 5 6 7 |
db.transactions.aggregate([ { $lookup: { from: "accounts", localField: "account_id", foreignField: "account_id", as: "account_info" } }, { $unwind: "$account_info" }, { $replaceRoot: { newRoot: { $mergeObjects: ["$account_info", "$ROOT"] } } }, { $unset: "account_info" } ]) |
💡 6.3 $unwind: 배열 펼치기 실습
🔹 Listing 6.7: accounts 배열 분해
|
1 2 3 4 5 6 7 8 |
use sample_analytics db.customers.aggregate([ { $match: { _id: ObjectId("5ca4bbcea2dd94ee58162a76") } }, { $unwind: "$accounts" }, { $project: { _id: 0, username: 1, accounts: 1 } } ]) // 결과: 6개 문서 (각 계좌별 1개) |
🔹 Listing 6.8: 계좌별 중복 개수 집계
|
1 2 3 4 5 6 |
db.customers.aggregate([ { $unwind: "$accounts" }, { $group: { _id: "$accounts", count: { $sum: 1 } } }, { $sort: { count: -1 } } ]) |
💡 6.4 누산기(Accumulator): $sum, $avg, $max 실습
🔹 Listing 6.9: 사용자별 최대 계좌번호
|
1 2 3 4 5 6 7 8 9 |
db.customers.aggregate([ { $group: { _id: "$username", maxAccountNumber: { $max: "$accounts" } } } ]) |
🔹 평균 계좌 수 계산
|
1 2 3 4 5 6 7 8 9 |
db.customers.aggregate([ { $group: { _id: null, averageAccounts: { $avg: { $size: "$accounts" } } } } ]) |
💡 6.1.4 결과 저장: $out vs $merge
|
1 2 3 4 5 6 7 8 9 10 11 12 |
// $out: 새 컬렉션 완전 교체 (마지막 스테이지) { $out: { db: "output_db", coll: "results" } } // $merge: 기존 컬렉션 병합 (마지막 스테이지) { $merge: { into: "routes", on: "_id", whenMatched: "merge", whenNotMatched: "insert" } } |
📌 저스틴의 6장 정리
첫째, 저자분의 파이프라인 = 공장 컨베이어 비유로 $match→$group→$sort→$limit 기본 구조 완벽 이해!
둘째, $lookup+$unwind+$mergeObjects</strong>로 조인+배열+플랫화 마스터! <strong>셋째</strong>, <strong>$set/$unset>$project</strong> + 누산기($sum/$avg/$max)로 효율적 데이터 변환!
💪 오늘의 실천 과제
아래 3개 파이프라인 순서대로 실행 → 결과 스크린샷:
- CR2 출발지 TOP5 (Listing 6.1 전체 복사)
- 계좌 중복 개수 (Listing 6.8)
- 뷰 생성 후 조회 (Listing 6.6 +
db.enriched_transactions.findOne())
📖 MongoDB in Action 7강: 인덱싱 완전 가이드! ESR 규칙 + explain() 실습 🔥
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 7장 "Indexing for query performance"를 함께 공부하는 7강입니다. 저자분께서 쿼리 속도를 100배 빠르게 만드는 인덱스 최적화 비법을 공개해 주셨어요! Query Planner, ESR 규칙, $indexStats까지 실습하며 COLLSCAN → IXSCAN 마법을 경험하세요. sample_mflix.movies에서 바로 실행!
🎯 저자분의 핵심 메시지: 인덱스 = B-트리 데이터 구조
"Indexes are special data structures that store a small portion of the collection's data in an easily traversable B-tree form."
저자분께서 말씀하시는 핵심은 인덱스 = B-트리라는 거예요! 전체 컬렉션 스캔(COLLSCAN) 대신 인덱스 스캔(IXSCAN)으로 문서 1/100만 읽기! 제가 쉽게 풀어보면, 마치 책 색인으로 전체 책 훑지 않고 바로 페이지 찾기죠. 쓰기 느려지는 단점도 있지만, 읽기 99% 애플리케이션에선 필수!
💡 7.1 Query Planner + explain() 실행 계획 분석
Query Planner 동작:
- 모든 인덱스 후보 평가
- Trial Phase로 실제 실행 테스트
- 최고 성능 플랜 캐시 저장
🔹 explain() 3단계 (Listing 7.1)
|
1 2 3 4 5 6 7 8 9 10 11 |
use sample_mflix // 1. queryPlanner (기본) db.movies.find({ runtime: 100 }).explain() // 2. executionStats (실행 통계) db.movies.find({ runtime: 100 }).explain("executionStats") // 3. allPlansExecution (모든 후보 플랜) db.movies.find({ runtime: 100 }).explain("allPlansExecution") |
Listing 7.2 핵심 결과:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
winningPlan: { stage: "FETCH", // 문서 가져오기 inputStage: { stage: "IXSCAN", // ✅ 인덱스 스캔! indexName: "runtime_1" } } executionStats: { totalKeysExamined: 1, // 인덱스 키 1개 totalDocsExamined: 1, // 문서 1개 executionTimeMillis: 3 } |
❌ COLLSCAN (최악):
|
1 2 3 |
winningPlan: { stage: "COLLSCAN" } // 전체 컬렉션 스캔! totalDocsExamined: 21349 // 2만개 문서 스캔! |
💡 7.2 인덱스 생성/확인 실습
🔹 단일 필드 인덱스 (Listing 7.3)
|
1 2 3 4 5 6 7 |
db.movies.createIndex({ runtime: 1 }) // 오름차순 db.movies.getIndexes() // 인덱스 목록 // 결과: _id_ + runtime_1 db.movies.find({ runtime: { $lt: 40 } }).explain("executionStats") |
🔹 복합 인덱스 (Listing 7.6) + ESR 규칙
|
1 2 3 4 5 |
ESR (Equality → Sort → Range) 규칙: 1. E: year: 1914 (== 정확 일치) 2. S: title: 1 (정렬) 3. R: imdb.rating: { $gte: 7 } (범위) |
|
1 2 3 4 5 6 7 8 |
db.movies.createIndex({ year: 1, title: 1, "imdb.rating": 1 }) db.movies.find({ year: 1914, "imdb.rating": { $gte: 7 } }).sort({ title: 1 }).explain("executionStats") |
지원 쿼리 (프리픽스):
|
1 2 3 4 5 |
{ year: 1914 } ✅ { year: 1914, type: "movie" } ✅ { year: 1914, "imdb.rating": { $gte: 7 } } ✅ { type: "movie" } ❌ (year 없음) |
💡 7.2.3 멀티키 인덱스 (배열 인덱싱)
|
1 2 3 4 5 |
use sample_analytics db.customers.createIndex({ accounts: 1 }) // 배열 인덱스 db.customers.find({ accounts: 371138 }) // 배열 내 값 검색 |
복합 멀티키:
|
1 2 3 |
db.customers.createIndex({ username: 1, accounts: 1 }) db.customers.find({ username: "fmiller", accounts: 371138 }) |
💡 7.4 인덱스 속성 실습
🔹 Partial Index (부분 인덱스)
|
1 2 3 4 5 |
db.movies.createIndex( { year: 1, type: 1, "imdb.rating": 1 }, { partialFilterExpression: { type: { $eq: "movie" } } } ) |
🔹 Sparse Index (null 무시)
|
1 2 |
db.movies.createIndex({ runtime: 1 }, { sparse: true }) |
🔹 TTL Index (자동 삭제, 1년)
|
1 2 3 4 5 6 |
use sample_analytics db.transactions.createIndex( { date: 1 }, { expireAfterSeconds: 31536000 } // 1년 후 삭제 ) |
💡 7.6 인덱스 관리 실습
🔹 $indexStats: 사용량 확인 (Listing 7.12)
|
1 2 3 |
db.movies.aggregate([{ $indexStats: {} }]) // 결과: ops: 11 (11회 사용) |
전체 DB 스캔:
|
1 2 3 4 5 6 7 8 9 10 |
db.getMongo().getDBNames().forEach(function(dbname) { if (dbname !== "admin" && dbname !== "config" && dbname !== "local") { db.getSiblingDB(dbname).getCollectionNames().forEach(function(cname) { print("=== " + dbname + "." + cname + " ==="); db.getSiblingDB(dbname)[cname].aggregate([{ $indexStats: {} }]) .forEach(printjson); }); } }); |
🔹 hint(): 강제 인덱스 사용
|
1 2 3 4 |
db.movies.find({ year: 1914 }) .sort({ title: 1 }) .hint({ year: 1, title: 1, "imdb.rating": 1 }) |
📌 저스틴의 7장 정리
첫째, 저자분의 Query Planner + explain("executionStats")로 IXSCAN vs COLLSCAN 구분!
둘째, ESR 규칙으로 복합 인덱스 설계: Equality→Sort→Range 순서!
셋째, $indexStats + Partial/Sparse/TTL로 인덱스 최적화+자동 삭제!
💪 오늘의 실습 과제
아래 4단계 순서대로 실행 → 스크린샷:
db.movies.createIndex({ year: 1, title: 1, "imdb.rating": 1 })db.movies.find({ year: 1914, "imdb.rating": { $gte: 7 } }).sort({ title: 1 }).explain("executionStats")db.movies.aggregate([{ $indexStats: {} }])db.movies.createIndex({ runtime: 1 }, { expireAfterSeconds: 3600 })(1시간 TTL)
📖 MongoDB in Action 8강: ACID 트랜잭션 완전 마스터! WiredTiger 실습 🔄
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 8장 "Executing multi-document ACID transactions"를 함께 공부하는 8강입니다. 저자분께서 단일 문서 원자성 → 멀티 문서 ACID 진화를 설명해 주셨어요! WiredTiger MVCC + Node/Python/Ruby 실습으로 항공권+호텔 동시 예약 같은 복잡 트랜잭션 구현하세요!
🎯 저자분의 핵심 메시지: 단일→멀티 문서 ACID
"MongoDB supports multi-document ACID transactions across multiple documents, collections, databases, and shards."
저자분께서 말씀하시는 핵심은 단일 문서=자동 ACID → 멀티 문서=명시적 트랜잭션이라는 거예요! 제가 쉽게 풀어보면, 마치 하나의 은행 송금=자동, 여러 계좌 이동=수동 승인처럼 복잡 거래는 트랜잭션 필요합니다!
💡 8.1 WiredTiger: MongoDB 기본 스토리지 엔진
주요 특징:
|
1 2 3 4 5 |
✅ MVCC (Multi-Version Concurrency Control) ✅ 압축 (Snappy/zlib/zstd) ✅ 체크포인트 (60초마다) ✅ 저널링 (Write-Ahead Logging) |
💡 8.4 Callback API vs Core API (Table 8.1)
| API | 특징 | 추천 |
|---|---|---|
| Callback | 자동 재시도/에러 처리 | ✅ 생산 권장 |
| Core | 수동 commit/abort | ❌ 피함 |
💡 8.4.2 mongosh 트랜잭션 실습 (Listing 8.1)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function executeTransaction(session) { const db = session.getDatabase('sample_analytics'); session.startTransaction({ readConcern: { level: 'snapshot' }, writeConcern: { w: 'majority' }, readPreference: 'primary' }); try { const account = db.accounts.findOne({ account_id: 371138 }); db.accounts.updateOne({ account_id: 371138 }, { $inc: { transaction_count: 1 } }); db.customers.updateMany({ accounts: 371138 }, { $inc: { transaction_count: 1 } }); db.transactions.insertOne({ account_id: 371138, amount: 1500 }); session.commitTransaction(); } catch (error) { session.abortTransaction(); throw error; } } |
재시도 래퍼:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function runWithRetry() { for (let i = 0; i < 5; i++) { const session = db.getMongo().startSession(); try { executeTransaction(session); return; } catch (error) { if (error.hasErrorLabel('TransientTransactionError')) continue; throw error; } finally { session.endSession(); } } } |
💡 8.4.3 Node.js Callback API (Listing 8.2)
|
1 2 3 4 5 6 7 8 |
const session = client.startSession(); session.withTransaction(async () => { const account = await accounts.findOne({ account_id: 371138 }, { session }); await accounts.updateOne({ account_id: 371138 }, { $inc: { transaction_count: 1 } }, { session }); await customers.updateMany({ accounts: 371138 }, { $inc: { transaction_count: 1 } }, { session }); await transactions.insertOne({ account_id: 371138, amount: 1500 }, { session }); }); |
📌 저스틴의 8장 정리
첫째, 저자분의 WiredTiger MVCC로 동시성+원자성 보장 이해!
둘째, Callback API 자동 재시도로 안전 트랜잭션 구현!
셋째, Node/Python/Ruby 3언어 실습으로 멀티 컬렉션 ACID 완성!
💪 오늘의 실습 과제
sample_analytics에서 다음 트랜잭션 → Node.js 코드 작성+실행:
|
1 2 3 4 |
1. accounts.transaction_count +1 2. customers.accounts 배열 있는 모든 문서 transaction_count +1 3. transactions에 새 레코드 insert |
📖 MongoDB in Action 9강: 복제+샤딩 완전 이해! Atlas 샤드 클러스터 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 9장 "Using replication and sharding"를 함께 공부하는 9강입니다. 저자분께서 **복제(고가용성) ≠ 샤딩(수평확장)**을 명확히 구분하고, Atlas에서 실제 샤드 클러스터 만드는 방법을 알려주셨어요! M30 유료 클러스터 생성부터 샤드키 분석까지 실습하며 TB급 데이터베이스 아키텍처를 마스터하세요!
🎯 저자분의 핵심 메시지: 복제 vs 샤딩 완전 구분
"Replication enhances data availability... Sharding partitions large database into smaller segments."
저자분께서 말씀하시는 핵심은 복제=가용성, 샤딩=확장성이라는 거예요! 복제는 Primary→Secondary 데이터 동기화(읽기 분산), 샤딩은 데이터 분할(쓰기 분산)입니다. 제가 쉽게 풀어보면, 복제는 '같은 책 여러 부', 샤딩은 '책을 챕터별로 나눠서' 저장하는 거죠!
💡 9.1 복제(Replication): 고가용성 보장
🔹 Replica Set 멤버 상태 (Table 9.1, Listing 9.1)
|
1 2 3 |
// 2장 클러스터에서 확인 rs.status() // 또는 db.adminCommand("replSetGetStatus") |
|
1 2 3 4 |
_id: 0, name: "...-00", state: 2 → SECONDARY _id: 1, name: "...-01", state: 1 → PRIMARY _id: 2, name: "...-02", state: 2 → SECONDARY |
| 상태 | 숫자 | 역할 |
|---|---|---|
| PRIMARY | 1 | 쓰기 담당 |
| SECONDARY | 2 | 읽기+복제 |
| ARBITER | 6 | 투표만 |
| ROLLBACK | 8 | 되돌리기 중 |
🔹 Oplog: 변경 이력 로그 (Listing 9.3)
|
1 2 3 |
use local db.oplog.rs.find().limit(3).pretty() |
|
1 2 3 |
{ op: 'i', ns: 'sample_mflix.sessions', o: { _id: ..., user_id: "12345" } } { op: 'd', ns: 'sample_mflix.sessions', o: { _id: ... } } |
oplog 크기 확인 (Listing 9.5):
|
1 2 3 |
db.getReplicationInfo() rs.printReplicationInfo() // Secondary 지연시간 |
💡 9.2 Change Streams: 실시간 변경 감지
🔹 mongosh 실시간 모니터링 (Listing 9.7)
|
1 2 3 4 5 6 7 8 9 10 |
const watchCursor = db.getSiblingDB("sample_mflix").watch() while (!watchCursor.isClosed()) { const next = watchCursor.tryNext() while (next !== null) { printjson(next) next = watchCursor.tryNext() } } |
새 세션 삽입 후 결과 (Listing 9.8):
|
1 2 3 4 |
db.getSiblingDB("sample_mflix").sessions.insertOne({ user_id: "12345", jwt: "token123456" }) |
|
1 2 3 |
operationType: 'insert', fullDocument: { _id: ..., user_id: '12345', jwt: 'token123456' } |
🔹 Node.js Change Stream (Listing 9.9)
|
1 2 3 4 5 |
const changeStream = sessionsCollection.watch([ { $match: { 'fullDocument.user_id': '12345' } }, { $addFields: { alert: 'VIP user changed!' } } ]) |
💡 9.3 샤딩(Sharding): 수평 확장 실습
🔹 Atlas 샤드 클러스터 생성 (M30+ 유료)
|
1 2 3 4 5 6 |
atlas clusters create "MongoDB-Sharded" \ --provider GCP --region CENTRAL_US \ --tier M30 --type SHARDED --shards 2 --mdbVersion 8.0 atlas clusters sampleData load "MongoDB-Sharded" |
연결:
|
1 2 3 |
mongosh "mongodb+srv://mongodb-sharded.xxx.mongodb.net" \ --apiVersion 1 --username manning |
🔹 샤드 클러스터 아키텍처 (Figure 9.2)
|
1 2 3 4 |
App → mongos (쿼리 라우터) ↓ Shard0 (Replica Set) + Shard1 + Config Shard (MongoDB 8.0+) |
🔹 샤드키 선택: analyzeShardKey (MongoDB 7.0+)
|
1 2 3 4 5 6 7 8 9 |
// 1. 쿼리 샘플링 활성화 db.routes.configureQueryAnalyzer({ mode: "full", samplesPerSecond: 1 }) // 2. 테스트 쿼리 실행 db.routes.find({"src_airport": "JFK", "dst_airport": "LAX", "airline.name": "Delta"}) // 3. 샤드키 분석 (Listing 9.13) db.routes.analyzeShardKey({ src_airport: 1, dst_airport: 1, "airline.name": 1 }) |
결과 핵심:
|
1 2 3 |
numDistinctValues: 66984 (✅ 고유성 좋음) singleShardReads: 84% (✅ 단일 샤드 읽기 많음) |
🔹 샤딩 활성화
|
1 2 3 4 |
sh.shardCollection("sample_training.routes", { src_airport: 1, dst_airport: 1, "airline.name": 1 }) sh.status() // 샤드 상태 확인 |
💡 9.5 읽기/쓰기 일관성 제어
🔹 Write Concern (기본: majority)
|
1 2 3 4 |
db.routes.insertOne({ src_airport: 'MUC' }, { writeConcern: { w: "majority", j: true, wtimeout: 5000 } }) |
🔹 Read Concern (기본: local)
|
1 2 |
db.routes.find({ src_airport: 'MUC' }).readConcern('majority') |
🔹 Read Preference (기본: primary)
|
1 2 |
db.routes.find({ src_airport: 'MUC' }).readPref('secondaryPreferred') |
📌 저스틴의 9장 정리
첫째, 저자분의 복제=PRIMARY(쓰기)+SECONDARY(읽기), 샤딩=데이터 분할 구분!
둘째, Change Streams로 실시간 변경 감지 + analyzeShardKey로 최적 샤드키 선택!
셋째, Atlas M30 샤드 클러스터 생성 + sh.shardCollection()으로 실제 샤딩 경험!
💪 오늘의 실천 과제
Atlas M30+에서 다음 3개 실행 → 스크린샷:
db.adminCommand("replSetGetStatus")→ Replica 상태db.getSiblingDB("sample_mflix").watch()→ Change Streamdb.routes.analyzeShardKey({ src_airport: 1, dst_airport: 1, "airline.name": 1 })→ 샤드키 분석
📖 MongoDB in Action 10강: Atlas DBaaS 완전 가이드! M0→M30→Global 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 10장 "Delving into database as a service"를 함께 공부하는 10강입니다. 저자분께서 Atlas의 M0 무료→Flex→M10 개발→M30 프로덕션→Global 완전 로드맵을 제시해 주셨어요! Auto Scaling, Multi-Cloud, Custom Write Concern까지 실습하며 운영 걱정 없는 클라우드 DB를 마스터하세요!
🎯 저자분의 핵심 메시지: Atlas = 관리 부담 제로
"Atlas takes care of most MongoDB administrative tasks... allowing developers to concentrate on application development."
저자분께서 말씀하시는 핵심은 Atlas = 서버 관리 0이라는 거예요! 배포/스케일링/백업/업그레이드 자동화 + Atlas Search/Vector/Stream/SQL 추가 기능까지! 제가 쉽게 풀어보면, 마치 호텔 체크인 = 짐 풀고 바로 사용처럼 DB도 설정 없이 바로 쓰는 거죠!
💡 10.1 공유 클러스터: M0 무료 + Flex
| 제한 | M0 | Flex |
|---|---|---|
| 스토리지 | 512MB | 5GB |
| 연산 | 100 ops/s | 500 ops/s |
| 샤딩 | ❌ | ❌ |
| 백업 | ❌ | 일일 스냅샷 |
| 연결 | 500 | 500 |
업그레이드:
|
1 2 3 |
Atlas UI → Edit Configuration → Cluster Tier → M10 선택 // CLI: atlas cluster update <클러스터명> --tier M10 |
💡 10.2 전용 클러스터: M10+ 프로덕션
| 기능 | M0 | Flex | M10+ |
|---|---|---|---|
| 스토리지 | 0.5GB | 5GB | 10GB-4TB |
| 샤딩 | ❌ | ❌ | M30+ ✅ |
| 백업 | ❌ | 제한 | 풀 백업 |
| VPC Peering | ❌ | ❌ | ✅ |
| Performance Advisor | ❌ | ❌ | ✅ |
클러스터 클래스 (M40+):
- Low CPU: 메모리 위주 (비용 절감)
- General: 균형 (권장)
- Local NVMe: 초고속 I/O
💡 10.2.3 Auto Scaling: 자동 크기 조정
🔹 클러스터 Auto Scaling
|
1 2 3 |
Atlas UI → Auto-Scale → Cluster Tier Scaling ON Min: M30 → Max: M50 (CPU/메모리 90% 초과시 자동 업그레이드) |
🔹 스토리지 Auto Scaling (기본 ON)
|
1 2 3 |
노드 90% → 자동 증가 (AWS/GCP: 70% 목표, Azure: 2배) 하향 스케일링은 수동! |
💡 10.3 Global Clusters: 전 세계 데이터 분산
| 존 타입 | 역할 |
|---|---|
| Highest Priority | Primary 배치 |
| Electable | Secondary (Primary 후보) |
| Read-only | 읽기 전용 |
| Analytics | BI/분석 분리 |
Multi-Cloud 예시:
|
1 2 3 4 |
GCP US-East1 (Highest Priority, 3노드) AWS Ireland (Electable, 2노드) Azure Frankfurt (Electable, 2노드) |
💡 10.5 Replica Set Tags: 쿼리 라우팅
| 태그 | 예시 |
|---|---|
nodeType: ANALYTICS |
분석 노드 |
region: US_EAST_2 |
지역 |
provider: GCP |
클라우드 |
연결문자열 옵션:
|
1 2 3 4 5 6 7 8 9 10 |
// 분석 노드만 ?readPreference=secondary&readPreferenceTags=nodeType:ANALYTICS // 운영 노드만 ?readPreference=secondary&readPreferenceTags=workloadType:OPERATIONAL // GCP 우선 → Fallback ?readPreference=nearest&readPreferenceTags=provider:GCP,region:us-east1& readPreferenceTags=&readConcernLevel=local |
💡 10.6 Custom Write Concern: 멀티 리전
| Write Concern | 의미 |
|---|---|
w: "twoRegions" |
2개 리전 인정 |
w: "threeRegions" |
3개 리전 인정 |
w: "twoProviders" |
2개 클라우드 인정 |
|
1 2 |
db.routes.insertOne({...}, { writeConcern: { w: "threeRegions" } }) |
📌 저스틴의 10장 정리
첫째, 저자분의 M0(무료)→Flex→M10(개발)→M30+(프로덕션) Atlas 계층 완벽 이해!
둘째, Auto Scaling + Global Clusters로 운영 자동화 + 전세계 저지연!
셋째, Replica Tags + Custom WC로 쿼리/쓰기 정밀 제어!
💪 오늘의 실천 과제
Atlas UI에서 다음 확인 → 스크린샷:
- 클러스터 → Edit Configuration → Auto-Scale 설정 확인
- Replica Set Tags 목록 (
rs.conf().members[0].tags) - 연결문자열에
readPreferenceTags=nodeType:ANALYTICS추가 테스트
📖 MongoDB in Action 11강: Atlas Search 완전 마스터! Lucene + $search 실습 🔥
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 11장 "Carrying out full-text search using Atlas Search"를 함께 공부하는 11강입니다. 저자분께서 Elasticsearch 동기화 복잡함 → Atlas Search 1개 API 혁신을 소개해 주셨어요! Lucene Inverted Index부터 $search 연산자, M0 클러스터에서 바로 실습하며 구글 검색 같은 풀텍스트 검색을 구현하세요!
🎯 저자분의 핵심 메시지: 별도 검색엔진 필요 제로
"Atlas Search eliminates the need to run a separate search system alongside your MongoDB database."
저자분께서 말씀하시는 핵심은 Atlas Search = DB+검색 통합이라는 거예요! Monstache 같은 동기화 없이 Change Streams로 자동 동기화 + 단일 API! 제가 쉽게 풀어보면, 마치 스마트폰에 카메라/전화/메시지 통합처럼 DB+검색이 하나로 해결되는 거죠!
💡 11.2 Apache Lucene: 뒤집힌 인덱스(Inverted Index)
Table 11.1 예시:
|
1 2 3 4 5 6 7 8 |
Token | Doc1 | Doc2 ----------------|------|------ LISANDRO CABRERA| ✓ | AZMY KIROLES | | ✓ BRONX | ✓ | JERSEY CITY | | ✓ NO VIOLATION | ✓ | ✓ |
검색 "No Violation BRONX" → Doc1만 반환 (AND 연산)
💡 11.4 Atlas Search 인덱스 생성 실습 (M0 클러스터)
🔹 index-definition.json 작성 (Listing 11.2)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "name": "default", "mappings": { "dynamic": false, "fields": { "business_name": { "type": "string", "analyzer": "lucene.standard" }, "result": { "type": "string", "analyzer": "lucene.standard" }, "sector": { "type": "string", "analyzer": "lucene.standard" }, "address.city": { "type": "string", "analyzer": "lucene.standard" } } } } |
🔹 인덱스 생성 (Listing 11.3)
|
1 2 3 4 5 6 7 8 |
atlas clusters search indexes create \ --clusterName MongoDB-in-Action \ --file index-definition.json atlas clusters search indexes list \ --clusterName MongoDB-in-Action \ --collection inspections --db sample_training |
Atlas UI 확인: Search & Vector Search → sample_training.inspections → READY
💡 11.5 $search 연산자 실습
🔹 Text + Compound (Listing 11.4)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
use sample_training db.inspections.aggregate([ { $search: { index: "default", compound: { must: [ { text: { query: "food", path: "business_name" } }, { text: { query: "PASS", path: "result" } }, { text: { query: "127", path: "sector" } } ] } } }, { $set: { score: { $meta: "searchScore" } } } ]) // 결과: MARTES FOOD CENTER CORP (score: 2.94) |
🔹 Fuzzy 검색 (오타 허용)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
db.inspections.aggregate([ { $search: { index: "default", text: { query: "BUILNG TO SERV INC", // 오타 의도 path: "business_name", fuzzy: { maxEdits: 2, prefixLength: 1 } } } } ]) // 결과: "BUILDING TO SERVE INC." (score: 7.31) |
🔹 Phrase (근접 검색)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
db.inspections.aggregate([ { $search: { index: "default", phrase: { query: ["food", "license"], path: "business_name", slop: 3 // 3단어 이내 } } } ]) |
🔹 Wildcard (패턴 검색)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
db.inspections.aggregate([ { $search: { index: "default", wildcard: { path: "business_name", query: "*L?CE*" // L_ICE 패턴 } } } ]) |
🔹 Facet (다면 검색)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
db.inspections.aggregate([ { $search: { index: "default", text: { query: "HOT DOG", path: "business_name" } } }, { $facet: { "ResultsByStatus": [{ $group: { _id: "$result", count: { $sum: 1 } } }], "ResultsByYear": [{ $group: { _id: { $year: { $toDate: "$date" } }, count: { $sum: 1 } } }] } } ]) |
💡 11.5.2 $searchMeta: 메타데이터만
|
1 2 3 4 5 6 7 8 9 10 |
db.inspections.aggregate([ { $searchMeta: { index: "default", text: { query: "Deli", path: "business_name" } } } ]) // 결과: { count: { lowerBound: 2447 } } |
📌 저스틴의 11장 정리
첫째, 저자분의 Lucene Inverted Index로 "No Violation BRONX" → Doc1 정확 검색 이해!
둘째, **M0에서 atlas clusters search indexes create**로 5분만에 인덱스 생성!
셋째, $search 연산자 (text/compound/fuzzy/phrase/wildcard/facet)로 구글급 검색 구현!
💪 오늘의 실천 과제
M0 클러스터에서 다음 3개 순서대로 → 스크린샷:
- 인덱스 생성:
atlas clusters search indexes create --file index-definition.json - Fuzzy 검색:
"BUILNG TO SERV INC"→ "BUILDING TO SERVE INC." 결과 - Facet 분석: "HOT DOG" → 상태/연도별 통계
📖 MongoDB in Action 12강: Vector Search + RAG 완전 실습! 임베딩 생성 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 12장 "Learning semantic techniques and Atlas Vector Search"를 함께 공부하는 12강입니다. 저자분께서 텍스트→임베딩→벡터검색 RAG(검색 증강 생성) 아키텍처를 완벽히 설명해 주셨어요! OpenAI API로 임베딩 생성부터 $vectorSearch, Atlas Triggers 자동화까지 실습하며 챗GPT 같은 AI 검색 구현하세요!
🎯 저자분의 핵심 메시지: 의미 기반 검색 혁명
"Vector search identifies vectors that are near your query... 'renewable energy' → solar/wind power 반환."
저자분께서 말씀하시는 핵심은 키워드 → 의미 전환이라는 거예요! "재생에너지" 검색시 "태양광/풍력"도 반환! 제가 쉽게 풀어보면, 마치 "운동화" 검색 → 러닝/농구화 추천처럼 유사도 기반 검색입니다. RAG=검색+LLM으로 환각(Hallucination) 해결!
💡 12.1 임베딩(Embeddings): 텍스트→숫자 벡터 변환
Figure 12.1 다차원 공간:
|
1 2 3 4 5 6 |
"Renewable Energy" [0.3, 0.8, -0.2] ← 가까움 ↓ "Solar Power" [0.4, 0.7, -0.1] "Wind Energy" [0.2, 0.9, -0.3] "Coal Power" [-0.5, 0.1, 0.8] ← 멀음 |
🔹 OpenAI API 임베딩 생성 (Listing 12.1)
|
1 2 3 4 5 6 7 8 |
export OPENAI_API_KEY=sk-... curl https://api.openai.com/v1/embeddings \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "input": "MongoDB in Action 8.0", "model": "text-embedding-3-small" }' |
결과: 1536차원 벡터 (text-embedding-3-small)
💡 12.2 Atlas Vector Search: HNSW 알고리즘
sample_mflix.embedded_movies 확인:
|
1 2 3 |
use sample_mflix db.embedded_movies.findOne() |
|
1 2 |
plot_embedding: [0.0007, -0.0268, 0.0135, ...] // 1536개 숫자! |
🔹 벡터 인덱스 생성 (vector-definition.json)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "name": "vector-index", "type": "vectorSearch", "fields": [ { "type": "vector", "path": "plot_embedding", "numDimensions": 1536, "similarity": "cosine" }, { "type": "filter", "path": "genres" }, { "type": "filter", "path": "year" } ] } |
|
1 2 3 |
atlas clusters search indexes create \ --clusterName MongoDB-in-Action --file vector-definition.json |
💡 12.3 $vectorSearch 실습
기본 쿼리 (Listing 12.4):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
db.embedded_movies.aggregate([ { $vectorSearch: { index: "vector-index", path: "plot_embedding", queryVector: [-0.0016, -0.028, ...], // OpenAI 임베딩 numCandidates: 150, limit: 5 } }, { $project: { title: 1, plot: 1, score: { $meta: "vectorSearchScore" } } } ]) |
Pre-filtering (Listing 12.5):
|
1 2 3 4 5 6 7 8 9 10 11 |
{ $vectorSearch: { filter: { $or: [ { genres: "Action" }, { runtime: { $lt: 120 } } ] } } } |
💡 12.5 Atlas Triggers: 자동 임베딩 생성
Trigger 설정 (Listing 12.6):
- Atlas UI → Triggers → Create Trigger
- Event:
sample_mflix.embedded_moviesINSERT/UPDATE - Function (OpenAI API 호출):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
exports = async function(changeEvent) { const docId = changeEvent.documentKey._id; const plot = changeEvent.fullDocument.plot; const response = await context.http.post({ url: 'https://api.openai.com/v1/embeddings', headers: { 'Authorization': `Bearer ${OPENAI_KEY}` }, body: JSON.stringify({ input: plot, model: "text-embedding-3-small" }) }); const embedding = EJSON.parse(response.body.text()).data[0].embedding; await context.services.get("Cluster0") .db("sample_mflix") .collection("embedded_movies") .updateOne({ _id: docId }, { $set: { plot_embedding: embedding } }); }; |
테스트:
|
1 2 3 |
db.embedded_movies.insertOne({ plot: "새 영화 줄거리" }) // → 자동으로 plot_embedding 1536차원 생성! |
📌 저스틴의 12장 정리
첫째, 저자분의 OpenAI API→임베딩→$vectorSearch RAG 파이프라인 완벽 이해!
둘째, 1536차원 벡터 인덱스 생성 + cosine 유사도로 의미 검색!
셋째, Atlas Triggers로 INSERT시 자동 임베딩 → 운영 Zero-Touch!
💪 오늘의 실천 과제
1. OpenAI API 키 발급 → 2. 벡터 인덱스 생성 → 3. Trigger 설정 → 스크린샷 3장:
|
1 2 3 4 |
1. curl https://api.openai.com/v1/embeddings "MongoDB" 2. atlas clusters search indexes create --file vector-definition.json 3. Atlas UI Triggers → embedded_movies INSERT → OpenAI Function |
📖 MongoDB in Action 13강: 로컬 Atlas CLI 완전 가이드! Docker+Search 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 13장 "Developing AI applications locally with Atlas CLI"를 함께 공부하는 13강입니다. 저자분께서 클라우드 없이 로컬에서 Atlas Search/Vector Search 개발 환경 구축법을 공개해 주셨어요! Docker+Atlas CLI로 5분만에 완전한 Atlas 환경 구축하고, mongorestore로 샘플 데이터 로드 실습하세요!
🎯 저자분의 핵심 메시지: 클라우드 없이 로컬 Atlas
"Atlas CLI allows you to develop locally with MongoDB Atlas deployments, including Atlas Search and Vector Search."
저자분께서 말씀하시는 핵심은 로컬=클라우드 동일 기능이라는 거예요! Docker로 mongod+mongot(Lucene) 실행 → Search/Vector Search 완전 지원! 비용 걱정 없이 AI 앱 개발 가능! 제가 쉽게 풀어보면, 마치 모카 앱으로 카페 메뉴 테스트처럼 로컬에서 Atlas 풀 기능 체험하는 거죠!
💡 13.2 로컬 Atlas 클러스터 생성 (Docker 필수)
🔹 Docker 설치 확인
|
1 2 3 |
docker info # Docker 실행 확인 docker ps # 실행 컨테이너 확인 |
🔹 로컬 클러스터 생성 (Listing 13.1)
|
1 2 |
atlas deployments setup --type local |
|
1 2 3 4 |
? Deployment Name: local-test (기본값) ? MongoDB Version: 8.0 (기본값) ? Port: 27017 (기본값) |
결과:
|
1 2 |
Connection string: mongodb://localhost:27017/?directConnection=true |
mongosh 자동 연결:
|
1 2 3 |
AtlasLocalDev rs-localdev [direct: primary] test> show dbs admin config local |
💡 13.3 클러스터 관리 실습
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 목록 atlas deployments list --type LOCAL # local-test LOCAL 8.0 IDLE # 일시 정지 atlas deployments pause local-test --type LOCAL # 재시작 atlas deployments start local-test --type LOCAL # 로그 확인 atlas deployments logs local-test --type LOCAL # 삭제 atlas deployments delete local-test --type LOCAL |
💡 13.3.2 샘플 데이터 로드 (mongorestore)
|
1 2 3 4 5 6 7 8 9 10 11 |
# 1. 샘플 데이터 다운로드 (몇 분 소요) curl https://atlas-education.s3.amazonaws.com/sampledata.archive -o sampledata.archive # 2. 로컬 클러스터 연결문자열 확인 atlas deployments connect --connectWith connectionString local-test # mongodb://localhost:27107/?directConnection=true # 3. 데이터 복원 mongorestore --archive=sampledata.archive \ --uri mongodb://localhost:27107/?directConnection=true |
|
1 2 |
425367 document(s) restored successfully! |
확인:
|
1 2 3 |
show dbs // sample_airbnb, sample_mflix, sample_training... ✅ |
💡 13.4 Docker 내부 탐색
|
1 2 3 4 5 6 7 |
docker ps # CONTAINER ID: b32351f3a7c7 IMAGE: mongodb/mongodb-atlas-local:8.0 docker inspect mongodb/mongodb-atlas-local:8.0 # 이미지 정보 docker top local-test # 실행 프로세스 |
|
1 2 3 4 |
UID PID CMD 997 4426 mongod --replSet rs-localdev ... 997 4520 /opt/mongot/bin/jdk/bin/java ... # mongot (Search!) |
컨테이너 내부 진입:
|
1 2 3 4 |
docker exec -it local-test /bin/bash cd /opt/mongot/ cat README.md # mongot 설명서 |
💡 13.5 로컬 Search/Vector Search 실습
🔹 Full-Text Search 인덱스 생성
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use sample_training db.inspections.createSearchIndex("local-search", { mappings: { dynamic: true } }) db.inspections.getSearchIndexes() db.inspections.aggregate([ { $search: { index: "local-search", text: { query: "food violation", path: "business_name" } }}, { $limit: 3 } ]) |
🔹 Vector Search 인덱스 생성
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use sample_mflix db.embedded_movies.createSearchIndex("vector-local", { mappings: { fields: { plot_embedding: { type: "knnVector", dimensions: 1536, similarity: "euclidean" } } } }) |
📌 저스틴의 13장 정리
첫째, 저자분의 Docker+Atlas CLI로 5분 로컬 Atlas (mongod+mongot 완전 재현)!
둘째, mongorestore 샘플 데이터 → Search/Vector Search 즉시 사용 가능!
셋째, 클라우드 비용 0원으로 AI 앱 개발 환경 완성!
💪 오늘의 실천 과제
로컬 Atlas 4단계 → 스크린샷 4장:
atlas deployments setup --type localmongorestore --archive=sampledata.archivedb.inspections.createSearchIndex("local", {mappings:{dynamic:true}})docker top <container>(mongot 프로세스 확인!)
📖 MongoDB in Action 14강: RAG AI 챗봇 완성! LangChain + Atlas 실습 🔥
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 14장 "Building retrieval-augmented generation AI chatbots"를 함께 공부하는 14강입니다. 저자분께서 환각(Hallucination) 해결 RAG + LangChain 오케스트레이션 완전 구현법을 공개해 주셨어요! PDF→임베딩→Vector Search→GPT 응답까지 로컬에서 10분만에 AI 챗봇 완성하세요!
🎯 저자분의 핵심 메시지: RAG = 환각 제로 AI
"RAG combines generating text with real-time information retrieval to improve accuracy."
저자분께서 말씀하시는 핵심은 RAG = LLM + 검색이라는 거예요! 챗GPT 환각(허구 생성) 해결 위해 Vector Search로 문서 검색 → LLM에 컨텍스트 제공! 제가 쉽게 풀어보면, 마치 **학생=지식(검색)+답변생성(LLM)**처럼 검색 증강 생성입니다!
💡 14.1 RAG 파이프라인 8단계 (Figure 14.1)
|
1 2 3 4 5 6 7 8 |
1. PDF 문서 → 2. 청크 분할 ↓ 3. OpenAI 임베딩 → 4. Atlas Vector Search 저장 ↓ (사용자 질문) 5. 질문 임베딩 → 6. Vector Search (Top-K) ↓ 7. 문서 컨텍스트 → 8. GPT 응답 생성 |
💡 14.4 LangChain RAG 챗봇 구축 실습
🔹 1단계: LangChain 프로젝트 생성
|
1 2 3 4 |
pip3 install -U langchain-cli langchain_openai langchain app new mongodb-rag --package rag-mongo cd mongodb-rag |
🔹 2단계: 환경변수 설정
|
1 2 3 |
export OPENAI_API_KEY=sk-... export MONGO_URI="mongodb://localhost:27017/?directConnection=true" # 로컬 Atlas |
🔹 3단계: PDF 임베딩 생성 (ingest.py 수정)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# packages/rag-mongo/ingest.py DB_NAME = "langchain" COLLECTION_NAME = "mongodb" ATLAS_VECTOR_SEARCH_INDEX_NAME = "default" loader = PyPDFLoader("https://images.g2crowd.com/uploads/attachment/file/83340/atlas-best-practices.pdf") data = loader.load() docs = RecursiveCharacterTextSplitter(chunk_size=500).split_documents(data) MongoDBAtlasVectorSearch.from_documents( docs, OpenAIEmbeddings(), collection=MONGODB_COLLECTION, index_name="default" ) |
|
1 2 |
python3 packages/rag-mongo/ingest.py |
🔹 4단계: Vector Search 인덱스 생성
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# vector-search.json { "name": "default", "type": "vectorSearch", "fields": [{ "type": "vector", "path": "embedding", "numDimensions": 1536, "similarity": "cosine" }] } |
|
1 2 |
atlas deployments search indexes create --file vector-search.json --type LOCAL |
🔹 5단계: 서버 실행 + Playground 테스트
|
1 2 |
langchain serve |
브라우저: http://127.0.0.1:8000/rag-mongo/playground/
질문 테스트:
|
1 2 3 |
Q: "MongoDB가 지원하는 인덱스 종류는?" A: "compound, geospatial, text search, unique, array, TTL, sparse, partial..." |
🔹 6단계: curl API 테스트
|
1 2 3 4 |
curl -X POST "http://127.0.0.1:8000/rag-mongo/invoke" \ -H "Content-Type: application/json" \ -d '{"input": "Atlas 암호화 방법은?"}' |
📌 저스틴의 14장 정리
첫째, 저자분의 RAG 8단계 (PDF→청크→임베딩→Vector Search→GPT) 완벽 파악!
둘째, langchain app new rag-mongo → 10줄 코드로 챗봇 완성!
셋째, LangServe Playground + curl API로 즉시 테스트 가능!
💪 오늘의 실천 과제
로컬 Atlas에서 RAG 챗봇 5단계 → 스크린샷:
langchain app new mongodb-rag --package rag-mongopython3 packages/rag-mongo/ingest.py(PDF 임베딩)- Vector 인덱스 생성 +
langchain serve http://localhost:8000/rag-mongo/playground/→ "인덱스 종류?" 질문curlAPI 응답 확인
📖 MongoDB in Action 15강: Atlas Stream Processing 완전 마스터! 실시간 스트림 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 "MongoDB in Action, Third Edition"의 15장 "Building event-driven applications"를 함께 공부하는 15강입니다. 저자분께서 Kafka/Elasticsearch 복잡함 → Atlas Stream Processing 1개 파이프라인 혁신을 소개해 주셨어요! $source→$validate→$tumblingWindow→$merge로 실시간 이벤트 처리 실습하며 이벤트 기반 아키텍처 완성하세요!
🎯 저자분의 핵심 메시지: 스트림 처리 = Aggregation Pipeline
"Atlas Stream Processing is essentially a MongoDB aggregation pipeline that continuously processes incoming data streams."
저자분께서 말씀하시는 핵심은 Stream Processing = 무한 Aggregation이라는 거예요! $source(Kafka/Change Stream)→실시간 변환→$merge(DB 저장)! 별도 Kafka Streams/Flink 필요 없음! 제가 쉽게 풀어보면, 마치 호스 물줄기=끊임없는 파이프라인처럼 데이터 흐름 실시간 가공입니다!
💡 15.4 Atlas Stream Processing 구성요소
|
1 2 3 4 5 6 7 8 |
Connection Registry (연결 저장소) ↓ Stream Processing Instance (SPI) ↓ (최대 4개) Stream Processor (파이프라인) ↓ Worker (자동 스케일링) |
💡 15.5 스트림 파이프라인 구조
필수 순서:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
$source (Kafka/Change Stream) ↓ (선택) $validate (스키마 검증) ↓ (무상태) $match/$project/$set ↓ (1개만, 선택) $tumblingWindow or $hoppingWindow ↓ (상태) $group/$count ↓ (1개 필수) $emit (Kafka) or $merge (DB) |
🔹 $source: 데이터 소스 (Listing 15.2)
|
1 2 3 4 5 6 7 |
let source = { $source: { connectionName: "kafka-connection", topic: "sales-topic" } } |
🔹 $validate: 실시간 검증
|
1 2 3 4 5 6 7 8 9 10 11 12 |
let validate = { $validate: { validator: { $and: [ { quantity: { $gte: 1 } }, { price: { $type: "double", $gt: 0 } } ] }, validationAction: "dlq" // Dead Letter Queue } } |
🔹 $tumblingWindow: 10초 고정 윈도우
|
1 2 3 4 5 6 7 |
let window = { $tumblingWindow: { interval: { size: 10, unit: "second" }, pipeline: [{ $group: { _id: "$product", total: { $sum: "$quantity" } } }] } } |
💡 15.6 Stream Processor 생성 실습
🔹 1단계: SPI 생성 (AWS Frankfurt)
|
1 2 3 |
atlas streams instances create "My-SPI" \ --provider AWS --region FRANKFURT_DEU |
🔹 2단계: 연결 (mongosh)
|
1 2 3 4 |
mongosh "mongodb://atlas-stream-xxx.frankfurt-deu.a.query.mongodb.net/" \ --username manning sp.listConnections() |
🔹 3단계: 간단한 Processor (Listing 15.2)
|
1 2 3 4 |
let source = { $source: { connectionName: "sample_stream_solar" } } let processor = [source] sp.process(processor) // 실시간 출력! |
|
1 2 3 |
{ device_id: 'device_1', obs: { watts: 114, temp: 11 } } { device_id: 'device_4', obs: { watts: 129, temp: 20 } } |
🔹 4단계: 완전한 Processor (센서 데이터 처리)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
let source = { $source: { connectionName: "sample_stream_solar" } } let window = { $tumblingWindow: { interval: { size: 10, unit: "second" }, pipeline: [{ $group: { _id: "$group_id", avg_temp: { $avg: "$obs.temp" }, avg_watts: { $avg: "$obs.watts" } } }] } } let merge = { $merge: { into: { connectionName: "mongodb-connection", db: "stream_db", coll: "solar_stats" } } } let processor = [source, window, merge] sp.createStreamProcessor("solar-processor", processor) sp.solar-processor.start() |
💡 15.7 Dead Letter Queue (DLQ): 오류 처리
|
1 2 3 |
올바른 데이터 → $merge (DB 저장) 오류 데이터 → DLQ (분석용 컬렉션) |
|
1 2 3 4 5 6 7 8 |
{ $validate: { validator: { price: { $gt: 0 } }, validationAction: "dlq", // mongodb-connection → error_coll dlq: { db: "errors", coll: "failed_orders" } } } |
📌 저스틴의 15장 정리
첫째, 저자분의 $source→validate→window→merge 실시간 스트림 파이프라인 완벽 이해!
둘째, SPI 생성 → sp.process() 즉시 테스트 → sp.createStreamProcessor() 영구 실행!
셋째, DLQ+Checkpoint로 오류 복구 + Tumbling/Hopping Window로 집계 처리**!
💪 오늘의 실습 과제
Atlas에서 다음 3단계 → 스크린샷:
atlas streams instances create "test-spi"- mongosh 연결 →
sp.process([{ $source: { connectionName: "sample_stream_solar" } }]) - 10초 윈도우 집계 Processor 생성 →
sp.<name>.start()
📖 MongoDB in Action 16강: Atlas Data Federation 완전 가이드! S3+Atlas 통합 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 16장 “Optimizing data processing with Atlas Data Federation”를 함께 공부하는 16강입니다. 저자분께서 ETL 없이 S3/Blob/Atlas 통합 쿼리 혁신을 소개해 주셨어요! Federated DB 인스턴스 생성부터 Virtual Collection으로 멀티 소스 데이터 실시간 분석 실습하세요!
🎯 저자분의 핵심 메시지: ETL 없이 데이터 연합
“Atlas Data Federation allows querying AWS S3/Azure Blob via MongoDB Query API without moving data.”
저자분께서 말씀하시는 핵심은 ETL=비용/복잡 → Data Federation=0 이동이라는 거예요! S3/Atlas/Online Archive Virtual DB로 단일 쿼리 API! 제가 쉽게 풀어보면, 마치 여러 창고 재고=하나의 ERP처럼 분산 데이터=하나의 뷰로 분석하는 거죠!
💡 16.2 Data Federation 아키텍처 4계층
|
1 2 3 4 5 6 |
Application & Services (Compass/Driver) ↓ (Control Plane) Compute Plane (쿼리 노드 풀) ↓ (Data Plane) Atlas + S3 + Blob + HTTP |
Virtual Database:
|
1 2 3 4 5 6 |
S3/parquet → Virtual Collection1 Atlas/movies → Virtual Collection2 Online Archive → Virtual Collection3 ↓ db.federated.find() // 단일 쿼리! |
💡 16.3 Federated DB 인스턴스 생성 실습
Atlas UI 절차:
- Data Federation → Create Federated Database
- Name:
my-federation - Data Sources: Atlas 클러스터 + S3 버킷 추가
- Storage Config (JSON 매핑):
|
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "sample_mflix.movies": { "provider": "Atlas", "clusterName": "MongoDB-in-Action" }, "s3-sales": { "provider": "S3", "bucket": "my-sales-bucket", "prefix": "parquet/" } } |
- Create → mongosh 연결
💡 16.4 제한사항 + 비용 구조
| 제한 | 내용 |
|---|---|
| 연결 | 60개/리전 |
| 쿼리 | 동시 30개 |
| 문서 | 16MB 초과 금지 |
| 인덱스 | ❌ 생성 불가 |
| 모니터링 | ❌ Atlas Metrics 없음 |
비용 (AWS 기준):
|
1 2 3 |
처리량: $5/TB (최소 10MB/쿼리) 전송량: $0.01/GB (동일 리전) |
최적화 팁:
|
1 2 3 4 |
✅ 동일 리전 S3 사용 ✅ 파티션 활용 (10GB→1GB 쿼리) ✅ limit() 필수 |
📌 저스틴의 16장 정리
첫째, 저자분의 4계층 아키텍처 (App→Control→Compute→Data) 완벽 이해!
둘째, ETL 0원으로 S3/Atlas/Archive Virtual DB 단일 쿼리!
셋째, 동시 30쿼리/60연결 제한 + $5/TB 비용 구조 파악!
💪 오늘의 실천 과제
Atlas UI에서 다음 3단계 → 스크린샷:
- Data Federation → Create → Atlas 클러스터 연결
- S3 버킷 매핑 JSON 작성 (가상)
- mongosh 연결문자열 복사 +
show dbs확인
📖 MongoDB in Action 17강: Atlas Online Archive 완전 가이드! 저비용 아카이빙 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 17장 “Archiving online with Atlas Online Archive”를 함께 공부하는 17강입니다. 저자분께서 활성 데이터=M10 고가, 비활성 데이터=S3 저가 비용 최적화 전략을 공개해 주셨어요! M10+에서 5분만에 아카이빙 룰 설정하고, Federated DB로 활성+아카이브 통합 쿼리 실습하세요!
🎯 저자분의 핵심 메시지: 비용 최적화 아카이빙
“Atlas Online Archive moves infrequently accessed data to lower-cost storage while keeping it queryable.”
저자분께서 말씀하시는 핵심은 아카이빙=저비용 저장+쿼리 가능이라는 거예요! 활성 데이터(M10 SSD)와 비활성 데이터(S3 Glacier) 분리 저장 + Federated DB로 통합 쿼리! 제가 쉽게 풀어보면, 마치 자주 입는 옷=옷장, 옷장 안 입는 옷=박스처럼 비용 최적화입니다!
💡 17.1 아카이빙 룰 설정 (Table 17.1)
M10+에서만 가능!
| 컬렉션 타입 | 기준 | 예시 |
|---|---|---|
| Standard | saleDate + 5일 |
saleDate < now-5days |
| Time Series | timeField + 30일 |
IoT/로그 |
실습: sample_supplies.sales (5일 후 아카이빙)
|
1 2 3 4 5 |
atlas clusters onlineArchive create \ --clusterName MongoDB-in-Action-M10 \ --db sample_supplies --coll sales \ --dateField saleDate --archiveAfter 5 |
인덱스 필수:
|
1 2 |
db.sales.createIndex({ saleDate: 1 }) |
💡 17.2 아카이빙 동작 원리
|
1 2 3 4 |
1. 5분마다 Job 실행 (2GB 미만→지연) 2. Atlas 클러스터 → S3 (아카이빙) 3. Atlas 클러스터에서 삭제 (중복 제거) |
파티션 필드 (쿼리 최적화):
|
1 2 |
--partitionFields saleDate,customer_age |
아카이빙 상태:
|
1 2 3 4 |
atlas clusters onlineArchive list --clusterName MongoDB-M10 # ID DB COLL STATE # 6677 sample_supplies sales ACTIVE |
💡 17.3 Federated DB 연결+쿼리
3가지 연결문자열:
|
1 2 3 4 |
1. 클러스터+아카이브 (권장) 2. 클러스터만 3. 아카이브만 (read-only) |
|
1 2 3 4 5 |
// 통합 쿼리 mongosh "mongodb://atlas-online-archive-xxx.mongodb.net/" --username manning show dbs // sample_supplies (아카이브 데이터 포함) db.sales.countDocuments() // 5000 (아카이브 데이터) |
💡 17.4 복원(Restore) 절차
|
1 2 3 4 |
1. atlas clusters onlineArchive pause <ID> 2. 대상 클러스터에 유니크 인덱스 생성 3. 아카이브 → $merge 복원 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 1. 일시정지 atlas clusters onlineArchive pause 66771d91... // 2. 대상에 인덱스 db.sales.createIndex({ saleDate: 1, customer: 1 }, { unique: true }) // 3. 복원 db.sales.aggregate([{ $merge: { into: { atlas: { clusterName: "MongoDB-M10", db: "sample_supplies", coll: "sales" } }, on: ["saleDate", "customer"], whenMatched: "keepExisting", whenNotMatched: "insert" } }]) |
📌 저스틴의 17장 정리
첫째, 저자분의 M10+에서 atlas clusters onlineArchive create 5분 설정!
둘째, saleDate + 5일 자동 S3 이동 + Federated DB 통합 쿼리!
셋째, $merge로 필요시 복원 + 비용=데이터 스캔량!
💪 오늘의 실천 과제
M10+ 클러스터에서 다음 4단계 → 스크린샷:
atlas clusters onlineArchive create --dateField saleDate --archiveAfter 5atlas clusters onlineArchive list(ACTIVE 확인)- Federated DB 연결 →
db.sales.countDocuments() - Atlas UI Online Archive 대시보드
📖 MongoDB in Action 18강: Atlas SQL Interface 완전 가이드! $sql + db.sql() 실습 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 18장 “Querying MongoDB Atlas using SQL”를 함께 공부하는 18강입니다. 저자분께서 NoSQL에 SQL 혁신을 소개해 주셨어요! Data Federation 기반 $sql 파이프라인 + db.sql() 단축문법으로 Power BI/Tableau 연동 가능한 하이브리드 쿼리 실습하세요!
🎯 저자분의 핵심 메시지: MongoDB에 SQL 추가
“Atlas SQL Interface uses MongoDB-native SQL-92 compatible dialect (mongosql).”
저자분께서 말씀하시는 핵심은 Atlas SQL = NoSQL+SQL 통합이라는 거예요! Data Federation 위에 SQL-92 얹어서 SELECT/WHERE 직접 사용! 제가 쉽게 풀어보면, 마치 엑셀=SQL+NoSQL처럼 하이브리드 분석 가능하다는 거죠!
💡 18.2 Atlas SQL Interface 활성화
Atlas UI → Connect → Atlas SQL → Quick Start
|
1 2 3 4 |
1. 클러스터 선택 (M0 이상) 2. Create → Data Federation 자동 생성 3. mongosh 연결문자열 복사 |
|
1 2 |
mongosh "mongodb://atlas-sql-xxx.mongodb.net/" --username manning |
💡 18.3 SQL 쿼리 2가지 문법
🔹 1. $sql Aggregation Pipeline (Listing 18.1)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use sample_analytics db.customers.aggregate([{ $sql: { statement: ` SELECT * FROM customers WHERE username = 'valenciajennifer' AND email = 'cooperalexis@hotmail.com' `, format: "jdbc", dialect: "mongosql" } }]) |
🔹 2. db.sql() 단축문법 (Listing 18.2)
|
1 2 3 4 5 6 |
db.sql(` SELECT username, name, address FROM customers WHERE username = 'valenciajennifer' `) |
💡 18.3.3 배열/중첩 처리: UNWIND + FLATTEN
🔹 UNWIND: 배열 펼치기
|
1 2 3 4 |
SELECT account_id, products AS product FROM UNWIND(accounts WITH PATH => products) WHERE account_id = 198100 |
|
1 2 3 |
{ account_id: 198100, product: 'Derivatives' } { account_id: 198100, product: 'CurrencyService' } |
🔹 FLATTEN: 중첩 플랫화
|
1 2 3 |
SELECT * FROM FLATTEN(routes) WHERE src_airport = 'KZN' AND dst_airport = 'ASF' |
|
1 2 |
routes: { airline_alias: '2B', airline_name: 'Aerocondor', ... } |
💡 18.4 제한사항 (SQL-92 준수)
|
1 2 3 4 5 6 |
❌ UNION (UNION ALL만) ❌ date (timestamp 사용) ❌ SELECT DISTINCT ❌ Interval 산술 ❌ Atlas Search/Vector Search |
📌 저스틴의 18장 정리
첫째, 저자분의 Data Federation + mongosql로 MongoDB에 SQL 추가!
둘째, $sql 파이프라인 + db.sql() 단축 2가지 문법 완벽 익히기!
셋째, UNWIND/FLATTEN으로 배열/중첩 데이터 관계형 변환!
💪 오늘의 실천 과제
Atlas SQL Quick Start 후 다음 3개 → 스크린샷:
- Connect → Atlas SQL → Quick Start → mongosh 연결
db.customers.aggregate([{$sql: {statement: "SELECT * FROM customers WHERE username='test'" }}])db.sql("SELECT COUNT(*) FROM customers")
📖 MongoDB in Action 19강: Atlas Charts + Triggers 완전 실습! 시각화+이벤트 자동화 🚀
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 19장 “Creating Atlas charts, database triggers, and functions”를 함께 공부하는 19강입니다. 저자분께서 자연어 차트 생성 + 실시간 트리거 완전 자동화 방법을 공개해 주셨어요! “맨하탄 최고 음식점” → 자동 차트 + INSERT시 자동 OpenAI 임베딩 실습으로 운영 완전 자동화하세요!
🎯 저자분의 핵심 메시지: No-Code 시각화 + Serverless 트리거
“Atlas Charts: no-code interface… Database triggers automatically execute functions.”
저자분께서 말씀하시는 핵심은 Atlas = No-Code + Serverless라는 거예요! 영어로 “최고 레스토랑” → 자동 차트 + INSERT → 자동 함수 실행! 제가 쉽게 풀어보면, 마치 음성 비서=영어 명령→실행처럼 Atlas도 자연어/이벤트→자동화입니다!
💡 19.1 Atlas Charts: 자연어 시각화
| 타입 | 용도 |
|---|---|
| Natural Language | "맨하탄 최고 음식 10개" |
| Column/Bar | 범주 비교 |
| Line/Area | 시계열 트렌드 |
| Heatmap | 상관관계 |
| Scatter | 분포 |
자연어 예시 (Figure 19.2):
|
1 2 |
"맨하탄별 최고 10개 요리" → 자동 Bar Chart 생성! |
Billing Dashboard:
|
1 2 |
월별 비용 / 프로젝트별 / 인스턴스 크기별 자동 시각화 |
💡 19.2 Database Triggers: 실시간 자동화
| 트리거 | 트리거 조건 |
|---|---|
| Database | INSERT/UPDATE/DELETE |
| Scheduled | CRON */1 * * * * (매분) |
| Authentication | 로그인/회원가입 |
🔹 Database Trigger 생성 (Listing 19.1)
|
1 2 3 4 |
Atlas UI → Triggers → Add Trigger → Database Watch: sample_mflix.sessions (INSERT/UPDATE) Function: |
|
1 2 3 4 5 6 7 8 9 10 |
exports = async function(changeEvent) { const logs = context.services.get("Cluster").db("sample_mflix").collection("logs"); await logs.insertOne({ operation: changeEvent.operationType, documentId: changeEvent.documentKey._id, timestamp: new Date() }); }; |
💡 19.2.2 Atlas Functions: 서버리스 JS
실행 환경:
|
1 2 3 4 5 |
✅ MongoDB 접근 (context.services) ✅ HTTP API 호출 ✅ 다른 Function 호출 ✅ npm 패키지 사용 |
예시 (Listing 19.2):
|
1 2 3 4 5 6 7 8 |
exports = async function() { const response = await context.http.get({ url: 'https://api.example.com/user', headers: { 'Authorization': `Bearer ${context.user.id}` } }); return JSON.parse(response.body.text()).name; }; |
📌 저스틴의 19장 정리
첫째, 저자분의 자연어=”맨하탄 최고 음식” → 자동 차트 No-Code 시각화!
둘째, Database/Scheduled/Auth 3대 트리거 + 서버리스 Function 실시간 자동화!
셋째, Billing Dashboard로 비용 자동 모니터링!
💪 오늘의 실습 과제
Atlas UI에서 다음 3개 → 스크린샷:
- Charts → Natural Language →
"sample_mflix 최고 평점 영화 10개" - Triggers → Database Trigger 생성 → sample_mflix.movies INSERT 로그
- Billing Dashboard 월별 비용 차트
📖 MongoDB in Action 20강: Atlas 보안 완전 가이드! 공유 책임 + 암호화 실습 🔒
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 20장 “Understanding Atlas and MongoDB security features”를 함께 공부하는 20강입니다. 저자분께서 공유 책임 모델 + 5대 보안 영역 완전 체계를 공개해 주셨어요! IP 화이트리스트 → VPC Peering → CSFLE → Audit → Defense in Depth 실습으로 금융/의료급 보안 구현하세요!
🎯 저자분의 핵심 메시지: 공유 책임 모델
“MongoDB Atlas: SaaS model where security tasks are divided between MongoDB, cloud providers, and customers.”
저자분께서 말씀하시는 핵심은 3계층 책임 분담이라는 거예요!
|
1 2 3 4 |
고객: 데이터/접근 제어 MongoDB: 플랫폼/암호화/백업 클라우드: 물리 보안 |
제가 쉽게 풀어보면, 마치 **아파트=관리사무소(운영)+세입자(데이터)+건물주(물리)**처럼 보안도 3단 책임입니다!
💡 20.1 공유 책임 모델 상세 (Table 20.1)
| 영역 | 고객 | MongoDB | 클라우드 |
|---|---|---|---|
| 인프라 | 리전/티어 선택 | 클러스터 프로비저닝 | 물리 보안 |
| 접근 | IAM/LDAP/MFA | SCRAM/X.509 | 네트워크 |
| 암호화 | KMS/BYOK 설정 | TLS/AES-256 자동 | 스토리지 |
| 감사 | 필터 설정 | 로그 생성 | – |
💡 20.2 인증: 5대 방법
🔹 SCRAM (기본, 비밀번호 해싱)
|
1 2 |
가장 보편적, 모든 드라이버 지원 |
🔹 X.509 인증서 (상호 인증)
|
1 2 |
금융/의료 추천, PKI 기반 |
🔹 OAuth 2.0/OIDC (SSO)
|
1 2 |
Google/Okta/Azure AD 통합 |
🔹 AWS IAM (비밀번호리스)
|
1 2 |
EC2/Lambda 자동 인증 |
🔹 LDAP (엔터프라이즈, 8.0 deprecated)
|
1 2 |
Active Directory 통합 |
💡 20.3 권한: 최소 권한 원칙(RBAC)
Atlas 역할:
|
1 2 3 4 |
Organization Owner → 모든 권한 Project Owner → 프로젝트 관리 Read Only → 조회만 |
DB 역할:
|
1 2 3 4 |
atlasAdmin → 전체 관리 readWriteAnyDatabase → 모든 DB 읽기/쓰기 read → 특정 DB 읽기 |
커스텀 역할:
|
1 2 3 |
atlas customDbRoles create readMongoDB \ --privilege 'READ@sample_training.mongodb' |
💡 20.4 감사(Auditing): 모든 행동 추적
Audit 이벤트:
|
1 2 3 |
authCheck → find/insert/update/delete authenticate → 로그인 시도 |
필터 예시:
|
1 2 3 4 5 6 |
{ "users.user": {"$nin": ["backup"]}, "param.command": {"$in": ["find", "insert"]}, "param.ns": {"$nin": [{"$regex": "^config\\."}]} } |
💡 20.5 암호화 3단계
🔹 1단계: 전송 중 (TLS 1.2+ 자동)
|
1 2 |
모든 트래픽 자동 암호화 (끄기 불가) |
🔹 2단계: 저장 시 (AES-256 자동)
|
1 2 |
클라우드 제공 KMS + WiredTiger ESE |
🔹 3단계: 클라이언트 측 (CSFLE)
|
1 2 |
app에서 암호화 → MongoDB는 암호문만 저장 |
Queryable Encryption:
|
1 2 |
암호화 상태로 범위/접두사 검색 가능 (미래) |
💡 20.6 네트워크 보안
|
1 2 3 |
IP Access List → VPC Peering → Private Endpoint ↓ 보안성↑ ↓ 지연↓ |
|
1 2 |
atlas accessLists create --currentIp # 현재 IP 허용 |
📌 저스틴의 20장 정리
첫째, 저자분의 공유 책임 3계층 (고객/Atlas/클라우드) 완벽 이해!
둘째, SCRAM/X.509/OIDC/IAM/LDAP 5대 인증 + RBAC 최소 권한!
셋째, TLS/AES/CSFLE 3단계 암호화 + Audit+IP 화이트리스트!
💪 오늘의 실천 과제
Atlas 프로젝트에서 다음 4개 → 스크린샷:
- Network Access → IP Access List 추가
- Database Access → Custom Role 생성 (
READ@sample_training) - Audit → 필터 설정 (
find만) - Project Settings → Encryption → Customer KMS 활성화
📖 MongoDB in Action 21강: Atlas 운영 완전 자동화! 백업+모니터링 실습 ⚙️
안녕하세요, 여러분! 일타 강사 저스틴입니다! 🚀
오늘은 “MongoDB in Action, Third Edition”의 21장 “Operational excellence with MongoDB Atlas”를 함께 공부하는 21강입니다. 저자분께서 자동 백업+실시간 모니터링+성능 최적화 완전 운영 체계를 공개해 주셨어요! Continuous Backup→Performance Advisor→Alerting 실습으로 Zero-Downtime 운영 마스터하세요!
🎯 저자분의 핵심 메시지: 자동화된 운영 우수성
“Atlas provides automatic backups, real-time monitoring, alerting… ensuring optimal performance.”
저자분께서 말씀하시는 핵심은 Atlas=운영 자동화라는 거예요! 백업/모니터링/알림/최적화 전체 자동! 제가 쉽게 풀어보면, 마치 스마트홈=온도/조명/보안 자동처럼 DB도 모든 운영 자동입니다!
💡 21.1 백업 전략 (M0→Flex→M10+)
| 클러스터 | 백업 | PITR | CLI 지원 |
|---|---|---|---|
| M0 | ❌ | ❌ | mongodump |
| Flex | 일일 스냅샷 | ❌ | UI만 |
| M10+ | 연속+온디맨드 | 1분 단위 | ✅ |
🔹 M10+ 백업 활성화
|
1 2 3 |
atlas clusters create "M10-Backup" --backup \ --provider GCP --tier M10 --mdbVersion 8.0 |
스케줄 확인:
|
1 2 |
atlas backups schedule describe M10-Backup |
|
1 2 |
HOURLY(7일) → DAILY(7일) → WEEKLY(4주) → MONTHLY(12개월) → YEARLY(1년) |
🔹 온디맨드 백업
|
1 2 3 |
atlas backups snapshots create M10-Backup --desc "테스트" atlas backups snapshots list M10-Backup # 진행상황 |
💡 21.2 복구(Restore) 실습
🔹 Automated Restore (동일 클러스터)
|
1 2 3 4 5 |
atlas backups restores start automated \ --clusterName M10-Backup \ --targetClusterName M10-Backup \ --snapshotId <ID> |
🔹 Point-in-Time Restore (1분 단위)
|
1 2 3 4 5 |
atlas backups restores start pointInTime \ --clusterName M10-Backup \ --pointInTimeUTCSeconds <TIMESTAMP> \ --targetClusterName Restore-Test |
💡 21.2.1 성능 모니터링 도구
🔹 Performance Advisor (느린 쿼리+인덱스 추천)
|
1 2 3 |
atlas performanceAdvisor namespaces list --processName <node> atlas performanceAdvisor suggestedIndexes list --processName <node> |
🔹 Real-Time Performance Panel (RTPP)
|
1 2 3 |
CPU/메모리/디스크/쿼리 지연 실시간 M10+에서만 가능 |
🔹 Namespace Insights (컬렉션별 지연)
|
1 2 |
컬렉션 단위 쿼리 성능 분석 |
💡 21.3 Alerting + Logging
🔹 Alert 설정
|
1 2 3 4 5 6 7 |
atlas alerts settings create \ --event OUTSIDE_METRIC_THRESHOLD \ --metricName QUERY_TARGETING_SCANNED_OBJECTS_PER_RETURNED \ --metricThreshold 1000 \ --notificationType EMAIL \ --notificationEmail your@email.com |
🔹 로그 다운로드
|
1 2 |
atlas logs download <hostname> mongodb.gz |
📌 저스틴의 21장 정리
첫째, 저자분의 M10+ 연속 백업(1분 PITR) + 온디맨드 스냅샷 완벽 이해!
둘째, Performance Advisor+Query Profiler+RTPP 3대 모니터링 툴!
셋째, 자동 Alerting+Logging으로 Zero-Touch 운영!
💪 오늘의 실천 과제
M10+ 클러스터에서 다음 4개 → 스크린샷:
atlas clusters create M10-Backup --backupatlas backups snapshots create M10-Backup- Performance Advisor 느린 쿼리 목록
- Alert 설정 (Query Targeting > 1000)
