본 글은 educative.io 의 Grokking Modern System Design Interview 코스의 Databases 챕터 내용을 정리한 글입니다.
Introduction to Databases
Problem statement
DB 없이 소프트웨어 앱을 만들 수 있을까? 왓츠앱 같은 앱을 생각해보면 사람들은 친구들과 대화하기 위해 앱을 사용한다. 그렇다면 사람들의 이름이나 메시지같은 정보를 어디에, 어떻게 영구 저장하고, 가져올 수 있을까?
단순히 파일 하나를 사용해서 정보들을 저장할 수 있다. 하지만 이런 구현은 제약사항들이 있다.
Limitations of file storage
- 서로 다른 유저들이 동시에 파일에 접근하도록 할 수 없다
- 각 유저들에게 서로 다른 권한을 부여할 수 없다
- 확장성이 없다
- 짧은 지연시간 안에 검색 결과를 제공하기 어렵다
Solution
위의 한계점은 DB 를 사용해서 해결할 수 있다.
데이터베이스는 쉽게 관리하고 접근할 수 있는 조직된 데이터 모음이라고 할 수 있다. DB 는 서로 다른 처리를 수행하는 유저들이 쉽게 데이터를 저장, 검색, 수정, 제거할 수 있도록 한다.
뱅킹 시스템, 온라인 쇼핑몰 등의 앱에서 DB 를 사용할 수 있다. 각 조직은 요구사항에 맞는 서로 다른 DB 규모를 갖는다.
https://www.comparebusinessproducts.com
위 사이트에 의하면 World Data Center for Climate (WDCC) 가 세계 최대 규모로, 220TB 의 웹 데이터와 6PB 의 기타 데이터를 포함한다고 한다.
DB 의 두가지 기본타입은 다음과 같다
- SQL (relational databases)
- NoSQL (non-relational databases)
두 타입은 사용 방법, 저장하는 정보의 타입, 저장 방법 등에서 서로 다르다.
RDB 는 미리 정의된 스키마가 있으며, Non-RDB 는 구조화되지 않고 분산되어있으며 동적인 스키마를 제공한다.
Advantages
DB 는 모든 주요 정보를 저장하기 때문에 상황에 맞는 DB 를 선택하는건 항상 필수적이다. DB 가 중요한 이유들로는 다음과 같은 이유들이 더 있다.
- Managing large data
- 많은 양의 데이터를 쉽게 처리할 수 있다.
- Retrieving accurate data (data consistency)
- 언제든지 정확한 데이터를 가져올 수 있다.
- Easy updation
- DML (데이터 조작 언어) 를 이용하면 DB 데이터를 업데이트하기 쉽다.
- Security
- DB 는 인가된 요청만을 수용한다.
- Data integrity
- 서로 다른 제약조건을 사용함으로서 데이터 무결성을 보장할 수 있다.
- Availability
- DB 는 서로 다른 서버에 복제되고, 동시에 업데이트 될 수 있어 이런 복제본은 가용성을 높여준다.
- Scalability
- DB 는 파티셔닝에 의해 나눠져서 하나의 노드가 받는 부하를 관리할 수 있다. 이는 확장성을 준다.
Types of Databases
Relational databases
RDB 는 데이터를 저장할 때 특정한 스키마를 준수한다. RDB 에 저장된 데이터는 사전 구조를 가지며 대부분 이 모델은 고유 키를 사용해 데이터를 하나 이상의 relation (또는 테이블) 로 구성한다. 데이터의 각 엔티티는 인스턴스와 속성으로 구분되며, 인스턴스는 행으로 저장되고, 속성은 열로 저장된다. 각 튜플은 고유한 키가 있기 때문에 한 테이블의 인스턴스는 다른 테이블의 기본 키를 저장하는 방법으로 (외래키) 다른 테이블의 인스턴스와 연결될 수 있다.
SQL (Structured Query Language) 는 DB 를 조작 (삽입, 제거, 검색 등) 하는데 사용한다.
RDB 가 인기있는데에는 단순성, 견고성, 유연성, 성능, 확장성 및 일반 데이터 관리의 호환성 등 다양한 이유가 있다.
RDB 는 DB 의 무결성을 유지하기 위해 원자성, 일관성, 분리 및 내구성 (ACID) 속성을 제공한다. ACID 는 데이터와의 복잡한 상호작용을 단순하게 추상화 시켜주며, 트랜잭션 중단 이면에 숨겨진 dirty reads, dirty writes, read skew, lost updates, write skew, phantom reads 등의 많은 이상징후를 숨겨준다.
- ACID
- Atomicity
- 트랜잭션 내의 모든게 성공적으로 실행되거나 실행되지 않아야 한다. 트랜잭션 중에 실패하면 트랜잭션을 중단하고 실행 전으로 롤백되어야 한다.
- Consistency
- DB 는 항상 일관된 상태여야 하며, 모든 트랜잭션 후에도 일관된 상태를 유지해야 한다.
- Isolation
- 여러 트랜잭션이 동시에 실행되는 경우 서로 영향을 받지 않아야 한다. 최종적으로는 트랜잭션이 순차적으로 실행된 것처럼 보여야 한다
- Durability
- 완료된 트랜잭션은 장애상황에서도 영구적으로 유지될 수 있어야 한다.
- Atomicity
널리 사용되는 DBMS 에는 MySQL, OracleDB, MSSQL, Postgres, SQLite 등이 있다.
Why RDB?
RDB 는 구조화된 데이터 저장소를 위한 기본 선택 사항이다. 여러 장점이 있지만 가장 큰 장점중 하나는 ACID 트랜잭션과 프로그래밍 관련 추상화들이다. RDB 의 주요 기능들을 다시 살펴보자
- Flexibility
- SQL 의 경우 DDL 을 통해 테이블이나 컬럼 등의 스키마를 유연하게 수정할 수 있다. DDL 을 사용하면 다른 쿼리가 처리중인 상황에서도 스키마를 수정할 수도 있다.
- Reduced redundancy
- RDB 의 가장 큰 장점 중 하나는 데이터 중복을 제거한다는 것이다. 특정 엔티티와 관련된 정보는 한 테이블에 나타나고, 다른 관련없는 데이터는 외부키를 통해 연결된 다른 테이블에 표시된다. 이 과정을 정규화라고 하며, 일관성 없는 종속성을 제거하는 추가적인 장점이 있다.
- Concurrency
- 동시성은 엔터프라이즈 레벨 설계에서 중요한데, 데이터를 여러 유저가 동시에 읽고 쓸 수 있어야 한다. 데이터의 불일치를 방지하기 위해 상호작용을 조정할 필요가 있다. RDB 의 동시성은 데이터에 트랜잭션을 통한 액세스를 하는 것으로 처리된다.
- Integration
- 여러 소스의 데이터를 집계하는 것은 일반적인 사용 사례이고, 이를 수행하는 일반적인 방법은 여러 앱이 사용하는 공유 DB 를 통합하는 것이다. 이렇게 동시성 제어조치가 여러 앱의 접근을 처리하는 동안 모든 앱은 서로의 데이터에 쉽게 액세스할 수 있다.
- Backup and disaster recovery
- RDB 는 데이터 상태가 항상 일관성 있도록 보장하기 때문에 내보내기 및 가져오기 작업을 통한 백업과 복원이 쉬워진다. 대부분의 클라우드기반 RDB 는 미러링을 통해 데이터 손실을 방지하고 더 빠르고 쉬운 복구 프로세스를 제공한다.
Drawback
- Impedance mismatch
- 임피던스 불일치는 관계형 모델과 메모리내 데이터 구조의 차이이다. 관계형 모델은 데이터를 표 형식 구조로 구성하고, SQL 연산은 관계형 대수와 정렬된 관계를 얻어낸다. 그러나 이는 몇가지 제약사항을 가지고있는데, 예를들어 테이블의 값은 구조체나 배열이 될 수 없는 단순 값을 사용한다. 그러나 메모리 내의 데이터는 더 복잡한 구조를 가질 수 있다. 이렇게 복잡한 구조를 관계형 모델과 호환되게 하려면 데이터의 번역이 필요하다. 따라서 임피던스 불일치는 다음 그림과 같이 두 표현 사이의 변환을 필요로 한다.
Why non-relational (NoSQL) databases?
NoSQL DB 는 다양한 데이터 모델에 접근하고 관리하기 위해 설계되었다. 여러 종류의 NoSQL DB 가 있으며, 이러한 DB 는 대규모의 반정형 또는 비정형 데이터, 짧은 지연 및 유연한 데이터 모델을 필요로 하는 앱에서 사용될 수 있다. 이는 다른 DB 의 데이터 일관성을 일부 제한하는 방식으로 달성할 수 있다. NoSQL DB 의 특성을 몇가지 알아보자
- Simple Design
- RDB 와 달리 NoSQL 은 여러 테이블을 join 하거나 하는 대신 하나의 문서에 특정 엔티티의 모든 데이터를 저장하기 때문에 임피던스 불일치를 처리할 필요가 없다. 이 전략은 코드 작성, 디버깅, 유지보수등을 더 편하고 간단하게 해준다.
- Horizontal scaling
- NoSQL 은 보통 대규모 클러스터에서 DB 를 운영할 수 있기 때문에 선호된다. 이는 동시 사용자 수가 증가할 때의 문제를 해결하며, 특정 직원과 관련된 데이터를 하나의 문서에 저장하는 식으로 사용하기 때문에 데이터가 여러 노드에 걸쳐 저장될 필요가 없어 스케일 아웃이 더 쉬워진다. NoSQL 은 종종 여러 노드에 데이터를 분산시키고, 쿼리와 데이터의 균형을 자동으로 조정한다. 노드에 장애가 발생하면 앱 중단 없이 노드를 투명하게 교체할 수 있다.
- Availability
- 데이터 가용성을 높이기 위해 앱 다운타임 없이 노드 교체를 수행할 수 있다. 대부분의 NoSQL DB 군은 고가용성과 재해복구 보장을 위한 데이터 복제를 지원한다.
- Support for unstructured and semi-structured-data
- 대부분의 NoSQL DB 는 DB 구성시 또는 데이터 쓰기시 스키마가 없는 상태로 동작한다. 예를들어 문서 DB 는 구조가 없으며, 문서 (JSON, XML ..) 가 서로 다른 필드를 가질 수 있다.
- Cost
- 많은 RDBMS 의 라이센스는 꽤 비싼 반면, 많은 NoSQL DB 는 오픈소스이며 무료로 사용할 수 있다. 또한 일부 RDBMS 는 비싼 전용 하드웨어 및 스토리지 시스템에 의존하는 반면, NoSQL DB 는 일반적으로 저렴한 범용 서버 클러스터를 사용한다.
Types of NoSQL DB
NoSQL DB 는 문서 저장소, 컬럼 DB, Key-Value DB 및 그래프 DB 를 포함하여 다양한 범주로 나뉜다.
Key-value DB
키-값 DB 는 해시테이블처럼 key-value 쌍으로 데이터를 저장한다. 여기서 키는 고유키 또는 기본키 역할을 하며, 값은 단순 스칼라 값에서부터 복잡한 오브젝트까지 다양할 수 있다. 이러한 데이터베이스를 사용하면 데이터를 쉽게 파티셔닝하고 수평적으로 확장할 수 있다. 이런 키밸류 저장소에는 Amazon DynamoDB,Redis, Memcahed 등이 있다.
Use case: 키값 데이터베이스는 세션 지향 앱에 효율적이다. 웹앱과 같은 세션 지향 앱은 사용자 데이터를 세션동안 메인 메모리나 DB 에 저장한다. 이러한 데이터는 유저 프로필 정보, 추천, 할인 정보 등이 포함될 수 있다. 이를 쉽게 접근하거나 저장하기 위해 각 사용자 세션에 고유한 ID 를 할당할 수 있다. 이러한 경우 키밸류 DB 가 좋은 선택이 될 수 있다.
다음 그림은 키값 DB 의 예제를 나타낸 것이다. 아이템의 Product ID 와 Type 이 합쳐져서 기본 키로 간주되고, 키값 DB 에서 key 에 해당하게 된다. 아이템의 속성을 저장하기 위한 스키마는 아이템의 특성과 아이템이 가지는 속성의 갯수에 따라 정의된다.
Document database
Document DB 는 XML, JSON, BSON 등의 포맷으로 된 문서를 저장하고 검색하기 위한 목적으로 설계되었다. 이러한 문서는 맵, 컬랙션, 스칼라 값들을 포함하는 계층적 트리 데이터구조로 구성된다. 문서는 다양한 구조와 데이터를 가질 수 닜다. MongoDB 와 Google Cloud Firestore 가 이러한 documentDB 의 예다.
Use case: document DB 는 JSON 파일이나 다른 복잡한 구조적 계층 데이터와 같은 비정형 카탈로그 데이터에 적합하다. 예를들어 이커머스 앱의 경우 제품에는 수천개의 속성들이 있으며 이는 읽기 성능 때문에 RDB 에 저장하기는 부적합하다. document DB 는 각 속성을 하나의 파일에 저장하여 관리가 쉽고 읽기 속도도 더 빠르다. 또한 블로그나 비디오 플랫폼과 같은 컨텐츠 관리 앱에도 적합하다. 앱에서의 하나의 엔티티는 단일 문서에 저장된다.
아래는 JSON 문서로 저장된 데이터 예이다. 이 데이터는 한 사람에 관한것으로 id, name, email 등의 다양한 속성이 하나의 파일에 저장된다.
Graph database
graph DB 는 데이터를 저장하기 위해 그래프 데이터 구조를 사용하는데, 노드는 엔티티를, 엣지는 엔티티간의 관계를 나타낸다. 관계를 기반으로 노드를 구성하면 노드간에 흥미로운 패턴이 나타난다. 이러한 DB 는 데이터를 한번 저장하면 이것을 관계 기반으로 다르게 해석할 수 있게 해준다. 유명한 graph DB 로는 Neo4J, OrientDB, InfiniteGraph 등이 있다. 그래프 데이터는 영구 저징소에 파일로 저장된다. 각 파일은 그래프의 특정 부분 (노드, 링크, 속성 등) 에 대한 정보를 담고있다.
다음 그림은 간단한 인간관계를 데이터를 그래프로 저장한 예이다.
Use case: graph DB 는 소셜 앱에 사용될 수 있으며 서로 다른 종류의 사람들과 그들의 행동간에 재밌는 사실과 수치를 보여줄 수 있다. graph DB 는 엔티티간의 관계를 기반으로 분석하고 의사결정 할 수 있게 하는데 중점을 둔다. graph DB 의 특성은 데이터 규제, 보안, 머신러닝 연구, 금융 서비스 기반 앱 등에 적합할 수 있다.
Columnar database
컬럼기반 DB 는 데이터를 열의 형태가 아닌 행의 형태로 저장한다. 이를 통해 DB 컬럼에 있는 모든 엔트리들을 빠르고 효과적으로 접근할 수 있게 한다. 인기있는 예로는 Cassandra, HBase, Hypertable, Amazon SimpleDB 등이 있다.
Use case: 컬럼기반 DB 는 많은 수의 집계 및 데이터 분석 쿼리에 효과적이다. disk IO 요청량을 크게 줄여줄 수 있다. 예를 들어 금융기관 관련 앱에서는 일정 기간동안의 거래 데이터를 합산해야 할 수 있는데, 컬럼기반 DB 는 이 작업을 다른 속성들을 무시하고 금액에 대한 열만을 읽어오도록 해서 더 빠르게 수행할 수 있게 한다.
다음 그림은 row-oriented DB 와 column-oriented DB 가 어떻게 다른지 나타낸다.
Drawbacks of NoSQL databases
Lack of standardization
NoSQL 은 특정 표준을 따르지 않기 때문에, 하나의 NoSQL DB 에서 다른 타입으로 앱을 포팅하는 것은 어려울 수 있다.
Consistency
NoSQL DB 는 일관성과 가용성의 트레이드오프에 따라 선택할 수 있는 서로 다른 제품들이 있다. 관계형 DB 와 같은 강한 데이터 무결성은 없다. 데이터는 강력한 일관성을 갖진 못할수 있지만 궁극적인 일관성을 가질 수 있다.
Choose the right database
RDB Non-RDB
저장될 데이터가 정형화 되어있는 경우 | 저장될 데이터가 비정형인 경우 |
ACID 속성이 필요한 경우 | 데이터를 직렬화/역직렬화 할 필요가 있는 경우 |
데이터 크기가 상대적으로 작아서 하나의 노드에 들어갈 수 있는 경우 | 데이터 크기가 큰 경우 |
Note: NoSQL DB 가 처음 생겼을 때 기존 DB 와 비교해서 사용방법이 매우 달랐다. 그러나 시간이 지나면서 NoSQL 과 기존 전통적인 데이터 저장소와의 경계가 모호해지고 있다. 우리는 NoSQL 을 사용할 때 같은 SQL 쿼리로 사용할 수 있고 비슷한 성능과 일관성을 가질수도 있다. Google 의 Cloud Spanner 는 그러한 DB 중 하나로, 지리적으로 복제되며, 자동적으로 수평 확장될 수도 있고 매우 빠른 속도로 데이터 전체의 스냅샷을 생성할수 있다.
'System Design' 카테고리의 다른 글
Databases #3 - Data Partitioning (0) | 2023.06.01 |
---|---|
Databases #2 - Data Replication (0) | 2023.04.16 |
Load Balancer #3 - Advanced Details of Load Balancers (0) | 2023.03.29 |
Load Balancer #2 - Global and Local Load Balancing (0) | 2023.03.26 |
Load Balancer #1 - Introduction to Load Balancers (0) | 2023.03.26 |