데이터베이스의 기본 역할, 주요 카테고리(OLTP, OLAP), DBMS 아키텍처, 그리고 관계형 DB와 다양한 NoSQL 유형(Key-Value, Document, Column-Family, Graph), Elasticsearch, 지리정보 DB까지 살펴보았습니다.
이번 글에서는 대규모 분산 데이터 처리의 대명사인 Hadoop 에코시스템, 고가용성과 쓰기 성능에 특화된 NoSQL인 Apache Cassandra, 그리고 IoT와 모니터링 시대의 필수 요소인 시계열 데이터베이스(Time-Series DB)에 대해 깊이 있게 알아봅니다. 마지막으로, 지금까지 다룬 다양한 데이터베이스 유형들의 장단점과 트레이드오프를 성능, 확장성, 정합성, 비용, 개발 복잡도 관점에서 비교 분석하며, 어떤 상황에 어떤 DB를 선택해야 하는지에 대한 통찰을 제공하고자 합니다.
1. Hadoop 기반 분산 저장/분석 시스템: 빅데이터 처리의 시작점
Hadoop 에코시스템은 대규모 데이터의 저장 및 배치(Batch) 분석을 위해 탄생한 오픈소스 플랫폼입니다. 그 핵심에는 분산 파일 시스템인 HDFS(Hadoop Distributed File System)와 병렬 처리 프로그래밍 모델인 MapReduce가 자리 잡고 있습니다.
- 전통 RDBMS vs. Hadoop:
- RDBMS가 주로 소수의 고성능 노드에서 OLTP(온라인 트랜잭션 처리)에 사용되는 반면, Hadoop은 상대적으로 저렴한 다수의 범용 서버(Commodity Hardware)를 클러스터로 묶어 페타바이트(PB)급 이상의 거대한 데이터까지도 분산 저장하고, 이를 병렬로 효율적인 일괄 처리가 가능하도록 설계되었습니다.
- 스케일 아웃(Scale-out) 최적화: Hadoop은 노드를 추가함으로써 저장 용량과 처리 성능을 거의 선형적으로 확장할 수 있는 구조에 최적화되어 있습니다.
- 스케일 업(Scale-up)이란? 기존 서버의 CPU, RAM, SSD 등을 더 좋은 사양으로 업그레이드하는 방식 (서버 1대를 더 비싼 고성능 머신으로 교체).
- 스케일 아웃(Scale-out)이란? 서버의 대수를 늘려 시스템 전체의 처리 용량을 확장하는 방식 (예: 서버 10대를 20대로 늘려 부하 분산).
- "노드를 추가함으로써 성능과 저장 용량을 선형적으로 확장할 수 있다"는 의미는, 노드 수가 2배가 되면 성능과 저장 용량도 거의 2배가 되고, 3배가 되면 거의 3배로 비례하여 증가한다는 뜻입니다. 이는 일부 시스템에서 노드를 추가해도 성능 향상이 미미하거나 오히려 저하되는 문제없이 효율적인 확장이 가능하다는 Hadoop의 강점을 나타냅니다.
- 다양한 데이터 유형 지원: 정형 데이터뿐만 아니라 반정형 데이터(JSON, XML 등)나 비정형 데이터(텍스트 로그, 이미지, 영상 등)도 원시(raw) 형태로 자유롭게 저장할 수 있습니다. 이 때문에 데이터 레이크(Data Lake) 구축의 핵심 기술로 널리 활용됩니다.
- 데이터 레이크(Data Lake)란? 정형, 반정형, 비정형 등 모든 형태의 데이터를 원시 형태로 저장하고 필요에 따라 분석할 수 있는 대규모 중앙 저장소입니다.
◼️ MapReduce란? 대규모 데이터 병렬 처리 모델

