Skip to content

ADR-07: 공유 인프라 전략 ​

English Version

날짜작성자영향 리포지토리
2024-12-17@KubrickCode전체

Context ​

문제 상황 ​

여러 서비스로 구성된 분산 시스템에서, 데이터베이스와 캐시 같은 공유 인프라를 어떻게 관리할 것인가는 핵심적인 아키텍처 결정. 이 결정은 다음에 영향을 미침:

  1. 데이터 일관성: 서비스 간 데이터 무결성 유지 방법
  2. 운영 복잡도: 관리해야 할 인프라 구성요소 수
  3. 비용 효율: 리소스 활용률과 인프라 비용
  4. 서비스 독립성: 서비스별 독립 배포 및 스케일링 가능 여부
  5. 장애 격리: 인프라 장애 시 영향 범위

데이터 인프라 스펙트럼 ​

접근 방식데이터 일관성운영 오버헤드서비스 독립성비용
공유 데이터베이스강함 (ACID)낮음낮음낮음
서비스별 스키마강함 (ACID)낮음~중간중간낮음
서비스별 데이터베이스최종 일관성높음높음높음
하이브리드 (읽기 복제)혼합중간중간중간

핵심 결정 요소 ​

  • 팀 구조: 단일 팀 vs 서비스별 독립 팀
  • 데이터 관계: 서비스 간 데이터 연산 빈도
  • 일관성 요구사항: 강한 일관성 필요 vs 최종 일관성 허용
  • 운영 역량: DevOps/DBA 전문성 보유 여부
  • 스케일 요구사항: 현재 및 예상 트래픽 패턴
  • 컴플라이언스: 데이터 격리 또는 멀티테넌시 요구사항

핵심 질문 ​

공유 상태에 대한 접근이 필요한 여러 서비스가 있는 시스템에서, 운영 단순성과 아키텍처 유연성의 균형을 맞추기 위해 데이터베이스와 캐시 인프라를 어떻게 구성해야 하는가?

Decision ​

모든 서비스가 공통 데이터베이스와 캐시 인스턴스에 접근하는 공유 인프라 전략을 채택한다.

핵심 원칙:

  • 운영 단순화: 데이터 인프라의 단일 관리 지점
  • 데이터 일관성: 서비스 경계를 넘는 ACID 트랜잭션 활용
  • 비용 효율: 공유를 통한 리소스 활용 극대화
  • 실용적 트레이드오프: 복잡도 감소를 위해 결합도 수용
  • 진화 경로: 필요시 분해를 위한 설계 고려

Options Considered ​

Option A: 공유 인프라 (선택됨) ​

모든 서비스가 단일 데이터베이스 인스턴스와 공유 캐시 계층에 연결함.

장점:

  • 운영 단순화: 단일 데이터베이스 모니터링, 백업, 유지보수
  • 강한 일관성: 서비스 간 데이터에 대한 ACID 트랜잭션, 조율 불필요
  • 비용 효율: 인프라 중복 없음, 연결 풀 공유
  • 쿼리 단순화: API 오케스트레이션 없이 서비스 간 데이터 조인
  • 통합 스키마: 단일 진실 공급원, 이해 용이
  • 지연 시간 감소: 서비스 간 데이터 접근에 네트워크 홉 없음

단점:

  • 강한 결합: 스키마 변경 시 모든 서비스 간 조율 필요
  • 공유 운명: 데이터베이스 장애가 모든 서비스에 동시 영향
  • 스케일링 제약: 서비스별 독립 DB 스케일링 불가
  • 리소스 경쟁: 한 서비스의 무거운 쿼리가 다른 서비스에 영향
  • 기술 선택 제한: 모든 서비스가 호환 가능한 데이터 모델 사용 필수
  • 마이그레이션 복잡도: 나중에 서비스 분리 시 어려움

Option B: 서비스별 데이터베이스 ​

각 서비스가 전용 데이터베이스 인스턴스를 소유하고 관리함.

장점:

  • 서비스 독립성: 각 팀이 데이터 모델과 스키마 진화 제어
  • 장애 격리: 데이터베이스 문제가 개별 서비스에 한정
  • 독립 스케일링: 서비스 요구에 따른 데이터베이스 리소스 스케일링
  • 기술 자유도: 각 서비스가 최적의 데이터베이스 기술 선택 가능
  • 명확한 소유권: 데이터 책임에 대한 모호함 없음
  • 팀 자율성: 독립적 배포 및 마이그레이션 일정

단점:

  • 운영 오버헤드: 여러 데이터베이스 관리, 모니터링, 백업 필요
  • 데이터 일관성: 분산 트랜잭션 또는 최종 일관성 필요
  • 높은 비용: 더 많은 인스턴스, 연결, 인프라
  • 쿼리 복잡도: 서비스 간 데이터는 API 호출 또는 이벤트 동기화 필요
  • 데이터 중복: 비정규화 필요한 경우 많음
  • 조율 오버헤드: 서비스 간 통신 패턴 필요

Option C: 서비스별 스키마 ​

단일 데이터베이스 인스턴스에서 각 서비스별로 격리된 스키마 사용함.

장점:

  • 논리적 분리: 인프라를 공유하면서 명확한 경계
  • 마이그레이션 경로: 나중에 완전 분리로의 전환 용이
  • 비용 효율: 논리적 격리를 가진 단일 인스턴스
  • 일부 독립성: 스키마 변경이 서비스 스키마 내에 한정
  • 균형 잡힌 트레이드오프: 공유와 격리 사이의 중간 지점

