1편. 데이터 집약적 애플리케이션

·4분 읽기
목차

현대의 대부분 소프트웨어는 단순한 웹 페이지를 렌더링하는 수준을 넘어서, 많은 양의 데이터를 지속적으로 저장하고, 조회하고, 전달하고, 변환해야 합니다. SNS 피드, 쇼핑몰 추천, 실시간 분석, 로그 수집, 금융 거래 시스템까지 이 모든 서비스의 근본적인 어려움은 “데이터가 어떻게 흐르고, 어떤 기술과 결합되는가”에서 발생합니다.

이번 글에서는 Designing Data-Intensive Applications 책의 1장을 정리하면서 데이터 시스템 설계에서 가장 기본이 되는 개념을 이해해보려고 합니다.


연산 중심(Compute-Intensive) vs 데이터 중심(Data-Intensive)

현대 소프트웨어 시스템은 크게 두 부류로 나눌 수 있습니다

연산 중심(Compute-Intensive)

병목이 CPU/GPU 연산량에 있는 시스템입니다.

  • 물리 계산
  • 그래픽 렌더링
  • 머신러닝 학습
  • 고성능 수치 연산(HPC)

핵심은 하드웨어 성능, 병렬 최적화, 알고리즘 개선입니다.

데이터 중심(Data-Intensive)

반대로 현대의 대부분 서비스는 CPU 연산이 아니라 데이터의 양·속도·다양성·일관성이 전체 난이도를 결정합니다.

  • SNS 피드 생성
  • 추천 시스템
  • 로그 수집 및 분석
  • 검색 인덱싱
  • 금융 트랜잭션 처리
  • 스트리밍 서비스
  • 데이터 파이프라인(ETL/ELT)

이런 시스템이 어려운 이유는 CPU가 아니라 저장소, 네트워크, 지연(latency), 데이터 품질, 복제·동기화 문제 때문이다. 다시 말해, 오늘날 대부분의 애플리케이션은 데이터 집약적(data-intensive)이라고 볼 수 있습니다.


데이터 시스템을 구성하는 주요 컴포넌트

데이터 집약적 애플리케이션은 하나의 시스템으로 해결하지 않습니다. 보통 여러 시스템이 함께 동작하며 하나의 파이프라인을 구성합니다.

1. 데이터베이스

데이터의 영속 저장소입니다. 관계형, 문서형, 키-값, 컬럼 기반 등 다양한 모델이 존재합니다. 각 모델은 일관성과 확장성, 질의 패턴에 따라 장단점이 갈립니다.

캐시

읽기 성능을 높이기 위해 메모리에 데이터를 보관합니다. 하지만 캐시 갱신 시점에 따라 일관성 문제가 발생할 수 있습니다.

  • 예) SNS에서 좋아요 수가 캐시와 DB에서 다르게 보일 수 있음

3) 검색 인덱스 (Search Index)

전문 검색을 위해 역색인 구조 등을 사용하는 별도 시스템입니다. Elasticsearch, Solr 등이 대표적이며 RDB와는 저장 방식이 완전히 다릅니다.

  • 예) 쇼핑몰에서 “청바지” 검색 시 DB 스캔이 아니라 역색인 구조로 빠르게 탐색

4) 배치 처리 시스템

대량 데이터를 모아 한 번에 처리하는 방식입니다. Hadoop, Spark 등이 대표적입니다.

  • 예) 하루치 클릭 로그를 모아 추천 모델 생성

5) 스트림 처리 시스템

데이터가 발생하는 즉시 처리합니다. Kafka Streams, Flink 등이 대표적입니다.

  • 예) 결제 이벤트를 받아 즉시 이상거래 탐지에 활용

좋은 데이터 시스템의 기준

이 책에서는 좋은 데이터 시스템이 갖춰야 할 기준을 신뢰성(Reliability) / 확장성(Scalability) / 유지보수성(Maintainability) 세 가지로 정리합니다.


신뢰성 (Reliability)

신뢰성은 단순히 “장애가 없다”는 뜻이 아니라, 장애가 발생해도 데이터 손실 없이 예상 가능한 방식으로 복구되는 것을 의미합니다.

