NoSQL

2024. 2. 15. 15:31

NoSQL(Not Only SQL)은 관계형 데이터베이스 모델을 사용하지 않는 데이터베이스 시스템을 가리킨다.

대량의 비정형 데이터를 처리하고 확장성과 성능을 향상시킬 수 있는 유연한 데이터 모델을 제공한다.

1. 개요

- NoSQL은 스키마가 없거나 유연한 스키마를 가지며, 데이터 모델은 키-값, 문서, 열, 그래프 등 다양한 형태를 가질 수 있다.

- 수평적으로 확장 가능하며, 대량의 데이터 처리에 특화되어 있다.

- 고 가용성, 분산 처리, 자동 복구 등을 지원하여 데이터베이스 시스템의 신뢰성을 향상시킨다.

- 일반적으로 RDBMS에 비해 쓰기와 읽기 성능이 월등히 빠르다.

- 일반적으로 관계형 데베는 저장된 데이터의 양이 많아질수록 읽기/쓰기 성능의 저하가 일어난다. 특히 쓰기 성능의 저하가 심한데, 이는 대부분의 관계형 데베가 채택하고 있는 인덱스 처리 방법인 B-tree의 한계에서 기인한다.

- NoSQL을 선택하는 이유는 하드웨어 추가에 따른 성능의 선형 증가를 얻을 수 있다는 장점 때문이다. 또한 다양한 NoSQL이 존재하므로 선택이 폭이 넓다는 것도 장점.

 

*스키마란?

=> 데이터베이스에서 데이터의 구조, 제약 조건, 관계 등을 정의하는데 사용되는 개념. 데이터의 구조를 정의함으로써 데이터베이스에서 사용되는 테이블, 컬럼, 관계 등을 명확하게 표현할 수 있다.

=> 데이터베이스의 논리적인 구조를 설명하며, 데이터베이스에서 사용되는 테이블, 컬럼, 인덱스, 제약 조건 등을 정의한다. 스키마는 데이터베이스의 구조를 나타내는 도면이라고 생각할 수 있다.

 

2. NoSQL 데이터 모델

- 키-값(Key-Value) 모델 : 간단한 키와 해당 키에 대응하는 값으로 데이터를 저장한다. Redis, Amazon DynamicDB 등이 대표적인 예이다.

     - ex) 사용자 세션 관리 시스템 : 세션 ID가 키, 해당 세션에 대한 정보가 값.

- 문서(Document) 모델 : JSON이나 XML과 같은 문서 형태로 데이터를 저장하며, 유연한 스키마를 제공한다. MongoDB, Couchbase 등이 대표적인 예이다.

     - ex) 블로그 게시물 저장 : 각 게시물은 문서로 표현되고, 제목, 내용, 작성자, 작성일 등의 필드를 포함할 수 있다.

- 열(Column) 모델 : 키-값 쌍을 열의 집합으로 구성된 테이블 형태로 저장한다. Cassandra, HBase 등이 대표적인 예이다.

     - ex) 웹 애플리케이션에서 사용자 프로필 저장하는 경우, 각 패밀리는 사용자 ID를 행으로 가지고, 이름, 나이, 이메일 등의 열로 구성될 수 있다.

- 그래프(Graph) 모델 : 노드와 간선으로 데이터를 표현하며, 복잡한 관계를 효율적으로 처리할 수 있다. Neo4j, Amazon Neptune 등이 대표적인 예이다.

     - ex) 소셜 네트워크에서는 사용자를 노드로 표현하고, 친구 관계를 간선으로 표현할 수 있다. 이를 통해 친구 추천, 네트워크 분석 등 다양한 작업을 수행할 수 있다.

 

 

3. 장점

- 유연한 데이터 모델 : 스키마의 제약이 적어 다양한 형태의 데이터를 저장할 수 있다.

- 확장성 : 수평적인 확장이 가능하여 대규모 데이터 처리에 용이하다.

- 높은 가용성 : 분산 아키텍처와 자동 복구 기능을 통해 시스템의 가용성을 높일 수 있다.

