NoSQL 등장 배경
모놀리틱 아키텍처 문제점
모놀리틱 아키텍처 : 전체 애플리케이션을 하나의 통합 패키지로 개발 및 배포
- 한개의 시스템에 문제 생기면 → 전체 시스템의 문제
- 하나의 모듈 수정 → 전체 애플리케이션 다시 배포
- 일부 파트에서 리소스 확장하고 싶어도 → 시스템 전체를 확장해야함 (리소스 낭비)
마이크로서비스 아키텍처 등장
각각의 독립된 모듈을 조립해 하나의 서비슬르 만드는 아키텍처
- 업데이트, 테스트 배포, 확장을 각 서비스별로 독립적으로 수행 가능 (새로운 기능 추가 및 배포가 편리)
- 한 서비스의 문제 → 다른 서비스에 영향 주지않음(독립성)
- But, 서비스 분리로 인한 관리의 복잡도 증가
데이터 저장소 요구사항 변화
기존의 모놀리틱은 관계형DB 많이씀(중앙집중형 시스템)
- 최근의 서비스 → 비정형 데이터 증가하는 추세(정해진 형태x, 구조 예측 불가)
- 다차원 적 or 깊은 계층 구조 → 정형화된 테이블로 관리 힘듦
- ex) 실시간 로그 데이터 → 쓰기 성능이슈
- ex) 그래프화 된 데이터 → 변환하는데 추가적인 계산 필요
- ex) json 데이터 → 필드 분석 후, 알맞은 칼럼 정의해야함
⇒ 마이크로 서비스는 독립된 데이터 저장소가 필요
- 서비스별 비즈니스 특성과 데치터 형태를 고려해, 관계형 데이터베이스 or NoSQL 데이터베이스 선택
NoSQL 이란?
- SQL을 사용하지 않는 데이터 저장소임을 내포 (No SQL or Not Only SQL)
- 여러 가지 타입이 있지만, 관계가 정의돼 있지 않은 데이터를 저장한다는 공통적 특징
NoSQL 일반적 특징
마이크로 서비스의 저장소로 쓰일 수 있도록 여러 요구사항 만족시킴
- 실시간 응답
- 마이크로 서비스 내의 저장소에서는 빠른 응답 속도 중요.
- 개별 서비스가 빠르게 동작 안하면 → 서비스 자체가 병목현상 유발
- 확장성
- 예상치 못한 이벤트로 인한 트랜잭션 증가에 유연하게 확장 될 수 있음
- 고가용성
- 장애 상황에서 신속하게 복구돼 항상 사용할 수 있는 상태 유지
- 클라우드 네이티브
- 단순성
- 유연성
- 관계형 DB보다, 다양한 방식으로 비정형 데이터 저장할 수 있는 방법 제공
NoSQL 데이터 저장소 유형
1. 그래프 유형
- 노드, 엣지, 속성으로 데이터 나타냄. (데이터의 엔티티 → 노드, 관계 → 엣지)
- 엣지 : 항상 시작 노드, 끝 노드, 유형, 방향 가짐 + 상-하위 관계, 동작, 소유자 정보 저장
- 엔티티 간의 관계를 효율적으로 저장하도록 설계됨. (관계를 저장하고 표현할 때 유용하게 사용)
⇒ 저장되는 속성 크기가 크거나, 많은 속성 저장할 때는 적합 X
⇒ 추천 서비스에서 유용하게 사용될 수 있음
⇒ ex) 유저(노드)간 친구 관계(엣지)를 이용해 새로운 친구 추천
⇒ 사기 감지, 소셜 미디어, 네트워크 및 IT 운영 상황에서도 유용하게 사용 가능
2. 칼럼 유형
- 데이터는 하나의 열에 중첩된 키-값 형태로 저장될 수 있음(유연한 스키마 저장가능)
- 대량의 데이터에 대한 집계 쿼리를 다른 유형보다 훨씬 빠르게 처리 가능
⇒ 데이터를 행이 아닌, 열을 기준으로 저장
⇒ 기업의 BI 분석을 위한 데이터 웨어하우스에서 유용
⇒ 분석, 보고, 빅데이터 처리에 적합
3. 문서 유형
- 모든 값은 항상 키와 연결되는 계층적 트리와 같은 구조⇒ 데이터를 저장하거나 검색하는데 효과적
- ⇒ ex) MongoDB, CouchDB, AWS의 DocumentDB
- JSON 형태로 데이터 저장
4. 키-값 유형
- 모든 값은 키에 연결됨. 키 자체도 유의미한 데이터.
⇒ 로그를 남기는 작업이나, 대규모 세션을 실시간으로 관리하는 상황에서는 응답속도 중요(지연시간 최소화)
⇒ 키-값 유형 모델은 구조의 단순성으로 인해 빠른 데이터 액세스와 처리속도를 보장
⇒ ex) 레디스, AWS의 ElastiCache, AWS의 DynamoDB, Oracle NoSQL Database, Memcached
레디스(Remote dictionary server) 란?
고성능 키-값 유형의 인메모리 NoSQL 데이터베이스
- 오픈 소스 기반의 데이터 저장소 (소스코드가 있음) → 이후에 설치할때, 패키지로도 가능하지만, 소스코드로도 가능
레디스 특징
1 ) 실시간 응답(빠른 성능)
- 인메모리 DB vs 온디스크 DB자주 사용되는 데이터는 캐싱되어 메모리에 올라와있는 경우도 있지만, 그렇지 않은 데이터는 직접 디스크에 가서 데이터를 검색하는 과정을 거쳐야함. 이때, 디스크에 접근하는 빈도가 증가할 수록 → 시스템 성능 저하.인메모리 : 모든 데이터가 컴퓨터의 메모리에서 관리됨.
- 디스크에 접근하는 과정이 필요없어, 데이터의 처리성능이 빠름.
- ( 디스크의 데이터를 페이지 단위로 메모리에 올린 뒤, 메모리에서 데이터를 찾고, 없는 경우, 다시 다른 페이지를 디스크에서 가져와 메모리에 올린뒤 찾음 + HDD, SSD와 같은 디스크에 접근하는 속도는 RAM과 같은 메모리에 접근하는 속도보다 현저히 느림)
- 온디스크 : 데이터는 영구적으로 디스크에 저장.
2) 단순성
- 레디스는 키-값 형태로 데이터 관리할 수 있는 저장소.
- 키에 매핑되는 값 → 문자열, hash, set 등 다양한 데이터 구조 저장 가능
- 기존 관계형 DB : 임피던스 불일치(Impedance mismatches) → 관계형 DB 테이블과 프로그래밍 언어간 데이터 구조, 기능차이로 인해 발생하는 충돌.
- 레디스: 다양한 자료구조 통해 임피던스 불일치 해소.
⚠️ 주의사항
레디스는 싱글 스레드로 동작한다. (정확히는, 메인 스레드 1개와 별도의 스레드 3개) 하지만, 클라이언트의 커맨드를 처리하는 부분은 이벤트 루프를 이용한 싱글 스레드로 동작!
+) 최소 하나의 코어만 있어도 레디스 사용할 수 있어 배포가 쉬움. (CPU가 적은 서버에서도 좋은 성능)+) 멀티 스레드 애플리케이션에서 요구되는 동기화나 잠금 매커니즘 없이도 안정적이고 빠르게 사용자 요청 처리 가능.
⇒ BUT, 싱글 스레드로 동작한다는 것은 한 사용자가 오래 걸리는 작업을 수행하면, 다른 사용자는 그 쿼리가 완료될 때까지 대기할 수 밖에 없는 것.
⇒ 레디스는 메모리에서 동작하기 때문에 대부분의 커맨드는 빠른 응답시간.반환 느린 특정 커맨드가 존재하는데, 이런 커맨드만 주의해서 사용하면 장애 가능성 줄일 수 있음
3 ) 고가용성
- 레디스는 자체적으로 HA(High Availability) 기능을 제공
- 복제를 통해 데이터를 여러 서버에 분산 가능
- 센티널은 장애 상황 탐지 → 자동으로 페일오버(fail-over)
- 애플리케이션이 센티널을 이용해 레디스에 연결하는 구조 → 마스터에 장애가 발생하더라도 레디스로의 엔드포인트를 변경할 필요없이, 페일오버가 완료돼 정상화되 마스터 노드 사용 가능
- 페일 오버(fail-over)?
- 페일오버(Failover) 는 장애 조치 기능으로 시스템 장애 이벤트 발생 시 하나 이상의 예비 백업 시스템(노드) 로 자동 전환되는 것을 말합니다.
4 ) 확장성
- 레디스에서 클러스터 모드 사용 → 손쉬운 수평적 확장이 가능
5 ) 클라우드 네이티브 - 멀티 클라우드
- 클라우드 네이티브?마이크로 서비스, 컨테이너, 오케스트레이션, 데브옵스와 같은 개발 및 운영 패러다임 포용
- 클라우드 환경에 특화된 애플리케이션의 개발 및 운영방식
- 레디스는 클라우드 네이티브 환경에서 빠른 데이터 액세스 및 처리를 지원하는 구조로 인해, 마이크로 서비스 아키텍처와의 연계에서 큰 장점
데이터 저장소로서의 레디스
- 레디스는 마이크로 서비스 아키텍처에서 각 서비스별 개별 저장소로 사용하기 적절
- 설치 간편 + 최소한의 리소스로 막대한 처리량 + 다양한 자료 구조 제공
- 고가용성을 위해 → 로드밸런서나 프록시등 추가적인 서비스 설치 필요없음. (HA(High Availability) 기능을 제공)
- 영속성 측면 → 레디스는 AOF와 RDB 형식으로 주기적으로 디스크에 저장할 수 있음
- AOF : Redis에 작용하는 모든 write/update 연산을 별도의 로그 파일에 기록
- Application이 종료된 후, 다시 구동될 때, 해당 로그파일 참조하여 데이터 복구
- 로그 파일 복구시에 시간걸림 + 로그파일 커지면 많은 공간 차지
- RDB : 주기적으로 디스크 기반에 데이터베이스에 접근. Redis의 상태를 옮겨서 저장
- Redis 데이터를 옮기는 동안 Redis가 blocking 될 수 있다.
- 일반적으로 두가지 방식을 혼합하여 사용
- ex) 매일 새벽 3시마다 RDB 스냅샷을 생성하고, RDB 생성 이후, 변경되는 데이터는 AOF 이용해서 백업
- AOF : Redis에 작용하는 모든 write/update 연산을 별도의 로그 파일에 기록
- 레디스에 장애가 발생해, 데이터 유실되어도 → 백업 파일로 다시복구 가능