# Redis

`Remote Dictionary Server`

### 개념

* 키-값 구조를 가진 비관계형(NoSQL) 데이터베이스로, 메모리 기반의 데이터 처리를 지원
  * In-Memory기반으로 메인메모리(DRAM)에서 데이터를 저장하고 처리해 빠른 속도 제공
  * 주로 서버환경에서 동작하며, 클라이언트-서버 아키텍처를 따름
    * 클라이언트는 Redis 서버에 접속해 데이터를 읽고 쓰며 Redis는 프로세스로써 동작

<br>

### 특징

* **Key-value 구조**
  * 비관계형 구조로 데이터를 `키-값`형태로 단순하게 저장하는 구조
  * 관계형 데이터베이스와 같이 쿼리 연산을 지원하지 않으나, 데이터의 **고속 읽기와 쓰기**에 최적화
  * NoSQL DBMS로 분류 됨
* **In-Memory 솔루션**
  * 다양한 데이터 구조체를 지원함
    * DB, Cache, Message Queue, Shared Memory용도로 사용될 수 있음
    * 메모리에 상주하며 서비스의 상황에 따라 DB 혹은 Cache로 사용될 수 있음
  * 일반DB와 같이 디스크(ssd)에 데이터를 쓰는 구조가 아닌 메모리(dram)에서 데이터를 처리함
    * 작업 속도가 상당히 빠름
  * 메모리 기반으로 데이터 저장 속도가 매우 빠름
    * 리스트형 데이터 입력과 삭제가 MySQL에 비해 10배 정도 빠름
    * 외부 저장 장치를 사용했다면 메모리와 외부 저장 장치와 병목현상 발생
* **Remote Data Storage**
  * 여러 서버에서 같은 데이터를 공유하고 보고 싶을 때 사용가능
* **영속성 보장**
  * 기본적으로 메모리 기반의 데이터베이스로 휘발성이란 특징이 있으나 영속성 옵션을 제공해 데이터의 지속성 보장
  * RDB(Redis DataBase) 스냅샷
    * 주기적으로 데이터를 디스크에 스냅샷 형태로 저장
    * `*.rdb` 형식으로 저장하며 해당 시점으로 복구 가능
    * 백업이나 서버 재시작 시의 데이터 손실을 방지하기 위해 사용
  * AOF(Append-Only File) 로그 파일
    * 모든 쓰기 연산을 AOF 파일에 기록하는 방식 사용 가능
    * 주로 RDB 스냅샷보다 더 정확한 복구를 위해 사용
* **싱글 쓰레드**
  * 싱글 스레드로 1번에 1개의 명령어만 실행
  * 멀티 스레드 사용시 발생하는 비용 줄일 수 있어 빠른 응답 가능
    * `Context Switching` 과 `메모리 사용`을 줄일 수 있음
    * 원자성 보장
* **PUB/SUB를 가짐**
  * Publish / Subscribe 란 특정한 주제(topic)에 대해, 해당 topic을 구독한 모두에게 메시지를 발행하는 통신 방법
  * 실시간 채팅, 실시간 스트리밍, 실시간 알림, SNS 피드 등에 사용 가능
* 읽기 성능 증대를 위해 서버 측 복제를 지원
* 쓰기 성능 증대를 위해 클라이언트 측 샤딩을 지원
* 다양한 프로그래밍 언어 프레임워크 API 및 **다양한 자료구조 지원**

\ <br>

## Redis 주의할 점

* O(N) 시간복잡도 명령어 사용 금지
  * Redis는 Single Thread 서버이기 때문에 시간 복잡도를 고려해야 함
  * 동시에 1개의 명령어만 처리할 수 있기에, 해당 명령어가 오래걸릴 경우 나머지 명령어 대기상태로 전환됨
  * 데이터 속도가 많을 경우 큰 속도 저하 야기
  * O(N)의 시간복잡도를 갖는 대표적 명령어
    * keys, flushAll, flushDB, delete collections, get all collections
    * keys대신 scan명령어로 대체
* DEL명령어 대신 UNLINK 명령어 사용 권장
  * DEL 명령으로 삭제 시, 키에 많은 데이터가 있을 경우 해당 키를 지우는 동안 아무런 동작을 할 수 없음
  * UNLINK 명령 사용 시, 백그라운드로 삭제되기 때문에 권장 됨
