

reference ; https://ganganichamika.medium.com/deep-dive-into-nosql-database-types-80340598124
- 키-값 저장소
- 데이터가 키와 값의 쌍으로 저장
- 대표적인 데이터베이스: Redis, Riak, Amazon DynamoDB
- 칼럼 저장소
- 데이터가 로우(키 값), 컬럼 패밀리, 컬럼 이름으로 구성
- 2차원 키-값 저장소
- 대표적인 데이터베이스: HBase, Cassandra, Hypertable
- 문서 저장소
- 키-값 모델을 확장한 형태로, 데이터가 문서(보통 JSON이나 XML 형식) 형태로 저장
- 대표적인 데이터베이스: MongoDB, CouchDB
reference ; https://velog.io/@park2348190/%EB%85%BC%EB%AC%B8%EB%B2%88%EC%97%AD-SQL-vs-NoSQL-A-Performance-Comparison
- NoSQL 데이터베이스는 일반적으로 밀리초(ms) 단위의 매우 낮은 응답 지연시간을 제공할 수 있다
비정형 데이터 : 미리 정의된 데이터 모델이나 스키마가 없는 데이터
- 텍스트 파일 (워드 문서, PDF 등)
- 멀티미디어 파일 (이미지, 오디오, 비디오)
- 소셜 미디어 게시물
- 이메일 내용
- 센서 데이터
- 로그 파일
이러한 데이터는 고정된 스키마를 가진 관계형 데이터베이스에 저장하기 어려우므로, 유연한 스키마를 제공하는 NoSQL 데이터베이스를 활용하여 다양한 형태의 데이터를 쉽게 저장 및 관리 가능
NoSQL 데이터베이스, 특히 문서 저장소는 JSON, YAML, XML 등의 형식으로 데이터를 직접 저장 가능 -> 객체와 저장 형식 간의 변환 작업이 줄어듦
일반적으로 테라바이트(TB) 또는 페타바이트(PB) 규모의 데이터를 다룰 때 NoSQL이 유리할 수 있다
- NoSQL이 대용량 데이터 처리에 유리한 이유
- 수평적 확장성: 새로운 서버를 추가하여 쉽게 용량을 늘릴 수 있다
- 분산 아키텍처: 데이터를 여러 노드에 분산 저장하여 대규모 병렬 처리 가능
- 스키마 유연성: 다양한 형태의 대용량 데이터를 효율적으로 저장 가능
- 높은 쓰기 성능: 많은 NoSQL 데이터베이스는 대량의 쓰기 작업에 최적화되어 있음
스케일 업 (수직적 규모 확장) : 서버에 고사양 자원 (더 좋은 CPU, 더 많은 RAM 등) 을 추가하는 것스케일 아웃 (수평적 규모 확장) : 더 많은 서버를 추가하여 성능을 개선하는 것트래픽 양이 "적다"는 것에 대한 정확한 수치 기준은 없고 상황에 따라 상대적이며, 다음과 같은 요소들을 고려할 수 있다.
- 현재 서버의 성능: CPU, 메모리, 디스크 I/O 등의 리소스 사용률이 낮은 수준(예: 50% 미만) 유지
- 응답 시간: 사용자에게 허용 가능한 응답 시간 내에 서비스를 제공 가능
- 동시 사용자 수: 일반적으로 수천 명 이하의 동시 사용자를 처리할 수 있다면 단일 서버로 충분할 수 있음
- 성장률: 트래픽이 급격히 증가하지 않고 안정적이거나 완만하게 증가한다면 스케일 업으로 대응 가능
- 비용 효율성: 스케일 업이 스케일 아웃보다 비용 효율적인 경우
- 애플리케이션의 특성: 일부 애플리케이션은 수직적 확장에 더 적합할 수 있다.
- 단일 스레드 작업이 많은 경우 CPU 성능 향상이 효과적일 수 있음