- 빠른 속도 : 데이터 모델의 단순성과 분산 처리를 통해 빠른 읽기/쓰기 속도를 제공한다.

 

4. 한계

- 유연성 대비 복잡성 : 스키마가 없거나 유연한 스키마를 가지므로 데이터 일관성을 유지하기 위한 추가 작업이 필요할 수 있다.

- 쿼리의 제한 : SQL과 달리 NoSQL은 각각의 데이터 모델에 특화된 쿼리 언어를 사용하므로, 다양한 쿼리 작성에 제약이 있을 수 있다.

- 트랜잭션의 제한 : 일부 NoSQL 데이터베이스는 ACID 트랜잭션을 제공하지 않거나, 제한적인 TX모델을 가질 수 있다.

 

 

 

Redis

- 메모리 기반의 데이터 구조 저장소. 메모리에 데이터를 저장하므로 매우 빠른 데이터 액세스 속도를 제공하며, 주로 캐싱, 세션 관리, 메시지 브로커 등 다양한 용도로 사용된다.

- 키 - 값 구조로 데이터를 저장하며, 다양한 데이터 구조를 지원한다.

1. In-Memory 데이터 저장

2. 다양한 데이터 구조 : Redis는 단순한 키-값 저장소 뿐만 아니라 문자열, 리스트, 해시, 집합, 정렬된 집합 등 다양한 데이터 구조를 지원한다. 이를 통해 복잡한 데이터 조작이 가능하며, 데이터의 구조와 관계를 유지할 수 있다.

3. 영속성 지원 : Redis는 디스크에 데이터를 저장하고 복원할 수 있는 기능을 제공한다. 이를 통해 메모리의 데이터를 영속적으로 보존하고, 시스템 재부팅 등의 상황에서도 데이터를 안전하게 유지할 수 있다.

4. 분산 시스템 지원 : Redis는 마스터-슬레이브 구조를 통해 데이터를 복제하고, 클러스터링을 통해 데이터의 가용성과 확장성을 제공할 수 있다. 이를 통해고가용성과 성능을 향상시킬 수 있다.

5. 다양한 언어로 개발된 클라이언트 라이브러리를 제공, 다양한 어플리케이션과의 통합이 쉽다.

 

참조 : https://12bme.tistory.com/615   <- 다시 읽기

 

 

 

RDBMS vs NoSQL

1. RDBMS

장점

 - 정해진 스키마에 따라 데이터를 저장하여야 하므로 명확한 데이터 구조를 보장한다.

 - 또한 각 데이터를 중복없이 한 번만 저장할 수 있다.

단점

 - 테이블간 관계를 맺고 있어 시스템이 커질 경우 JOIN문이 많은 복잡한 쿼리가 만들어질 수 있다.

 - 성능 향상을 위해서는 Scale-up만을 지원한다. 이로 인해 비용이 기하급수적으로 늘어날 수 있다.

 - 스키마로 인해 데이터가 유연하지 못하다. 나중에 스키마가 변경될 경우 번거롭고 어렵다.

 

2. NoSQL

장점

 - 스키마가 없기 때문에 유연하며 자유로운 데이터 구조를 가질 수 있다.

 - 언제든 저장된 데이터를 조정하고 새로운 필드를 추가할 수 있다.

 - 데이터 분산이 용이하며 성능 향상을 위한 Scale-up 뿐만 아니라 Scale-out또한 가능하다.

단점

 - 데이터 중복이 발생할 수 있으며 중복된 데이터가 변경될 경우 수정을 모든 컬렉션에서 수행해야 한다.

 - 스키마가 존재하지 않기에 명확한 데이터 구조를 보장하지 않으며 데이터 구조를 결정하기 어려울 수 있다.

 

=> RDBMS는 데이터 구조가 명확하며 변경 될 여지가 없으며 명확한 스키마가 중요한 경우. 또한 중복된 데이터가 없어(데이터 무결성) 변경이 용이하기 때문에 관계를 맺고 있는 데이터가 자주 변경이 이루어지는 시스템에 적합하다.