신뢰성을 위협하는 요소

  • 하드웨어 고장 (디스크 불량, 네트워크 단절)
  • 소프트웨어 버그 (race condition, deadlock)
  • 운영자 실수 (잘못된 스키마 변경, 설정 오류)
  • 트래픽 급증 (세일 시작, 이벤트 폭주)

사례1. 결제 API 재시도 중복 처리

네트워크 문제로 결제가 여러 번 요청되더라도 시스템은 idempotency로 중복 처리를 방지해야 합니다.

사례2. 단일 노드 장애로 서비스 중단

DB 한 대 고장으로 전체 서비스가 다운되어선 안 됩니다. 복제(replication)와 자동 failover가 필수입니다.

사례3. 잘못된 데이터 입력이 전체 파이프라인을 멈출 수 있다

ETL 파이프라인에서 JSON 한 줄이 깨졌다고 배치 작업 전체가 실패하면 유지 불가능한 구조입니다.


확장성 (Scalability)

확장성은 부하 증가에 예측 가능하게 대응할 수 있는 능력입니다.

사례1. 쇼핑몰 세일 시작

00시가 되면 상품 조회·장바구니·결제가 동시에 폭주합니다. 시스템은 순간적인 스파이크를 견딜 수 있어야 합니다.

사례2. SNS 타임라인 폭증

팔로워 수백만 명을 가진 사용자가 글을 올리면 읽기 부하가 순식간에 터집니다.

확장 전략

시스템을 확장하는 방법은 아래와 같이 다양한 방법이 있습니다.

  • 수직 확장: 더 좋은 서버
  • 수평 확장: 더 많은 서버(샤딩, 파티셔닝)
  • 캐싱
  • 로드 밸런싱
  • 지리적 복제(geo-replication)

중요한 것은 단순히 확장하는 것이 아니라 확장성을 설계할 때 다양한 것을 고려해야 한다는 점입니다. 어떤 부하를 처리해야 하는지, 병목은 어디서 발생하는지, 어떤 방식으로 자원을 늘릴 것인지를 다 같이 고려해야 제대로 된 확장 전략을 짤 수 있습니다.


유지보수성 (Maintainability)

유지보수성은 시간이 지나도 시스템을 운영하고, 변경하고, 진화시키기 쉬운 구조를 말합니다.

1. 운영 가능성(Operability)

운영팀이 모니터링·로그·알람을 통해 시스템 상태를 쉽게 파악하고 대응할 수 있어야 합니다.

2. 단순함(Simplicity)

불필요한 복잡성(accidental complexity)은 곧 장애로 이어집니다.

  • 예) 중복된 ETL 파이프라인, 비관측 가능한 데이터 흐름
  • 예) 캐시 → DB → 검색 인덱스 간 업데이트 경로가 꼬여 추적 불가

3. 진화 가능성(Evolvability)

새로운 요구사항을 추가할 때 시스템 전체를 뜯어고쳐야 한다면 그 시스템은 오래 살아남기 어렵습니다.

  • 예) 컬럼 하나 추가하려고 앱 서버·배치·스트림·캐시를 모두 수정해야 한다면 그 시스템은 진화 불가능하다.

데이터 시스템은 왜 어려운가?

데이터는 단순히 한 곳에 저장되는 것이 아닙니다. 여러 시스템을 거쳐 흐르고, 복제되고, 변환되고, 소비됩니다. 시스템과 시스템이 연결되면서 복잡성이 기하급수적으로 증가합니다.

이 복잡성을 관리하기 위해서는 신뢰성, 확장성, 유지보수성이라는 세 가지 기준을 중심에 두고 설계해야 합니다.


마무리

1장은 “데이터 시스템이 왜 어려운가”라는 질문을 던지고, 그 답을 데이터 중심 구조의 복잡성과 이를 해결하기 위한 3대 원칙에서 찾습니다. 이 세 가지 원칙은 너무 당연해 보이지만, 실제로 시스템을 만들다 보면 얼마나 깊게 적용해야 하는지, 어디까지 고려해야 하는지 판단하기 어려운 경우가 많습니다. 그래서 이런 개념들을 참고해 설계 방향을 더 나은 쪽으로 잡아가는 것이 중요합니다.

다음 글에서는 2장을 정리하면서 데이터 시스템의 가장 근본적인 요소인 데이터 모델이 왜 전체 아키텍처를 규정하는지 살펴보겠습니다.

공유