* 캐시 만료시간 설정
  * 인메모리 DB는 크기가 한정되어 있기 때문에 key에 대한 Expire Time 설정 권장

\ <br>

## Redis 사용 이유

* Collection 제공
  * Sorted Set

    ![](https://blog.kakaocdn.net/dn/eCdBbM/btrFUUet1im/rflmRkbVwQfqDQK6dep8Pk/img.png)

    * 메모리에서 바로 가져와 사용하기에 디스크에 직접 접근하지 않아도됨
    * 정렬된 상태의 자료구조를 지원하기 때문에 빠르게 메모리에서 데이터를 가져와서 사용자에게 보여줄 수 있음
  * Key-Value
    * 간단한 key-value 형태로 redis에서 데이터 가져옴
* Atomic한 자료구조
  * Atomic한 자료 구조를 가지고 싱글 스레드로 동작해 race condtion 방지
  * 하지만 중복 요청 처리 등의 상황시 race condition 발생가능

\ <br>

## 고가용성 보장을 위한 Redis 아키텍처

### ✔️ Replication

* Master-slave 구조 기반
  * 하나의 Master서버와 하나이상의 Slave서버로 구성
    * Master 서버: 쓰기 작업 처리
    * Slave 서버: Master 서버의 데이터를 복제해 읽기 작업 처리
* 읽기 확장성 향상
  * Slave서버는 Master서버의 데이터를 복제해 읽기 작업 분산
* 데이터 가용성 향상
  * Master서버에 문제가 발생해도 Slave서버에서 데이터 사용 가능

> 마스터-슬레이브 구조로 읽기 성능을 향상시키고 데이터 가용성을 높임

<br>

### ✔️ Sentinel

> 고가용성을 보장하기 위한 모니터링 및 자동 장애 조치(failover) 시스템

* 모니터링
  * Redis 서버를 지속적으로 모니터링해 Master 서버나 Slave 서버의 상태 체크
* 자동 장애 조치
  * Master 서버에 장애 발생 시 자동으로 새로운 Master 서버 선출
  * 클라이언트가 새로운 Master 서버를 사용하도록 리디렉션
* 알림
  * 시스템 관리자에게 알림을 보내 장애 상황 통보

> Redis 서버를 모니터링하고, 장애 시 자동으로 장애 조치를 수행하여 고가용성을 보장

<br>

### ✔️ Cluster

> 데이터를 여러 노드에 분산 저장하고 처리하는 분산 데이터베이스 아키텍처

* 데이터 분산
  * 데이터는 여러 노드에 분산 저장되며, 각 노드는 데이터의 일부 관리
  * 키는 해싱 알고리즘을 통해 분산 됨
* 수평 확장성
  * 노드 추가로 클러스터의 용량과 성능을 확장 가능
* 고가용성
  * 자동으로 데이터 복제를 관리하여 특정 노드에 장애가 발생해도 데이터의 가용성 유지
* 자동 리밸런싱
  * 노드 추가 또는 제거 시 슬롯과 데이터를 자동으로 재분배하여 균형을 맞춤

> 데이터를 여러 노드에 분산 저장하고 처리하여 수평 확장성과 고가용성을 제공

\ <br>

## Redis 활용 사례

* I/O가 빈번히 발생하는 데이터
* 세션 캐싱 및 인증 토큰등 저장
* 전체 페이지 캐시
* 메시지 대기열 어플리케이션
* 랭킹 보드
* 좋아요 같은 빠른 데이터 처리를 요하는 시스템

\ <br>

> Redis는 RDBMS의 캐시 솔루션으로 사용 용도가 굉장히 높다

\ <br>

## 캐시(Cache)

**개념**

* 데이터나 값을 미리 복사해놓는 임시 저장소
* 한번 조회된 데이터를 미리 특정 공간에 저장해놓고, 똑같은 요청 발생 시 저장해놓은 데이터를 제공해 빠른 서비스를 제공하는 것

<br>

**DB와 캐시**

* DB는 데이터를 물리 디스크에 직접 씀
  * 서버에 문제가 발생해도 데이터가 손실되지 않음
  * 매 트랜잭션마다 디스크에 접근해야하므로 부하가 많아지면 성능이 떨어짐
* DB Scale In, Scale Out 방식 이외에도 `캐시 서버`의 사용 검토
* Redis Cache
  * 메모리 단(In-Memory) 위치
  * 용량은 적지만 빠른 접근 속도
  * 저장하려는 데이터 셋이 주어진 메모리 크기보다 클땐 디스크 사용이 유리

<br>

**캐시 전략**

캐시전략은 웹 서비스 환경에서 성능향상을 기대할 수 있는 중요한 기술.\
캐시 이용시 `데이터 정합성` 문제가 발생하므로, 적절한 `캐시 일기 전략`과 `캐시 쓰기 전략`을 통해 데이터 불일치 문제를 극복하며 빠른 성능을 유지한다.

[캐싱 전략 패턴 종류](https://inpa.tistory.com/entry/REDIS-📚-캐시Cache-설계-전략-지침-총정리#)

\ <br>

## Redis와 Memcached

**공통점**

* In Memory 저장소
* Key-value 저장 방식
* 1ms 이하의 응답 대기 시간
* 데이터 파티셔닝
  * 데이터를 여러 노드에 분산시켜 저장
  * 데이터 효과적 처리를 위한 스케일아웃 가능
* 다양한 프로그래밍 언어 지원

<br>

> **In-Memmory 데이터베이스** 데이터 저장을 메모리에 의존하는 특수 데이터베이스로, 디스크에 대한 접근을 없애 최소한의 응답시간을 가지도록 설계

<br>

**Memcached 특징**

* 정적 데이터 캐싱에 효과적
  * metadata에 더 적은 작원을 소모하기 때문에 내부 메모리 관리는 단순한 경우 매우 뛰어남
  * Redis 만큼 정교하지 않으나 String(유일한 지원 데이터 타입)은 추가 처리가 필요없어 읽기 전용에 적합
* 직렬화 데이터 저장
  * Redis
    * 데이터의 모든 형태를 그대로 저장 가능
  * Memcached
    * 직렬화된 형태로 데이터 저장하도록 제한
    * 직렬화 오버헤드를 보다 줄일 수 있음
* 멀티 쓰레드 기능 지원
  * Redis
    * **단일 쓰레드**로 데이터 손실없이 수평으로 스케일링
  * Memcached
    * **멀리 쓰레드**로 Redis에 비해 스케일링 유리
    * 컴퓨팅 자원 추가로 스케일 업 가능
    * 캐시된 데이터 유실 확률도 높음

\ <br>

### Memcached가 아닌 Redis 사용 이유

* 다양한 자료 구조 및 용량 지원
  * Memcached
    * key 이름 250 byte까지 제한
    * 단순히 string만 지원
  * Redis
    * keys, value 이름 512mb까지 지원
    * hash, set, list, string 등 다양한 데이터 구조 지원
* 다양한 삭제 정책 지원 (캐시 데이터 공간 확보 방법)
  * Memcached
    * LRU 방식 사용
    * 새로운 데이터와 크기가 비슷한 데이터 임의 제거
  * Redis
    * 6가지의 다른 데이터 삭제 정책 제공
    * 메모리 관리와 데이터 삭제 선택에 더 정교한 접근법 제공
    * lazy, active 삭제 지원
* 디스크 영속화 지원
  * Memcached와 달리 디스크 영구 저장 가능
  * DB의 데이터들은 서버 충돌이나 재부팅 시에도 복구 가능
* 복제 지원
  * 복제를 통해 데이터의 복제본이 또다른 인스턴스에 유지
  * Memcached는 Third Party를 사용하지 않고서는 복제본을 가질 수 없음
* 트랜젝션 지원
  * Memcached
    * 원자적으로 동작하나 트랜잭션을 지원하지 않음
  * Redis
    * 명령 실행을 위한 트랜잭션을 지원

\ <br>

### Ref

[레디스 소개 & 사용처 (캐시 / 세션) - 한눈에 쏙 정리](https://inpa.tistory.com/entry/REDIS-📚-개념-소개-사용처-캐시-세션-한눈에-쏙-정리?category=918728#)\
[우아한 Redis 정리(1)](https://codediary21.tistory.com/103) [In-memory Redis vs Memcached 비교하기](https://escapefromcoding.tistory.com/704)\
[\[Redis\] 레디스란? 특징, 활용예시, 비교 정리](https://hstory0208.tistory.com/entry/Redis-레디스란-특징-활용예시-비교-정리)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jmxx219.gitbook.io/cs/database/redis.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