MapReduce는 대량의 데이터를 여러 컴퓨터(노드)에서 동시에 나누어 처리하는 프로그래밍 모델이자 처리 프레임워크입니다. 이름 그대로 Map(데이터 분산 및 변환) 단계와 Reduce(결과 취합 및 집계) 단계로 구성됩니다.
- 예시: 웹사이트 로그 IP 주소별 접속 횟수 집계 (1억 건 로그 대상)
- Map 단계 (분산 처리):
- 1억 건의 로그 파일을 HDFS에서 여러 노드가 병렬로 나누어 읽습니다.
- 각 노드의 Map 함수는 로그 레코드 하나하나를 처리하여, 해당 로그의 IP 주소를 키(Key)로 하고 값(Value)을 1로 하는
<IP 주소, 1>
형태의 중간 결과물을 생성합니다.
- Shuffle & Sort 단계 (중간 과정, 프레임워크 자동 처리):
- Map 단계에서 생성된 모든
<Key, Value>
쌍들을 Key를 기준으로 정렬하고 그룹핑합니다. 동일한 IP 주소를 가진 데이터들이 같은 Reduce 태스크로 전달될 수 있도록 준비합니다.
- Reduce 단계 (결과 합치기):
- 각 Reduce 태스크는 특정 IP 주소에 대한 모든
<IP 주소, 1>
값들을 입력받습니다.
- 입력받은 값들을 모두 더하여 (1 + 1 + 1 + ...), 해당 IP 주소의 총 접속 횟수를 계산합니다.
- 최종 결과로
<IP 주소, 총 접속 횟수>
형태의 데이터를 출력합니다. (예: <192.168.1.10, 1280>
, <10.0.0.5, 325>
)
- 다양한 연산 가능: 단순 합계뿐만 아니라, 정렬, 조인(Join), 필터링 등 복잡한 데이터 분석 작업도 MapReduce 모델을 여러 단계로 조합하여 구현할 수 있습니다.
- 단점: MapReduce 작업은 기본적으로 배치 처리 방식이므로, 작업 시작부터 완료까지 상당한 시간이 소요될 수 있습니다. (높은 지연 시간, 실시간 처리에는 부적합)
◼️ Hadoop 주요 구성 요소
- HDFS (Hadoop Distributed File System):
- 파일을 블록(Block) 단위(기본 128MB 또는 256MB)로 분할하여 클러스터 내 여러 노드에 분산 저장합니다.
- 각 블록은 기본적으로 3개의 복제본(Replication)을 서로 다른 노드에 저장하여, 특정 노드에 장애가 발생하더라도 데이터 손실 없이 서비스를 지속할 수 있도록 합니다. 이는 Hadoop의 높은 가용성(High Availability)과 내결함성(Fault Tolerance)을 보장하는 핵심 기능입니다.
- MapReduce (또는 Apache Spark):
- 위에서 설명한 대규모 데이터 병렬 처리 엔진입니다.
- 최근에는 MapReduce보다 메모리 기반 처리를 통해 훨씬 빠른 성능을 제공하는 Apache Spark가 Hadoop 에코시스템의 주요 데이터 처리 엔진으로 널리 사용되고 있습니다. (Spark도 내부적으로는 Map과 Reduce와 유사한 연산 개념을 활용)
- YARN (Yet Another Resource Negotiator):
- Hadoop 클러스터의 리소스 관리 및 작업 스케줄링을 담당합니다. 여러 애플리케이션(MapReduce 잡, Spark 잡 등)이 클러스터 자원을 효율적으로 공유하고, 각 작업이 적절한 노드에 할당되어 실행되도록 제어합니다.
- 데이터 질의 레이어 (예: Hive, Pig, Presto/Trino):
- Apache Hive: SQL과 유사한 HiveQL이라는 언어를 사용하여 HDFS에 저장된 대용량 데이터를 조회하고 분석할 수 있게 해주는 데이터 웨어하우징 솔루션입니다. HiveQL 쿼리는 내부적으로 MapReduce 또는 Spark 잡으로 변환되어 실행됩니다.
- Apache Pig: 데이터 흐름(Data Flow)을 기술하는 Pig Latin이라는 스크립트 언어를 사용하여 복잡한 데이터 변환 작업을 정의하고 실행합니다.
- Presto/Trino: 분산 SQL 쿼리 엔진으로, HDFS뿐만 아니라 다양한 데이터 소스(RDBMS, NoSQL 등)에 대해 빠른 대화형(Interactive) SQL 쿼리를 실행할 수 있도록 지원합니다.
◼️ Hadoop의 장점과 단점
- 장점: 거의 무제한에 가까운 수평적 확장성, 저렴한 범용 하드웨어를 활용한 비용 효율적인 대용량 데이터 저장 및 처리, 다양한 데이터 유형(정형/반정형/비정형) 지원, 스키마 온 리드(Schema-on-Read) 방식의 유연한 데이터 처리.
- 단점: 실시간 처리의 어려움과 높은 조회 지연 시간(배치 처리 중심), 복잡한 설정 및 운영 난이도, 소규모 데이터 처리에는 오히려 비효율적일 수 있음.
Facebook, Yahoo 사례: 실제로 Facebook은 과거 Hadoop 기반으로 매일 수백 테라바이트(TB)의 사용자 로그를 처리하고 Hive를 통해 통계 분석을 수행했으며, Yahoo, Twitter 등도 방대한 이벤트 데이터를 Hadoop 클러스터에서 분석했습니다. 현대에는 클라우드 기반 데이터 레이크(예: AWS S3, Azure Data Lake Storage)와 Spark, Presto/Trino 등을 결합한 아키텍처로 많이 진화했지만, Hadoop에서 시작된 분산 처리의 기본 아이디어는 여전히 유효합니다.
인터뷰 팁: 면접에서 데이터 파이프라인이나 빅데이터 아키텍처에 대한 질문이 나온다면, Hadoop/HDFS와 같은 분산 스토리지 및 배치 처리의 기본 개념을 언급하는 것이 좋습니다. 특히 최근 트렌드인 스토리지와 컴퓨팅의 분리(예: AWS S3 + EMR/Spark)에 대해서도 이해하고 있다면 더욱 좋은 인상을 줄 수 있습니다.
2. 시계열 데이터베이스 (Time-Series DB, TSDB): 시간의 흐름을 기록하고 분석하다