단점:

  • 여전히 공유 운명: 인스턴스 수준 장애가 모든 서비스에 영향
  • 리소스 경쟁: 공유된 컴퓨팅 및 I/O 리소스
  • 경계 침범 유혹: 스키마 간 의존성 생성 용이
  • 부분적 이점: 완전한 격리나 완전한 공유의 이점 모두 부분적

Option D: 읽기 복제본을 활용한 하이브리드 ​

공유 주 데이터베이스와 서비스별 읽기 복제본 또는 캐시 사용함.

장점:

  • 읽기 확장성: 읽기 부하를 복제본에 분산
  • 쓰기 일관성: 쓰기에 대한 단일 진실 공급원
  • 점진적 진화: 추가 분해를 위한 경로
  • 성능 최적화: 서비스별 읽기 최적화

단점:

  • 복제 지연: 읽기에 대한 최종 일관성
  • 복잡도: 관리할 여러 데이터 소스
  • 비용: 추가 복제본 인스턴스
  • 부분적 해결: 쓰기 스케일링 미해결

Consequences ​

Positive ​

  1. 운영 단순화

    • 단일 데이터베이스 인스턴스 모니터링 및 유지보수
    • 통합된 백업 및 재해 복구 절차
    • 중앙화된 성능 튜닝 및 최적화
    • 인프라 알림 피로도 감소
  2. 데이터 무결성

    • ACID 트랜잭션이 서비스 데이터 간 일관성 보장
    • 분산 트랜잭션 조율 불필요
    • 참조 무결성이 데이터베이스 수준에서 강제됨
    • 단일 진실 공급원으로 동기화 문제 제거
  3. 비용 효율

    • 리소스 공유를 통한 낮은 인프라 비용
    • 공유 연결 풀로 오버헤드 감소
    • 단일 관리형 데이터베이스 서비스 구독
    • 더 큰 인스턴스 크기에 대한 규모의 경제
  4. 개발 속도

    • API 오케스트레이션 없이 서비스 간 쿼리
    • 복잡한 데이터 관계에 대한 익숙한 관계형 패턴
    • 단일 데이터베이스로 단순화된 로컬 개발
    • 데이터 흐름 이해를 위한 인지 부하 감소
  5. 관찰 가능성

    • 통합된 쿼리 로그와 성능 메트릭
    • 느린 쿼리 분석을 위한 단일 지점
    • 데이터 접근 패턴의 전체적 뷰
    • 서비스 경계를 넘는 단순화된 디버깅

Negative ​

  1. 서비스 결합

    • 스키마 변경에 팀 간 조율 필요
    • 서비스 간 배포 의존성
    • 완화 방안: 명확한 스키마 소유권 설정, 하위 호환 변경 사용, 스키마 변경 리뷰 프로세스 구현
  2. 영향 범위

    • 데이터베이스 장애가 모든 의존 서비스에 영향
    • 유지보수 윈도우가 전체 시스템에 영향
    • 완화 방안: 고가용성 구성, 자동 장애 조치, 포괄적 백업 전략, 서비스의 서킷 브레이커
  3. 스케일링 제한

    • 서비스 워크로드별 독립적 데이터베이스 스케일링 불가
    • 리소스 집약적 작업이 모든 서비스에 영향
    • 완화 방안: 쿼리 최적화, 캐싱 전략, 읽기 부하가 높은 워크로드용 읽기 복제본, 연결 풀링
  4. 기술 제약

    • 모든 서비스가 동일한 데이터베이스 기술로 작업 필요
    • 다른 데이터 패턴에 대한 스토리지 최적화 불가
    • 완화 방안: 데이터베이스 기능 유연하게 사용 (JSON 컬럼 등), 특화된 요구를 위한 마이그레이션 경로 계획
  5. 장기 유연성

    • 독립 스케일링을 위한 서비스 추출 어려움
    • 공유 데이터 모델로 팀 자율성 제한
    • 완화 방안: 깔끔한 데이터 접근 계층 추상화, 스키마에서 서비스 경계 문서화, 분해 트리거 계획

Technical Implications ​

측면함의
스키마 관리단일 마이그레이션 경로, 파괴적 변경에 조율 필요
연결 풀링서비스 간 공유 풀, 적절한 크기 조정 필요
쿼리 성능서비스 간 영향, 쿼리 최적화 규율 필요
백업/복구단일 백업 전략, 통합된 특정 시점 복구
보안공유 접근 제어, 앱 계층에서 서비스 수준 권한
모니터링통합 메트릭, 쉬운 상관관계 분석, 공유 알림
로컬 개발더 간단한 설정, 단일 데이터베이스 컨테이너/인스턴스
테스팅공유 테스트 데이터베이스, 테스트 격리 전략 필요

캐시 인프라 고려사항 ​

공유 캐싱(Redis/Memcached)도 유사한 트레이드오프를 가짐:

고려사항공유 캐시서비스별 캐시
키 네임스페이스충돌 방지를 위한 프리픽스 필요자연스러운 격리
메모리효율적 활용, 잠재적 제거전용 리소스, 예측 가능
장애캐시 미스가 모든 서비스에 영향격리된 장애
무효화서비스 간 캐시 조율 용이분산 무효화 필요

When to Reconsider ​

  • 성능 병목: 데이터베이스가 특정 서비스의 제한 요소가 됨
  • 팀 확장: 독립 팀이 자율적 데이터 소유권 필요
  • 컴플라이언스 요구사항: 규정에 의해 데이터 격리 의무화
  • 기술 요구: 서비스에 특화된 데이터베이스 필요 (그래프, 시계열 등)
  • 스케일 분기: 서비스 간 극적으로 다른 스케일링 요구사항
  • 장애 격리: 영향 범위 축소가 중요한 요구사항이 됨
  • 스키마 충돌: 스키마 변경에 대한 빈번한 조율 오버헤드

Open-source test coverage insights