NoSQL은 정확한 데이터 구조를 알 수 없고 데이터가 변경/확장이 될 수 있는 경우에 사용하는 것이 좋다. 하지만 데이터 중복이 발생할 수 있으며 중복된 데이터가 변경될 시에는 모든 컬렉션에서 수정을 해야 하기 때문에 Update가 많이 이루어지지않는 시스템이 좋다. 또는 scale-out이 가능하다는 장점을 활용해 막대한 데이터를 저장해야 되는 시스템에 적합하다.

 

*NoSQL이 Scale-out을 어떻게 할 수 있는지?

 

RDB와 비교하여 NOSQL의 특징은 ACID, Transaction을 지원하지 않는다는 것이다. RDB는 ACID와 tx를 보장하기 위해 수평적 확장이 쉽지 않다. 또한 RDB 같은 경우에는 multiple server로 수평적 확장을 하게 되면 join을 하기가 굉장히 복잡해진다. RDB도 수평적 확장이 가능하지만 NOSQL에 비해 훨씬 복잡하다. RDB를 수평확장하려면 샤딩(데이터가 수평적으로 분할되고 기기의 모음 전반에 걸쳐 분산되는 경우)가 필요하다. ACID 준수를 유지하면서 RDB를 샤딩하는 것은 매우 까다로운 작업이다.

 

- NOSQL는 분산 환경에서의 확장성과 유연성을 강조하기 위해 ACID와 TX의 일관성을 포기하는 경우가 있다.

- RDB에서 수평적 확장은 여러 서버에 데이터를 분산하고 저장하고 처리하는 것을 의미.

- 그러나 수평적 확장을 위해 데이터를 분산하는 샤딩 작업이 필요하므로 수직적 확장보다 더 복잡하다.

 - RDB에서 여러 서버로 수평적 확장하면 JOIN이 복잡해진다. 수평적으로 분할된 데이터는 여러 서버에 저장되어 있으므로, 조인 작업은 분산된 데이터를 수집하고 연결해야 하기 때문에 복잡성이 증가한다.

 - RDB에서 수평적 확장을 위해 샤딩을 사용한다. 샤딩은 데이터를 수평적으로 분할하여 여러 서버에 분산 저장하는 것을 의미한다. 그러나 샤딩은 ACID 준수를 유지하면서 수평적으로 분할된 데이터를 관리하는 것이 매우 까다로운 작업이다. 데이터의 일관성과 조인 작업에 대한 복잡성 등 다양한 고려 사항이 있기 때문이다.

 

ACID란 ?

= 데이터베이스 트랜잭션의 속성 네 가지. 데베에서 데이터 일관성과 안전성을 보장하기 위해 사용되는 기본적인 원칙

1. 원자성(Atomicity)

 - 트랜잭션은 작업의 최소 단위인 원자적인 단위로 간주된다.

 - 트랜잭션 내의 모든 작업은 전부 수행되거나, 전혀 수행되지 않아야 한다.

 - 트랜잭션 중간에 장애가 발생하더라도, 트랜잭션은 롤백되어 이전 상태로 복원된다.

 

2. 일관성(Consistency)

 - tx은 데베의 일관된 상태를 유지해야 한다.

 - tx이 수행되기 전과 후에 데베의 무결성 제약 조건이 항상 만족되어야 한다.

 - 예를 들어 계좌 이체 tx에서는 송금과 수취 계좌의 잔액 합이 변하지 않아야 일관성이 유지된다.

 

* 무결성 제약조건

 - 무결성 : 데이터의 정확성, 일관성. 즉 데이터에 결함이 없는 상태, 데이터를 정확하고 일관되게 유지하는 것을 의미한다.

- 무결정 제약 조건이란 데베의 정확성, 일관성을 보장하기 위해 저장, 삭제, 수정 등을 제약하기 위한 조건

