확장 가능한 웰니스 데이터: CQRS 패턴을 사용해 더 빠른 건강 대시보드 구축

발행: (2025년 12월 26일 오후 01:40 GMT+9)
6 min read
원문: Dev.to

Source: Dev.to

헬스와 웰니스 애플리케이션 세계에서 데이터가 왕이다. 사용자는 끊임없이 운동, 식사, 수면을 기록하지만, 동시에 시간에 따라 진행 상황을 보여주는 아름답고 거의 즉시 표시되는 대시보드를 기대한다.

이 두 가지 요구—빈번한 쓰기복잡한 분석 읽기—를 관리하면 전통적인 데이터베이스에서 성능 병목 현상이 발생하기 쉽다. 이 아키텍처는 앱이 확장될수록 반응성을 유지하기 위해 보다 전문화된 접근 방식이 필요함을 시사한다.

이러한 시스템 구축에 대한 심층적인 안내를 원한다면, 우리의 understanding your results 가이드에서 기술적인 walkthrough를 확인할 수 있다.

문제점: 하나의 데이터베이스만으로는 부족할 때

일반적인 웰니스 앱은 두 가지 매우 다른 유형의 트래픽을 처리한다. 첫 번째는 10 km 달리기와 같은 간단한 쓰기이며, 두 번째는 지난 1년 동안 요일별로 사용자의 평균 달리기 페이스를 계산하는 읽기이다.

하나의 데이터베이스가 두 역할을 모두 수행하려 하면 결국 한계에 부딪힌다. 빠른 데이터 입력에 최적화된(정규화된) 모델은 조인과 집계가 필요한 복잡한 분석에 비효율적이다.

사용자 기반이 성장함에 따라 이러한 고강도 분석 쿼리는 애플리케이션을 정지시킬 수 있다. 그래서 많은 엔지니어가 Command Query Responsibility Segregation (CQRS) 패턴을 선택한다.

해결책: 책임 분리

CQRS는 쓰기읽기 데이터를 위한 모델을 분리하는 아키텍처 패턴이다. 모든 요청을 하나의 모델이 처리하는 대신, 시스템을 두 개의 뚜렷한 측면으로 나눈다:

  • 명령 측면 – 쓰기, 업데이트, 삭제와 같은 상태 변화를 처리한다.
  • 조회 측면 – 데이터를 검색하고 표시하는 데만 최적화된다.

로그 기록에는 PostgreSQL과 같은 트랜잭션 데이터베이스를, 분석에는 ClickHouse와 같은 컬럼형 데이터베이스를 사용하면 빠른 로깅과 번개 같은 대시보드를 동시에 보장할 수 있다.

명령 vs. 조회: 간단 비교

FeatureCommand Side (Write)Query Side (Read)
Primary Goal데이터 무결성 및 일관성속도 및 분석 성능
Database ExamplePostgreSQLClickHouse
Data Structure정규화(깨끗한 테이블)비정규화(평탄하고 빠른 테이블)
Optimized ForLogWorkout, AddMealMonthlyTrends, YearlyAverages

Kafka로 시스템 연결하기

두 측면을 동기화하기 위해 Kafka와 같은 이벤트 버스를 사용한다. 사용자가 운동을 기록하면 해당 레코드가 PostgreSQL에 저장되고, 즉시 Kafka에 이벤트가 발행된다.

조회 측면은 이러한 이벤트를 수신하고 자체 테이블을 업데이트한다. 이 아키텍처는 **궁극적 일관성(eventual consistency)**과 연관되며, 기록된 운동이 대시보드에 표시되기까지 서브‑초 정도의 지연이 있을 수 있다.

이 작은 트레이드‑오프 덕분에 시스템 각 부분을 독립적으로 확장할 수 있어, 사용자가 통계를 확인하기 위해 급증해도 건강 데이터 기록을 담당하는 부분이 붕괴되지 않는다.

분석 확장을 위한 핵심 포인트

  • 전문화가 승리 – 트랜잭션 무결성에는 PostgreSQL, 고속 데이터 처리에는 ClickHouse를 사용한다.
  • 이벤트로 디커플링 – Kafka를 사용해 쓰기 모델과 읽기 모델 사이의 간극을 메우면서 사용자 경험을 저하시키지 않는다.
  • 사용자 중심 최적화 – 읽기 측면에서 데이터를 비정규화하면 복잡한 집계가 몇 분이 아니라 몇 밀리초 안에 실행된다.

Node.js와 Docker를 사용해 이 스택을 구현하는 전체 단계별 튜토리얼WellAlly’s full guide를 확인하라.

Back to Blog

관련 글

더 보기 »