Cloud Firestore
개요
Cloud Firestore는 Google Cloud의 완전 관리형 NoSQL 문서 데이터베이스로, DTA-WIDE 시스템에서 다음과 같은 용도로 사용됩니다:
- 사용자 프로필 데이터 저장
- 애플리케이션 설정 관리
- 실시간 데이터 동기화
- 비정형 데이터 저장소
모드 및 구성
DTA-WIDE는 다음과 같은 Firestore 구성을 사용합니다:
- 모드: Native 모드
- 리전: europe-west3 (Frankfurt)
- 데이터베이스 유형: 기본 데이터베이스
다중 데이터베이스 구성
Firestore의 다중 데이터베이스 기능을 활용하여 다음과 같은 용도별 데이터베이스를 구성했습니다:
| 데이터베이스 ID | 용도 |
|---|---|
| (default) | 기본 데이터베이스, 공통 데이터 저장 |
| analytics | 분석 데이터 저장 |
| dbm-ios | iOS 앱 관련 데이터 관리 |
| dbm-android | Android 앱 관련 데이터 관리 |
| genai | 생성형 AI 관련 데이터 저장 |
| logs-mobile | 모바일 애플리케이션 로그 저장 |
| medical-statement | 의료 명세서 관련 데이터 저장 |
| mobile | 공통 모바일 데이터 저장 |
각 데이터베이스는 독립적인 스토리지 및 처리량 할당량을 가지며, 특정 워크로드에 맞게 최적화되어 있습니다.
데이터 모델
컬렉션 구조
DTA-WIDE 시스템은 다음과 같은 주요 컬렉션을 사용합니다:
| 컬렉션 이름 | 설명 | 주요 필드 |
|---|---|---|
| users | 사용자 프로필 정보 | email, name, created_at |
| posts | 게시물 데이터 | author_id, title, content, published_at, tags |
| settings | 애플리케이션 설정 | environment, debug_mode, api_timeout |
| analytics | 분석 데이터 | user_id, event_type, timestamp, data |
인덱스 설정
성능 최적화를 위해 다음과 같은 복합 인덱스가 구성되어 있습니다:
| 컬렉션 | 인덱스 필드 | 순서 | 용도 |
|---|---|---|---|
| users | email, created_at | ASC, DESC | 사용자 검색 및 정렬 |
| posts | author_id, published_at | ASC, DESC | 작성자별 최신 게시물 조회 |
| posts | tags, published_at | ARRAY_CONTAINS, DESC | 태그별 최신 게시물 조회 |
| analytics | user_id, event_type, timestamp | ASC, ASC, DESC | 사용자별 이벤트 분석 |
액세스 패턴
데이터 읽기
- 단일 문서 읽기: 문서 ID를 사용한 직접 조회
- 컬렉션 쿼리: 필터링, 정렬 및 페이징을 적용한 쿼리
- 실시간 리스너: 데이터 변경 시 실시간 업데이트
데이터 쓰기
- 단일 문서 쓰기: 개별 문서 생성 및 업데이트
- 일괄 쓰기: 트랜잭션을 이용한 원자적 업데이트
- 자동 생성 ID: 문서 ID 자동 생성
보안 규칙
Firestore 보안 규칙은 Firebase Authentication과 함께 사용되어 데이터 액세스를 제어합니다:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// 사용자는 자신의 프로필만 읽고 쓸 수 있음
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// 게시물은 공개적으로 읽을 수 있지만 작성자만 수정 가능
match /posts/{postId} {
allow read: if true;
allow create: if request.auth != null;
allow update, delete: if request.auth != null &&
request.auth.uid == resource.data.author_id;
}
// 설정은 관리자만 접근 가능
match /settings/{document=**} {
allow read, write: if request.auth != null &&
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';
}
}
}
모범 사례
데이터 모델링
- 중첩 데이터 대신 별도 컬렉션 사용
- 쿼리 패턴에 맞는 문서 구조 설계
- 큰 문서 분할 (1MB 제한)
쿼리 최적화
- 필요한 필드만 조회
- 적절한 복합 인덱스 구성
- IN 쿼리 대신 OR 조건 사용 제한
비용 관리
- 불필요한 인덱스 제거
- 불필요한 읽기/쓰기 최소화
- 대량 데이터는 Cloud Storage 사용
다중 데이터베이스 활용
- 도메인별 워크로드 분리
- 읽기/쓰기 부하 분산
- 데이터 격리 및 보안 강화
- 용도별 확장성 관리
Terraform을 통한 인프라 관리
구현 요소
Firestore를 Terraform으로 관리하기 위해 다음 요소를 구현했습니다:
- Terraform 모듈: 재사용 가능한 Firestore 구성
- Terragrunt 구성: 환경별 설정값 관리
- 배포 파이프라인: CI/CD와 통합
Terraform 모듈 구조
Firestore 모듈은 다음과 같은 구조로 구현되어 있습니다:
infrastructure/
└── terraform/
└── modules/
└── firestore/
├── main.tf # 리소스 정의
├── variables.tf # 입력 변수
├── outputs.tf # 출력 변수
└── README.md # 사용 가이드
주요 기능
- Native 모드 Firestore 데이터베이스 생성
- 다중 데이터베이스 관리
- 컬렉션 인덱스 관리
- 초기 문서 데이터 설정
- 필요한 API 활성화
환경별 Terragrunt 구성
개발, 스테이징, 프로덕션 환경별로 다음과 같이 Terragrunt 구성 파일이 작성되어 있습니다:
infrastructure/
└── terragrunt/
├── dev/
│ └── firestore/
│ └── terragrunt.hcl # 개발 환경 구성
├── stage/
│ └── firestore/
│ └── terragrunt.hcl # 스테이징 환경 구성
└── prod/
└── firestore/
└── terragrunt.hcl # 프로덕션 환경 구성
환경별 주요 설정
- 개발 환경: 기본 인덱스, 디버그 모드 활성화, 전체 데이터베이스 세트
- 스테이징 환경: 개발 환경과 동일한 인덱스, 디버그 모드 비활성화, 전체 데이터베이스 세트
- 프로덕션 환경: 추가 인덱스 구성, 성능 최적화 설정, 전체 데이터베이스 세트
배포 방법
Firestore 리소스를 배포하려면 다음 단계를 따릅니다:
사전 요구 사항
- 프로젝트가 생성되어 있어야 합니다.
- Firestore API가 활성화되어 있어야 합니다:
gcloud services enable firestore.googleapis.com --project=PROJECT_ID - Terraform 및 Terragrunt가 설치되어 있어야 합니다.
- 적절한 GCP 권한이 필요합니다.
배포 단계
개발 환경 배포:
cd infrastructure/terragrunt/dev/firestore
terragrunt init
terragrunt plan
terragrunt apply
프로덕션 환경은 변경 관리 절차를 따라야 합니다:
cd infrastructure/terragrunt/prod/firestore
terragrunt init
terragrunt plan -out=firestore-plan.tfplan
# 계획 검토 및 승인 후
terragrunt apply firestore-plan.tfplan
문제 해결
Provider produced inconsistent result after apply 오류
기존 GCP 프로젝트에 Terraform으로 Firestore 데이터베이스를 프로비저닝할 때 다음과 같은 오류가 발생할 수 있습니다:
Error: Provider produced inconsistent result after apply
When applying changes to google_firestore_database.database, provider
"provider[\"registry.terraform.io/hashicorp/google\"]" produced an
unexpected new value: Root object was present, but now absent.
This is a bug in the provider, which should be reported in the provider's
own issue tracker.
원인:
- 이 오류는 Firestore 데이터베이스가 이미 존재하는 프로젝트에서 Terraform이 해당 리소스를 새로 생성하려고 할 때 발생합니다.
- 또는 Terraform 상태와 실제 GCP 상태가 일치하지 않는 경우 발생할 수 있습니다.
해결 방법:
-
기존 리소스 임포트:
# 개발 환경
cd infrastructure/terragrunt/dev/firestore
terragrunt import 'google_firestore_database.database' 'PROJECT_ID/(default)'
# 스테이징 환경
cd infrastructure/terragrunt/stage/firestore
terragrunt import 'google_firestore_database.database' 'PROJECT_ID/(default)'
# 프로덕션 환경
cd infrastructure/terragrunt/prod/firestore
terragrunt import 'google_firestore_database.database' 'PROJECT_ID/(default)'주의: PROJECT_ID는 각 환경에 맞는 프로젝트 ID로 대체해야 합니다.
- 개발:
dta-cloud-de-dev - 스테이징:
dta-cloud-de-stage - 프로덕션:
dta-cloud-de-prod
- 개발:
-
임포트 후 재시도: 임포트 후 다시
terragrunt apply명령을 실행해야 합니다:terragrunt apply -
새 환경 설정 시: 새 환경을 설정할 때는 항상 다음 순서를 따르세요:
- Firestore API 활성화
- 초기 Terraform 상태 임포트
- 나머지 리소스 적용
주의사항
- Firestore 모드(Native/Datastore)는 프로젝트당 한 번만 설정 가능하며 추후 변경 불가
- 데이터베이스 위치(리전)는 생성 후 변경 불가
- 인덱스 추가는 즉시 가능하지만 제거는 주의가 필요함
- Terraform을 통한 대용량 문서 관리는 권장하지 않음 (애플리케이션 코드에서 관리)
- 다중 데이터베이스는 Firestore Native 모드에서만 지원됨 (Datastore 모드는 지원 안 함)
- 프로젝트당 최대 100개의 Firestore 데이터베이스 생성 가능
연결 방법
클라이언트 라이브러리
다양한 언어로 Firestore에 접근 가능합니다:
-
Node.js:
const { Firestore } = require('@google-cloud/firestore');
// 기본 데이터베이스 연결
const defaultDb = new Firestore();
// 특정 데이터베이스 연결
const analyticsDb = new Firestore({
databaseId: 'analytics'
}); -
Python:
from google.cloud import firestore
# 기본 데이터베이스 연결
default_db = firestore.Client()
# 특정 데이터베이스 연결
mobile_db = firestore.Client(database='mobile')
인증 설정
서비스 계정을 사용한 인증:
# 환경 변수 설정
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
주요 기능
- 실시간 데이터 동기화
- 오프라인 지원
- 자동 인덱싱
- ACID 트랜잭션
- 다중 데이터베이스 지원
모니터링 및 운영
모니터링 지표
- 읽기/쓰기 작업 수
- 인덱스 사용률
- 스토리지 사용량
- 오류율
- 데이터베이스별 성능 지표
성능 최적화
- 인덱스 최적화
- 배치 작업 사용
- 적절한 쿼리 구성
- 데이터 분산 전략
- 워크로드에 따른 데이터베이스 분리
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-03-28 | bok@weltcorp.com | 최초 작성 |