주요 목적은 데베에 저장된 데이터의 무결성을 보장하고 데베의 상태를 일관되게 유지하는 것이다.

1) 개체 무결성 : 각 기본키를 구성하는 속성은 null값이나 중복된 값을 가질 수 없다.

2) 참조 무결성 : 외래키 값은 null이거나 참조하는 릴레이션의 기본키 값과 동일해야 한다.

즉, 각 릴레이션은 참조할 수 없는 외래키 값을 가질 수 없다. 외래키가 참조하는 기본키 값이 존재해야 한다.

3) 도메인 무결성 : 속성들의 값은 정의된 도메인에 속한 값이어야 한다.

4) 키 무결성 : 테이블의 기본 키나 대체 키가 null이 아니어야 함을 보장한다.

 

3. 고립성(Isolation)

 - 동시에 실행되는 여러 tx들이 서로 영향을 주지 않고 독립적으로 실행된 것처럼 보여야 한다.

 - 한 tx가 다른 tx의 중간 상태를 볼 수 없어야 하며, 중간 상태의 데이터를 변경하거나 참조할 수 없어야 한다.

 

4. 지속성(Durability)

 - tx이 성공적으로 완료되면, 그 결과는 영구적으로 저장되어야 한다.

 - 시스템 장애나 전원 손실과 같은 예기치 않은 상황이 발생하더라도, tx이 영구적으로 반영되어야 한다.

 

ACID 속성은 데베의 신뢰성과 안정성을 보장하기 위해 사용된다. 이러한 속성을 통해 데이터의 무결성을 유지하고, 동시성 문제를 해결하며, 장애 상황에서도 데이터의 안전성을 보장할 수 있다.

 

nosql 데이터베이스의 분산 아키텍쳐와 관련이 있다.

1. 샤딩(Sharding) : 샤딩은 데이터를 여러 개의 노드로 분할하는 것을 의미한다. 각 노드는 데이터의 부분 집합을 관리하며, 전체 데이터베이스가 여러 노드에 분산되어 저장된다. 이렇게하면 데이터베이스의 용량과 처리 능력을 확장할 수 있다. 각 노드는 독립적으로 작동하므로 읽기 및 쓰기 작업을 병렬로 처리할 수 있다.

2. 레플리케이션(Replication) : 레플리케이션은 데이터를 여러 노드에 복제하는 것을 의미한다. 이를 통해 데이터베이스의 가용성과 내결함성을 향상시킬 수 있다. 레플리케이션은 주로 데이터의 읽기 작업을 분산시키고, 쓰기 작업에는 일부 동기화를 필요로 한다. 레플리케이션은 데이터를 여러 지리적 위치에 복제하여 지리적으로 분산된 사용자에게 더 가까운 데이터 접근을 가능하게 한다.

3. 자동 분할 및 재배치 : NOSQL은 데이터의 분산을 자동으로 처리하고, 노드 간에 데이터를 재배치하여 부하를 균형화한다. 이를 통해 데베의 크기와 처리량을 유연하게 조정할 수 있으며, 새로운 노드를 추가하거나 기존 노드를 제거하는 등의 작업을 간편하게 수행할 수 있다.

4. CAP 이론 : NOSQL 데베는 CAP 이론에 따라 일관성(Consistency), 가용성(Availability), 분할 내성(Partition tolerance) 중에서 두 가지를 선택한다. 주로 분할 내성과 가용성을 선택하여 확장성과 성능을 강조한다. 이를 통해 데이터의 일관성을 약간 희생하고, 대신 가용성과 분할 내성을 보장한다.

 

* 클러스터링 vs 샤딩 vs 레플리케이션

모두 nosql 데이터베이스에서 사용되는 데이터 분산 방법이다. 목적과 작동 방식에서 차이가 있다.

 

 

클러스터링 : 동일한 DB 서버를 두 대를 두고 두 서버를 Active-Active 상태로 운영하면, 하나의 DB가 죽더라도 나머지 DB가 살아있기 때문에 정상적으로 서비스가 가능해진다. 또한 이전에는 하나의 서버가 부담하던 부하를 두 개의 DB가 나눠서 감당하므로 CPU, MEMORY 자원의 부하도 적어지게 된다.