시계열 데이터베이스(TSDB)는 시간에 따라 연속적으로 발생하는 데이터(예: 서버 모니터링 지표 - CPU/메모리 사용량, 주식 시장의 가격 변동, IoT 센서에서 수집되는 값, 애플리케이션 성능 메트릭 등)를 효율적으로 저장, 조회, 분석하기 위해 특별히 설계된 데이터베이스입니다.
대표적인 TSDB로는 InfluxDB, TimescaleDB, Prometheus, OpenTSDB 등이 있습니다. 이들은 공통적으로 타임스탬프(Timestamp)를 데이터의 핵심적인 기본 인덱스로 사용하며, 시간 순서대로 데이터를 빠르게 쓰고 읽을 수 있도록 최적화되어 있습니다.
◼️ 시계열 데이터의 특징과 TSDB의 필요성
- 데이터 양 방대 및 높은 삽입 빈도: 초당 수백만 건 이상의 데이터 포인트가 지속적으로 유입될 수 있습니다.
- 최근 데이터 조회 및 분석 중요: 현재 시스템 상태를 파악하거나 이상 징후를 감지하기 위해 최근 데이터에 대한 빠른 조회가 필수적입니다.
- 과거 장기 추세 분석 필요: 과거 데이터를 기반으로 패턴을 분석하고 미래를 예측하는 데 활용됩니다.
- 데이터 보존 정책 관리: 모든 데이터를 영구적으로 보존하기보다는, 오래된 데이터는 요약하거나 삭제하는 수명주기 관리가 중요합니다.
◼️ 시계열 DB의 주요 특징 및 기능
- 고속 쓰기(Ingestion) 최적화: 대량의 시계열 데이터를 지연 없이 빠르게 저장할 수 있도록 설계되었습니다. (Write-optimized)
- 압축 및 스토리지 최적화:
- 시계열 데이터는 특정 시간 범위 내에서 값의 변화 패턴이 반복되거나 유사한 경우가 많습니다. TSDB는 이러한 특성을 활용한 효율적인 압축 알고리즘(예: Gorilla, Delta-delta encoding)을 사용하여 저장 공간을 크게 절약합니다.
- 예를 들어, TimescaleDB는 시간 단위로 데이터를 파티셔닝하고 각 파티션에 대해 압축을 적용하여, 반복되는 태그(Tag) 값이나 유사한 숫자 패턴을 효과적으로 압축합니다.
- 다운샘플링(Downsampling/Rollups) 및 데이터 수명주기 관리 (Retention Policies):
- 모든 시계열 데이터를 원본 해상도 그대로 영구 보존하는 것은 비효율적입니다. TSDB는 오래된 세부 데이터를 자동으로 삭제하거나, 특정 기간이 지난 데이터를 더 낮은 해상도의 요약 통계(예: 1분 단위 데이터를 1시간 단위 평균/최대/최소값으로 집계)로 대체하는 정책(Continuous Queries, Retention Policies)을 기본적으로 지원합니다.
- 이를 통해 저장 공간을 효율적으로 관리하면서도 장기적인 추세 분석에 필요한 정보는 유지할 수 있습니다.
- 시계열 전문 질의 및 함수 지원:
- 시간 창(Time Window)별 집계, 이동 평균(Moving Average), 특정 기간별 값 비교, 미세한 시간 해상도에서의 패턴 검색 등 시계열 데이터 분석에 특화된 다양한 함수와 쿼리 기능을 제공합니다.
- 예를 들어, "최근 7일간 특정 센서 값의 변화율이 가장 컸던 TOP 5 항목 찾기"와 같은 복잡한 시계열 질의를 효율적으로 수행할 수 있습니다.
TimescaleDB vs. InfluxDB: TimescaleDB는 PostgreSQL의 확장(Extension) 형태로 개발되어, 관계형 데이터베이스의 강력한 SQL 기능과 시계열 데이터 처리 최적화를 함께 제공합니다. 반면 InfluxDB는 독자적인 스토리지 엔진과 쿼리 언어(InfluxQL, Flux)를 가지고 있으며, 모니터링 시스템(Telegraf, Kapacitor 등)과의 생태계 통합이 잘 되어 있습니다.
활용 분야: 금융(주식 시세 및 거래 내역 분석), IoT(수많은 센서에서 발생하는 스트리밍 데이터 처리), DevOps(시스템/애플리케이션 모니터링 지표 및 로그 저장/분석), 산업 자동화(스마트 팩토리 설비 데이터 실시간 모니터링) 등 다양한 분야에서 널리 사용됩니다. 특히 Prometheus + Grafana 조합의 모니터링 스택이 인기를 끌면서 TSDB는 백엔드 시스템의 필수 구성 요소로 자리 잡았습니다.
시나리오 #1: 스마트 팩토리 실시간 모니터링 시스템
- 목적: 공장 내 수천 개 센서에서 초당 수억 건씩 발생하는 실시간 데이터를 수집하고, 이를 기반으로 설비의 이상 징후를 즉시 탐지하며, 과거 데이터를 활용하여 유지보수 시점을 예측하고 운영 효율성을 분석하여 자동화합니다.
- TSDB를 사용하는 이유:
- 고속 쓰기 최적화: 대량의 실시간 센서 데이터를 빠르게 저장합니다.
- 자동 다운샘플링 및 보존 정책: 예를 들어 최근 1개월 치 데이터는 10초 단위로, 그 이전 데이터는 1분 단위로 자동 요약하여 저장 공간을 효율적으로 관리합니다.
- 시계열 전문 집계 함수: "최근 7일간 온도 변화가 가장 컸던 설비 TOP 5"와 같은 복잡한 분석 질의를 빠르게 처리합니다.
- 장기 데이터 보관 비용 절감: 효율적인 압축과 보존 정책을 통해 스토리지 비용을 최소화합니다.
인터뷰 팁: 면접에서 "1000개의 서버에서 CPU/Memory 사용량을 수집하여 모니터링 시스템을 구축해야 한다면 어떻게 설계할 것인가?"와 같은 질문을 받는다면, 일반적인 RDBMS보다는 InfluxDB나 TimescaleDB와 같은 시계열 데이터베이스를 언급하며 그 이유(대량의 시계열 데이터에 대한 빠른 집계 질의, 자동화된 데이터 보관 전략 등)를 설명하면 깊이 있는 이해를 보여줄 수 있습니다.
3. Apache Cassandra: 고가용성 및 쓰기 중심의 분산 NoSQL