✅ 로드밸런서의 트래픽 분산 원리
- 각 서버의 상태(사용량, 처리 능력/용량 등)를 모니터링하고, 적절한 알고리즘을 사용하여 트래픽을 분산한다.
- 로드밸런싱 알고리즘은 크게 2가지 범주로 나뉜다
정적 로드 밸런싱: 고정된 규칙을 따르며 현 서버 상태와 무관
- 라운드 로빈 방식 : 클라이언트 요청 순서대로 서버를 배정하는 방식
- 가중 라운드 로빈 방식 : 서버마다 가중치를 설정하고 가중치에 따라 서버를 배정하는 방식
- IP 해시 방식 : 클라이언트 IP 주소를 해싱이라고 하는 계산을 수행하여 숫자로 변환하여, 개별 서버에 매칭해 처리
동적 로드 밸런싱: 서버의 현재 상태 검사
- 최소 연결 방식 : 연결이 가장 적은 서버를 확인하고 해당 서버로 트래픽 전송
- 최소 응답시간 방식 : 응답 속도가 빠른 서버부터 우선적으로 트래픽 로드 배분
- 리소스 기반 방식 : 현재 서버 부하를 분석하여 트래픽 전송. 에이전트라고 하는 특수 소프트웨어는 각 서버에서 실행되며 컴퓨팅 용량 및 메모리와 같은 서버 리소스의 사용량을 계산하고, 해당 서버에 트래픽을 배포하기 전에 에이전트에 충분한 여유 리소스가 있는지 확인함
- 가장 많이 사용되는 알고리즘은 ?
- 라운드 로빈 방식은 구현이 간단하고 공평한 분배가 가능하다는 장점이 있어 많은 로드밸런서에서 기본적으로 사용되는 알고리즘
- NGINX: NGINX는 웹 서버이자 로드밸런서로 널리 사용되며, 기본적으로 라운드 로빈 방식 사용
- AWS Application Load Balancer (ALB): 이전에는 ALB가 라운드 로빈 알고리즘만을 사용하여 수신 요청을 백엔드 대상에 배포했음
- HAProxy: 오픈 소스 로드밸런서
- Apache HTTP Server mod_proxy_balancer: Apache의 로드밸런싱 모듈
쓰기 연산은 마스터에서만 지원한다읽기 연산 만을 지원한다✅ 즉시 새로운 부 데이터베이스가 추가되니까, 장애가 난 부 서버를 대체한다는 건가 ? 즉시 어떻게 데이터베이스가 추가되지 ?
실제로는 새로운 서버를 준비하고 데이터를 동기화하는 데 어느 정도 시간이 소요된다.
이 기간 동안 시스템은 degraded mode(성능 저하 모드)로 운영될 수 있다.
고가용성 시스템에서는 이러한 상황에 대비해 미리 준비된 대기 서버(standby server)를 두어 빠르게 전환할 수 있도록 하는 경우도 있음스탠바이 서버 (Standby Server)
- 주로 고가용성(HA) 시스템에서 사용되는 용어
- 주 서버(Primary/Master)의 장애 시 즉시 대체할 수 있도록 준비된 서버
슬레이브 서버 (Slave Server):
- 마스터-슬레이브 복제 구조에서 사용되는 용어
- 마스터 서버의 데이터 변경사항을 복제하여 동기화하는 서버
공통점
- 데이터 동기화: 모두 주 서버(마스터)의 데이터 변경사항을 지속적으로 동기화
- 읽기 전용 작업: 일반적으로 읽기 전용 쿼리를 처리 가능
- 장애 대비: 주 서버 장애 시 대체 역할을 할 수 있음
차이점
- 스탠바이 서버는 주로 고가용성을 위해 사용되며, 즉시 주 서버로 전환될 수 있도록 준비된 상태를 유지
- 슬레이브 서버는 주로 읽기 부하 분산을 위해 사용되며, 항상 마스터 서버의 복제본 역할을 함
- PostgreSQL에서는 이러한 서버를 "standby server"라고 부르며, 데이터를 지속적으로 동기화하고 필요시 주 서버로 승격될 수 있음
- 이 서버는 "warm standby" 또는 "hot standby" 모드로 운영될 수 있으며, 후자의 경우 읽기 전용 쿼리를 처리할 수 있음
- 기본적으로 주 서버의 데이터를 복제하고 필요시 대체 역할을 하는 서버를 지칭한다고 볼 수 있음
복구 스크립트 를 돌려서 추가하거나, 다중 마스터, 원형 다중화 방식을 도입하여 이런 상황에 대처할 수 있다다중 마스터
- 여러 데이터베이스 서버가 동시에 마스터 역할을 수행하는 구조
- 모든 노드가 읽기 및 쓰기 작업을 처리할 수 있음
- 높은 가용성과 확장성 제공
- 지리적으로 분산된 환경에서 유용
- 데이터 충돌 해결 메커니즘 필요
원형 다중화 방식
- 데이터베이스 서버들이 원형 구조로 연결되어 데이터를 복제하는 방식
- 각 노드는 다음 노드에 데이터를 복제
- 마지막 노드는 첫 번째 노드에 데이터를 복제하여 원형 구조 형성
- 단일 장애점(Single Point of Failure) 제거
- 네트워크 트래픽 분산
데이터베이스를 얼마나 자주 호출하느냐에 크게 좌우되는데, 캐시는 그런 문제를 완화할 수 있다캐시 계층 : 데이터가 잠시 보관되는 곳
수평적 확장 (Scale-Out)
- 가장 일반적인 방법으로, 캐시 서버의 수를 늘리는 것
- 여러 캐시 서버를 클러스터로 구성하여 부하를 분산시킴
- 일반적으로 consistent hashing (안정 해시) 알고리즘을 사용하여 데이터를 여러 캐시 서버에 분산 저장
수직적 확장 (Scale-Up)
- 개별 캐시 서버의 리소스를 증가시키는 방법
- 메모리, CPU, 네트워크 대역폭 등을 증가시켜 단일 서버의 성능을 향상시킴
캐시 우선 읽기 전략 (read-through)
계층화된 캐시 (Layered Caching)
CPU Register > L1 Cache > L2 Cache > L3 Cache > RAM > SSD > HDD 순의 접근 속도를 지니는데, 이 중에 Redis가 사용하는 계층이 RAM이다.
- Redis : 주로 메인 메모리 (RAM) 에 데이터를 저장하고 관리하는 인메모리 데이터 구조 저장소
- L1 캐시: CPU 내부에 위치 / CPU 코어마다 별도로 존재하는 가장 빠른 속도로 접근할 수 있는 캐시
- L2 캐시: L2 캐시는 CPU 회로판에 별도의 칩으로 내장된다. L1 캐시를 먼저 뒤지고, L2 캐시를 뒤져 데이터를 찾는다.
- L3 캐시 : L2 캐시로 충분히 커버할 수 있기 때문에 웬만한 프로세서에서는 L3 캐시 메모리를 달고있지 않다. L1/L2 캐시 메모리 정도만 CPU 성능에 직접적인 영향을 미치기에 L3 캐시는 크게 신경쓰지 않는것이 일반적인 추세다. L3 캐시는 CPU가 아닌 메인보드에 내장되는 경우가 더 많다.
지역 분산 캐시 (Geographically Distributed Cache)
- 전 세계적으로 분산된 사용자를 위해 여러 지역에 캐시 서버를 배치
- CDN과 유사한 개념으로, 사용자와 가까운 위치의 캐시 서버를 사용
- Amazon ElastiCache for Redis를 사용하면 여러 AWS 리전에 걸쳐 글로벌 데이터 스토어를 구성 가능
✅ 레디스의 만료기한 도래 시 데이터 삭제 정책
레디스는 기본적으로 TTL 이 만료된 데이터를 아래 2가지 방법으로 삭제
- 주기적으로(100ms) 만료시간이 설정된 일부 키를 임의로 선택하여 만료여부를 확인 후 삭제
- 레디스에 저장된 모든 키를 확인할 경우 CPU 부하가 심해진다. 레디스는 이를 막기위해 일부 키만을 선택하여 확인한다.
- 만료된 데이터에 접근시 삭제
- 키를 가져올 때 만료시간이 설정되어 있을 경우 만료여부를 확인한다. 만료되었다면 이 시점에 키를 삭제하고 아무것도 반환하지 않는다.
레디스의 데이터 방출 정책
- noeviction: 메모리가 고갈된 경우 새로운 쓰기 작업을 하려고 할 때 에러를 반환한다.
- allkeys-lru: 가장 최근에 사용되지 않은 키를 삭제한다.
- allkeys-random: 키 공간에서 임의의 키를 삭제한다.
- allkeys-lfu: 사용빈도가 적은 키를 삭제한다.
- volatile-lru: 만료기간이 설정된 키 중에서 가장 최근에 사용되지 않은 키를 삭제한다.
- volatile-random: 만료기간이 설정된 키 중에서 임의의 키를 삭제한다.
- volatile-lfu: 만료기간이 설정된 키 중에서 사용빈도가 적은 키를 삭제한다.
- volatile-ttl: 만료기간이 설정된 키 중에서 ttl 이 가장 짧은것을 삭제한다.
정적 콘텐츠를 전송하는 데 쓰이는, 지리적으로 분산된 서버의 네트워크응답 HTTP 헤더에는 해당 파일이 얼마나 오래 캐시될 수 있는지 설명하는 TTL (Time-To-Live) 값이 들어있다상태 정보 (사용자 세션 데이터와 같은) 를 웹 계층에서 제거해야 수평적으로 확장할 수 있다무상태 웹 계층 : 상태정보를 관계형 데이터베이스나 NoSQL 같은 지속성 저장소에 보관하고, 필요할 때 가져오도록 하는 것고정 세션 (sticky-session) 기능을 제공하고 있음지리적 라우팅 (geo-routing, geoDNS-routing) 장애가 없는 상황에서 사용자는 가장 가까운 데이터 센터로 안내된다✅ 데이터베이스의 수평적 확장 방법
- 샤딩(Sharding): 대규모 데이터셋을 더 작은 조각(샤드)으로 나누어 여러 데이터베이스에
분산 저장하는 기법- 레플리케이션(Replication): 동일한 데이터베이스 복사본을 여러 서버에 생성하는 방식 (데이터베이스 다중화)
- 페더레이션(Federation): 기능별로 데이터베이스를 분할하는 방식
ex) 결제, 주문, 프로필 등 각 기능별로 별도의 데이터베이스를 사용하여 각 데이터베이스의 읽기/쓰기 트래픽을 줄이고 전반적인 성능을 향상시킴- 파티셔닝(Partitioning): 큰 테이블을 더 작고 관리하기 쉬운 부분으로 나누는 기법
✅ 데이터베이스를 분할하는 2가지 방법 : 샤딩과 파티셔닝
- 파티셔닝
- 매우 큰 테이블을 여러개의 테이블로 각 행들을 분할하는 작업
- 수평 파티셔닝 : 하나의 테이블의 각 행을 다른 테이블에 분산시키는 것
(보통 수평 분할은 하나의 데이터베이스 안에서 이루어지는 경우를 지칭) <-> 샤딩 : 서로 다른 데이터베이스로 분산
- 수직 파티셔닝 : 테이블의 일부 열을 빼내는 형태로 분할.
정규화도 수직 파티셔닝과 관련된 거라고 할 수 있지만, 수직 파티셔닝은 이미 정규화된 데이터를 분리하는 과정이라고 생각해야 함
단일 서버 내 파티셔닝
- 일반적으로 말하는 파티셔닝은 하나의 데이터베이스 서버 내에서 데이터를 분할하는 기법
- 이 경우 서버 대수를 늘리지 않아도 됨. 주로 성능 최적화와 데이터 관리를 위해 사용됨
다중 서버 파티셔닝 (분산 파티셔닝)
- 테이블 A와 테이블 B를 서로 다른 서버에 분산하여 저장하는 방식
- 이 경우 서버 대수를 늘려야 함
- 샤딩
- 샤딩 : 동일한 스키마를 가지고 있는 여러대의 데이터베이스 서버들에 데이터를 작은 단위로 나누어 분산 저장하는 기법
- 물리적으로 서로 다른 컴퓨터에 데이터를 저장하므로, 쿼리 성능 향상과 더불어 부하가 분산되는 효과까지 얻을 수 있다. 즉, 샤딩은 데이터베이스 차원의 수평 확장(scale-out)인 셈!
데이터가 어떻게 분산될지 정하는 하나 이상의 칼럼으로 구성된다.