단점은 DB 스토리지를 두 DB 서버가 공유하기 때문에 병목이 생길 수 있다는 점과 이전보다 많은 비용이 투자되어야 한다는 점이 있다.

 

두 DB 서버 중 한 대를 STAND-BY로 두는 것. FAIL OVER을 통해 두 서버가 상태를 상호 전환함으로써 장애를 대응할 수 있다. 

단점은 FAIL OVER가 이뤄지는 수초~수분 간의 시간 동안에는 영업 손실이 필연적으로 발생하게 된다는 점. 결과적으로 DB 서버 두 대를 구비해야 하기 때문에 비용은 전과 동일하지만 효율은 이전보다 1/2정도 안나온다는 점.

 

레플리케이션 사용자는 마스터 DB서버에 DML(SELECT/INSERT/UPDATE/DELETE)작업을 하면 MasterDB는 그 데이터를 Slave 쪽에 데이터 복제를 한다.

이를 통해 DB 스토리지가 한 대여서 발생할 수 있는 데이터 손실을 방지할 수 있다.

단점은 Slave DB 서버가 놀게 된다는 점.

그래서 Master DB에는 INSERT.UPDATE.DELETE 작업을 하고 Slave DB 서버에 SELECT를 함으로써 양 서버에 부하를 분산할 수 있다.

다만 만약 테이블에 데이터 자체가 엄청나게 많다면 Slave DB 서버를 N대로 늘려도 원하는 데이터를 찾는데 많은 시간이 소요될 것이다.

 

그때 활용이 가능한 것이 샤딩(Sharding)이다.

샤딩은 테이블을 특정 기준으로 나눠서 저장 및 검색하는 것을 말한다.

샤딩의 핵심은 데이터를 어떻게 잘 분산시켜 저장할 것인지, 그리고 어떻게 잘 읽을 것인지에 대한 결정이다.

어떻게 잘 분산시켜 저장할지에 기준이 되는 것이 Shard Key이다.

크게 3가지가 있다.

1. Hash Sharding

샤드의 수만큼 Hash 함수를 사용해서 나온 결과에 따라 DB 서버에 저장하는 방식으로 구현이 간단하다는 것이 장점이다.

단점은 확장성이 낮다는 것이다. DB 서버가 추가 될 경우 해쉬 함수가 변경되어야 하므로 기존에 저장되던 데이터의 정합성이 깨지게 된다.

 

2. Dynamic Sharding

 

로케이터 서비스는 테이블 형식의 데이터를 바탕으로 샤드를 결정해서 적절히 저장하는 방식을 말한다. 해시 샤딩과 달리 단순히 키만 추가해주면 되므로 확장 또한 쉽다.

단점으로는 로케이터 서비스가 단일 장애점이 되므로, 로케이터 서비스에 장애가 발생하면 나머지 샤드 또한 문제가 발생한다.

 

3. Entity Group

 

앞서 두 방식은 nosql에 최적화 되어 있는 반면, 이 방식은 RDM와 잘 어울리는 방식이다.

엔티티 그룹은 연관성이 있는 엔티티를 한 샤드에 두는 방식이다. 같은 샤드에 있는 데이터를 조회할 때는 효과적이지만, 다른 샤드에 있는 데이터를 함께 조회할 때는 오히려 성능이 떨어지는 단점이 있다.

 

 

1. 샤딩 

 - 데이터를 여러 개의 노드로 분할하여 데베의 용량과 처리 능력을 확장하는 것이 주요 목적이다.

 - 데이터를 특정 기준(일반적으로 키나 해시 함수)에 따라 여러 파티션 또는 샤드로 분할한다. 각 샤드는 독립적으로 작동하며 데이터의 일부를 저장하고 처리한다. 이로 인해 읽기 및 쓰기 작업이 병렬로 처리되어 처리량이 증가하고 데베의 확장성이 향상된다.