데이터베이스는 백엔드 시스템 아키텍처의 핵심입니다. 그중에서도 Apache Cassandra는 가장 강력하고 확장 가능한 NoSQL 데이터베이스 중 하나로 꼽힙니다. 원래 Facebook에서 받은 편지함(Inbox) 검색 기능의 확장성 문제를 해결하기 위해 개발되었으며, 현재는 Discord, Netflix, Apple, Bloomberg 등 수많은 대규모 서비스에서 핵심 데이터 저장소로 활용되고 있습니다. 시스템 디자인 인터뷰에서도 자주 등장하는 주제이기도 합니다.
◼️ Cassandra 기본 개념
- 데이터 모델: 분산 와이드 컬럼 스토어 (Distributed Wide-Column Store)
- Keyspace: 최상위 데이터 컨테이너 (RDBMS의 데이터베이스와 유사한 개념).
- Table (Column Family): 행(Row)들을 저장하는 테이블.
- Row: 고유한 Primary Key로 식별되는 데이터 단위. 각 행은 서로 다른 컬럼들을 가질 수 있는 유연한 스키마를 지원.
- Column: 키-값(Key-Value) 쌍으로 구성되며, 각 컬럼 값에는 타임스탬프 메타데이터가 함께 저장되어 충돌 해결(Conflict Resolution)에 사용됩니다.
- Primary Key = Partition Key (+ Clustering Key(s))
- Partition Key: 데이터가 클러스터 내의 어떤 노드에 저장될지를 결정하는 해시 키.
- Clustering Key(s): 파티션 내에서 데이터가 정렬되는 순서를 결정. (선택 사항)
CREATE TABLE messages (
channel_id BIGINT,
bucket INT,
message_id BIGINT,
content TEXT,
author_id BIGINT,
PRIMARY KEY ((channel_id, bucket), message_id)
) WITH CLUSTERING ORDER BY (message_id DESC);
- 파티셔닝과 데이터 분산: Consistent Hashing
- Consistent Hashing(일관된 해싱): 대규모 분산 시스템에서 데이터를 여러 노드에 균형 있게 분산시키고, 노드의 추가/삭제 시 데이터 재분배(Rebalancing) 비용을 최소화하기 위한 핵심 해싱 전략입니다.
- 키(Key)와 노드(Node)를 동일한 해시 함수를 사용하여 원형의 해시 링(Hash Ring) 공간에 배치합니다.
- 데이터는 해시 링에서 자신의 해시 값보다 시계 방향으로 가장 가까운 노드(또는 해당 노드가 담당하는 가상 노드 - vnode)에 저장됩니다.
- 노드가 추가되거나 삭제될 때, 영향을 받는 일부 키만 이동하므로 전체 데이터를 재분배할 필요가 없습니다. 이는 Cassandra, DynamoDB, Redis Cluster 등 많은 분산 시스템에서 사용되는 중요한 개념입니다.
- Cassandra는 파티션 키를 해싱하여 특정 가상 노드(vnode)에 데이터를 할당하고, 하나의 물리적 노드가 여러 vnode를 소유하도록 하여 부하를 분산시키고 관리 효율성을 높입니다.
- 데이터 복제 (Replication):
- 고가용성(High Availability)과 내결함성(Fault Tolerance)을 보장하기 위해 데이터를 여러 노드에 자동으로 복제합니다.
Replication Factor (RF)
: 데이터 복제본 수를 지정. (일반적으로 3 사용)
NetworkTopologyStrategy
: 데이터 센터(DC) 및 랙(Rack) 정보를 인식하여, 서로 다른 DC와 랙에 복제본을 분산시켜 물리적 장애에도 데이터를 안전하게 보호합니다.
- 일관성 수준 (Consistency Level):
- Cassandra는 최종적 일관성(Eventual Consistency) 모델을 따르며, 읽기/쓰기 요청마다 애플리케이션에서 일관성 수준을 동적으로 지정할 수 있습니다. (예:
ONE
, QUORUM
, LOCAL_QUORUM
, ALL
)
- QUORUM: 전체 복제본 수의 과반수 (N/2 + 1) 노드로부터 응답을 받으면 성공으로 간주. 읽기와 쓰기 모두
QUORUM
으로 설정하면 (R + W > N 충족), 읽기 시 항상 가장 최근에 성공한 쓰기 결과를 보장받을 수 있습니다 (Strong Eventual Consistency).
- 전통적인 ACID 트랜잭션은 지원하지 않으며, 단일 행(Row) 수준의 원자성(Atomicity)만 보장합니다. (Lightweight Transactions - LWT를 통해 제한적인 조건부 업데이트 가능)
- 저장 구조: LSM-Tree (Log-Structured Merge Tree) 기반
- Cassandra는 디스크에 대한 랜덤 쓰기를 최소화하고 순차 쓰기(Sequential Write)를 최대화하여 매우 높은 쓰기 처리량을 달성하기 위해 LSM-Tree 기반의 스토리지 엔진을 사용합니다.
- 주요 구성 요소:
- Commit Log: 모든 쓰기 요청은 먼저 디스크의 Commit Log에 순차적으로 기록됩니다 (Write-Ahead Logging). 시스템 장애 시 복구에 사용됩니다.
- Memtable: 실제 데이터는 메모리 내의 정렬된 자료구조인 Memtable에 기록됩니다.
- SSTable (Sorted String Table): Memtable이 특정 크기에 도달하거나 일정 시간이 지나면, 정렬된 상태 그대로 디스크의 불변(Immutable) 파일인 SSTable로 플러시(Flush)됩니다.
- 쓰기 과정: Commit Log 기록 → Memtable에 쓰기 (매우 빠름).
- 읽기 과정: 먼저 Memtable 조회 → (없으면) Bloom Filter를 통해 해당 키가 존재할 가능성이 있는 SSTable들만 선택적으로 조회 → 여러 SSTable에서 데이터를 찾아 병합하여 반환.
- Compaction (압축): 백그라운드에서 주기적으로 여러 개의 작은 SSTable들을 병합하여 더 큰 SSTable로 만들고, 삭제 표시된 데이터(Tombstone)를 실제로 제거하여 읽기 성능을 최적화하고 디스크 공간을 확보합니다.
- Gossip 프로토콜:
- Cassandra 클러스터 내의 노드들은 중앙 제어 서버 없이 P2P(Peer-to-Peer) 방식으로 서로의 상태 정보(어떤 노드가 살아있는지, 어떤 노드가 다운되었는지, 어떤 데이터 범위를 담당하는지 등)를 주기적으로 교환합니다. 이때 사용되는 프로토콜이 Gossip 프로토콜입니다.
- 각 노드는 랜덤하게 선택된 다른 몇몇 노드와 자신이 알고 있는 클러스터 상태 정보를 주고받으며, 이 정보가 마치 소문처럼 클러스터 전체로 빠르게 전파됩니다.
- Seed 노드: 클러스터 부트스트랩 시 초기 연결 지점 역할을 하며, 새로운 노드가 클러스터에 참여할 때 다른 노드들을 발견하는 데 도움을 줍니다.
- 벡터 클럭(Vector Clock) 또는 유사 메커니즘: 상태 정보의 최신 여부를 판단하고 충돌을 방지하는 데 사용됩니다.
- Gossip 프로토콜을 통해 노드들은 동적으로 서로를 발견하고, 장애를 감지하며, 클러스터 멤버십을 유지할 수 있습니다.
◼️ Cassandra의 장애 복구 및 견고성 메커니즘
- 장애 감지: Phi Accrual Failure Detector와 같은 알고리즘을 사용하여 노드의 응답 없음을 확률적으로 판단하여 장애를 감지합니다.
- Hinted Handoff: 특정 노드가 일시적으로 다운되었을 때, 해당 노드로 가야 할 쓰기 요청을 다른 노드가 임시로 받아두었다가, 원래 노드가 복구되면 전달해주는 메커니즘입니다. (일시적인 쓰기 가용성 향상)
- Read Repair: 읽기 요청 시 여러 복제본에서 데이터를 가져와 비교하고, 만약 불일치가 발견되면 가장 최신 버전의 데이터로 다른 복제본들을 자동으로 수정(복구)하는 메커니즘입니다. (수동/백그라운드 리페어 작업도 존재)
◼️ 실제 사용 사례
- Discord 메시지 저장:
- 채널 ID와 시간 기반 버킷(예: 10일 단위)을 복합 파티션 키로 사용하여 매우 큰 채널의 메시지 데이터가 하나의 파티션에 몰리는 것을 방지하고, 메시지 ID(예: Snowflake ID)를 클러스터링 키로 사용하여 최신 메시지를 빠르게 조회하도록 데이터 모델링.
- Ticketmaster 좌석 예매 시스템:
- 이벤트 ID와 좌석 구역 ID를 복합 파티션 키로 사용하여 특정 이벤트의 특정 구역 좌석 정보를 분산 저장하고, 좌석 ID를 클러스터링 키로 사용하여 해당 구역 내 좌석들을 관리.
◼️ 언제 Cassandra를 고려해야 할까?
- 적합한 경우:
- 매우 높은 쓰기 처리량(Write Throughput)이 요구되는 시스템.
- 데이터 손실 없이 항상 서비스를 제공해야 하는 고가용성(High Availability) 및 내결함성(Fault Tolerance)이 중요한 시스템 (여러 데이터 센터에 걸친 분산 환경).
- 데이터 접근 패턴이 비교적 명확하고 예측 가능한 경우 (쿼리 기반 모델링).
- 선형적인 수평 확장이 필요한 대규모 데이터 저장소.
- 부적합한 경우:
- 강력한 ACID 트랜잭션이나 즉각적인 강한 일관성(Strong Consistency)이 필수적인 경우. (예: 금융 결제 시스템의 핵심 원장)
- 복잡한 JOIN 연산, Ad-hoc 쿼리, 집계 함수 등이 빈번하게 필요한 경우. (RDBMS나 분석용 DB가 더 적합)
- 데이터 모델링이 매우 복잡하고 관계 지향적인 경우.
인터뷰 팁: Cassandra는 쓰기 중심의 대규모 분산 환경에서 뛰어난 성능과 안정성을 제공하는 NoSQL 데이터베이스입니다. LSM-Tree, Consistent Hashing, Gossip 프로토콜, 조정 가능한 일관성 수준(Tunable Consistency) 등 핵심 개념을 정확히 이해하고, 실제 사용 사례와 데이터 모델링 방식을 함께 설명할 수 있다면 시스템 디자인 인터뷰에서 큰 강점을 보여줄 수 있습니다. FAANG(MAANG)급 회사들의 실제 사용 사례를 참고하는 것도 도움이 됩니다.
4. 각 DB 유형별 장단점 및 트레이드오프 종합 비교
지금까지 다양한 데이터베이스 유형들을 살펴보았습니다. 시스템을 설계할 때는 모든 요구사항을 단 하나의 기술로 완벽하게 충족시킬 수 없으며, 항상 특정 이점을 얻기 위해 다른 측면을 희생하는 트레이드오프(Trade-off) 관계를 이해하는 것이 중요합니다. 아래는 주요 특성별로 각 데이터베이스 유형을 비교한 내용입니다.
◼️ 성능 (Performance)
- RDBMS: 복잡한 JOIN 질의나 다중 레코드에 대한 ACID 트랜잭션 처리 성능이 우수합니다. 하지만 단일 노드의 처리량은 하드웨어 한계에 의해 제한되며, 수평 분산(샤딩) 없이는 대규모 트래픽 처리에 한계가 있을 수 있습니다.
- Key-Value 스토어 (특히 인메모리): 단순 조회/갱신 작업에 최적화되어 있으며, 메모리 내에서는 마이크로초 단위의 매우 낮은 응답 시간을 제공할 수 있습니다. 분산 환경에서는 노드 수 증가에 따라 거의 선형적인 성능 향상을 기대할 수 있습니다.
- Document/Column-Family DB: 적절한 인덱싱과 데이터 모델링을 통해 특정 패턴의 질의에 대해 매우 빠른 성능을 보일 수 있습니다. 하지만 데이터가 여러 샤드에 분산된 상황에서 교차 샤드(Cross-shard) 질의는 성능이 저하될 수 있습니다.
- Elasticsearch: 텍스트 검색, 필터링, 집계 쿼리 성능이 매우 뛰어납니다. 그러나 즉각적인 최신 데이터 조회가 중요한 OLTP성 워크로드에는 부적합합니다.
- 시계열 DB (TSDB): 대량의 시계열 데이터 쓰기(Ingestion) 성능이 극대화되어 있으며, 최근 데이터 범위에 대한 조회 및 집계 연산이 메모리 캐싱 등을 통해 빠르게 처리됩니다.
- Hadoop (MapReduce/Spark): 대규모 데이터셋에 대한 배치(Batch) 처리 성능은 매우 높지만 (마치 큰 망치로 한 번에 큰 못을 박는 것과 유사), 개별 레코드에 대한 단건 조회 성능은 매우 낮아 실시간 질의에는 사용되지 않습니다.
◼️ 확장성 (Scalability)
- RDBMS: 전통적으로 수직적 확장(Scale-up: 고성능 서버로 업그레이드)에 의존하며, 일정 수준 이상으로 확장하기 어렵습니다. 수평적 확장(Scale-out: 서버 대수 증가)을 위해서는 샤딩(Sharding), 데이터베이스 복제(Replication) 등 복잡한 아키텍처 설계와 애플리케이션 레벨에서의 추가적인 고려가 필요합니다. (최근에는 분산 SQL DB도 등장하고 있지만, 전통적인 RDBMS와는 다소 다릅니다.)
- NoSQL DB (대부분): 설계 단계부터 수평적 확장(Scale-out)을 염두에 두고 개발되어, 다수의 범용 서버 노드에 데이터를 분산함으로써 저장 용량과 처리량을 거의 제한 없이 늘릴 수 있습니다. Cassandra, MongoDB, DynamoDB 등은 몇 개의 노드에서 수백, 수천 개의 노드까지 선형적으로 확장이 가능하도록 설계되었습니다.
- Elasticsearch: 샤드(Shard) 수를 늘리고 데이터 노드를 추가함으로써 페타바이트(PB)급의 로그 데이터도 효과적으로 분산 저장하고 검색할 수 있습니다.
- 그래프 DB: 데이터 간의 관계가 매우 촘촘하게 얽혀있을 경우 샤딩이 어려워 수평적 확장성이 다른 NoSQL 유형보다 떨어질 수 있습니다. (최근에는 네이티브 멀티서버 그래프 DB도 발전 중)
- Hadoop (HDFS): 설계상 수천, 수만 개의 노드까지 확장 가능하며, 페타바이트(PB)를 넘어 엑사바이트(EB) 규모의 데이터까지 저장하고 처리하는 데 사용됩니다.
◼️ 정합성 (Consistency)
- RDBMS: ACID 트랜잭션을 엄격하게 준수하여 강한 일관성(Strong Consistency)을 기본적으로 제공합니다. 트랜잭션 내의 모든 데이터 변경은 원자적으로 처리되며, 커밋된 결과는 즉시 모든 후속 읽기 작업에서 일관되게 조회됩니다.
- NoSQL DB (대부분 분산 환경): CAP 이론(Consistency, Availability, Partition Tolerance)에 따라, 네트워크 분할(Partition Tolerance) 상황에서 일관성(Consistency)과 가용성(Availability) 중 하나를 우선시하는 경향이 있습니다.
- AP 지향 시스템 (예: Cassandra, DynamoDB): 네트워크 분할이나 일부 노드 장애 발생 시에도 쓰기/읽기 가용성을 최대한 유지하는 대신, 일시적으로 복제본 간 데이터 불일치가 발생할 수 있음을 허용합니다. 이를 최종적 일관성(Eventual Consistency)이라고 하며, 시간이 지나면 시스템이 자동으로 불일치를 해소(Reconcile)하여 모든 복제본이 동일한 상태로 수렴합니다.
- CP 지향 시스템 (예: MongoDB - Primary/Secondary 구성, HBase): 데이터 정합성을 가용성보다 우선시하여, 네트워크 분할이나 Primary 노드 장애 시 일시적으로 쓰기 작업이 불가능해질 수 있습니다. (하지만 RDBMS만큼의 강한 일관성을 모든 상황에서 보장하는 것은 아닐 수 있음)
- NewSQL DB (예: Google Spanner, CockroachDB): RDBMS의 강한 일관성과 NoSQL의 확장성을 동시에 제공하려는 시도이지만, 내부 구현이 매우 복잡합니다.
- 결론: 정합성 측면에서는 RDBMS가 가장 높은 수준의 즉각적이고 철저한 무결성을 제공하며, 대부분의 NoSQL은 최종적 일관성 모델을 따르거나 조정 가능한 일관성 수준을 제공합니다. 애플리케이션의 요구사항(예: 금융 거래 vs. 소셜 미디어 피드)에 따라 적절한 일관성 모델을 선택하는 것이 매우 중요합니다.
◼️ 비용 (Cost)
- 라이선스 비용: 상용 RDBMS(예: Oracle, MS SQL Server)는 라이선스 비용이 매우 높을 수 있습니다. 오픈소스 RDBMS(MySQL, PostgreSQL)나 대부분의 NoSQL DB, Hadoop 에코시스템은 라이선스 비용이 없습니다.
- 하드웨어 비용: RDBMS는 고성능 단일 서버(Scale-up)에 의존하는 경우가 많아 초기 하드웨어 투자 비용이 클 수 있습니다. 반면, NoSQL이나 Hadoop은 상대적으로 저렴한 범용 서버 여러 대(Scale-out)를 사용하는 구조이므로 초기 하드웨어 비용을 낮출 수 있습니다.
- 운영 비용 (인건비, 관리 복잡성): 분산 시스템(대부분의 NoSQL, Hadoop)을 직접 구축하고 운영하려면 높은 수준의 전문성과 운영 인력이 필요하며, 이는 인건비 상승으로 이어질 수 있습니다.
- 클라우드 관리형 서비스 비용: AWS (Aurora, DynamoDB, Redshift, EMR), GCP (Cloud SQL, Bigtable, BigQuery, Dataproc), Azure (Azure SQL Database, Cosmos DB, Synapse Analytics, HDInsight) 등 클라우드 제공업체의 관리형 데이터베이스 서비스를 사용하면 인프라 관리 부담을 크게 줄일 수 있지만, 사용량에 따른 서비스 비용이 발생하며 벤더 종속성이 생길 수 있습니다.
- 개발 비용 (복잡도): NoSQL 사용 시 애플리케이션 레벨에서 데이터 일관성 유지, 중복 데이터 관리, 충돌 해결 로직 등을 직접 구현해야 하는 경우가 있으며, 이 또한 개발 비용으로 간주될 수 있습니다.
◼️ 개발 복잡도 (Development Complexity)
- RDBMS + SQL: 수십 년간 검증된 표준 기술로, 대부분의 개발자에게 친숙하며 관련 자료와 튜닝 노하우가 풍부합니다. 요구사항에 부합하고 성능상 문제가 없다면 RDBMS를 우선적으로 고려하는 것이 개발 생산성을 높이는 방법일 수 있습니다.
- NoSQL: 각 유형별로 고유한 데이터 모델, API, 질의 언어(필요시)를 가지고 있어 학습 곡선이 존재할 수 있습니다. 데이터 모델링 방식도 전통적인 정규화 기반의 테이블 설계와는 다른 접근 방식(예: 비정규화, 쿼리 기반 모델링)이 필요할 수 있습니다. 분산 환경에서 발생할 수 있는 문제(네트워크 지연, 노드 간 데이터 불일치 등)는 디버깅이 어려워 개발 난이도를 높일 수 있습니다.
- 특정 문제에 대한 적합성: 반대로, 특정 문제(예: JSON API 개발, 로그 데이터 분석)에 대해서는 NoSQL이 훨씬 자연스럽고 간결한 해결책을 제공하여 개발 생산성을 높일 수도 있습니다. (예: JSON 데이터를 그대로 MongoDB에 저장, ELK 스택을 활용한 로그 분석 시스템 빠른 구축)
- Hadoop/Spark: SQL에 익숙한 개발자에게는 초기 진입 장벽이 있을 수 있지만, 데이터 과학자나 분석가에게는 대용량 데이터 처리를 위한 강력하고 유연한 도구를 제공합니다.
인터뷰 팁: 시스템 디자인 인터뷰에서 데이터베이스 선택에 대해 논의할 때는, 위에서 언급된 다양한 트레이드오프를 고려하고, "애플리케이션의 구체적인 요구사항(읽기/쓰기 패턴, 데이터 규모, 일관성 수준, 예산, 팀의 기술 역량 등)을 바탕으로 최적의 솔루션을 선택해야 한다"는 점을 강조하는 것이 좋습니다. "정답은 없으며, 상황에 따라 가장 합리적인 절충안을 찾는 것이 중요하다"는 성숙한 시각을 보여주는 것이 중요합니다.
이것으로 데이터베이스 완전 정복 시리즈를 마무리합니다. 이 글들이 여러분의 데이터베이스에 대한 이해를 한층 높이고, 더 나은 시스템을 설계하는 데 도움이 되었기를 바랍니다!