2. 레플리케이션

 - 데이터의 가용성과 내결함성을 향상시키는 것이 주요 목적이다.

 - 데이터를 여러 개의 노드에 복제한다.각 복제본은 원본 데이터의 신뢰성을 보장하고 읽기 작업을 분산시킨다. 일반적으로 복제본은 주 노드와 여러 개의 보조 노드로 구성된다. 주 노드가 쓰기 작업을 처리하고 보조 노드는 주 노드로부터 데이터를 동기화하여 읽기 요청에 응답한다. 이로 인해 데베의 가용성이 향상되고, 주 노드가 장애 발생시에도 보조노드에서 데이터를 제공할 수 있다.

요약하면 샤딩은 데이터의 분할과 병렬 처리를 통해 확장성을 강조하고 레플리케이션은 데이터의 복제와 분산된 읽기를 통해 가용성과 내결함성을 강조한다.

 

 

* Redis(Remote Dictionary Server)

 - 오픈 소스 인메모리 데이터 스토어로, 키-값 구조를 지원하는 NoSQL 데베이다. 

 - 데이터를 메모리에 저장하고 조회하는 데에 특화되어 있다.

1. 데이터 구조 

 - 다양한 데이터 구조를 지원한다. 가장 기본적인 형태인 문자열(String)을 비롯하여 해시(Hash), 리스트(List), 집합, 정렬된 집합 등 다양한 데이터 구조를 활용할 수 있다.

 - 이러한 데이터 구조를 활용하여 다양한 데이터 조작 작업을 효율적으로 수행할 수 있다.

 

2. 인메모리 데이터 저장

 - Redis는 데이터를 메모리에 저장하고 조회하기 때문에 매우 빠른 응답시간을 제공한다.

 - 따라서 캐싱, 세션 관리, 실시간 분석 등 데이터 액세스가 빈번한 작업에 적합하다.

 - 데이터를 디스크에도 저장할 수 있으므로, 데이터의 영속성을 보장할 수 있다.

 

3. Pub/Sub 메시지 브로커

 - 레디스는 Publish/Subscribe 메시지 브로커로 사용될 수 있다.

 - 클라이언트는 특정 채널에 메시지를 발행(Publish)하고, 다른 클라이언트는 해당 채널에 구독(Subscribe)하여 메시지를 수신할 수 있다.

 - 이를 통해 실시간 메시지 전달, 채팅 애플리케이션, 이벤트 기반 아키텍쳐 등을 구현할 수 있다.

 

4. 트랜잭션 지원

 - 레디스는 여러 개의 명령어를 하나의 트랜잭션으로 묶어 실행할 수 있다.

 - 이를 통해 여러 명령어의 실행을 원자적으로 보장하고, 중간에 다른 클라이언트의 작업이 끼어들지 않도록 할 수 있다.

 

5. 클러스터링과 고가용성

 - 클러스터링을 통해 데이터를 분산 저장하고, 고가용성을 보장할 수 있다.

 - 여러 대의 레디스 인스턴스를 클러스터로 구성하여 데이터를 분산 저장하고, 일부 노드의 장애에도 시스템이 정상적으로 동작할 수 있도록 한다.

 

=> Redis는 성능이 뛰어나고 다양한 데이터 구조와 기능을 제공하여 다양한 분야에서 활용되고 있다. 주요 사용 사례로는 캐싱, 세션 관리, 실시간 분석, 메시지 큐, 리더보드, 게임 서버 등이 있다.또한 레디스는 확장성과 가용성을 위한 클러스트링 기능을 제공하여 대규모 시스템에서도 사용될 수 있다.

 

참조 : https://jordy-torvalds.tistory.com/entry/Clustering-vs-Replication-vs-Sharding

'Database' 카테고리의 다른 글

정규화  (0) 2024.05.15
인덱스(Index)  (0) 2024.02.21
트랜잭션(Transaction)  (0) 2024.02.21

BELATED ARTICLES

more