프로젝트를 진행하며 Redis를 사용하였지만, 내가 직접 구현하지 못 한 것이 조금은 아쉬워서 먼저 흥미를 돋우어서 다음 프로젝트 때 내가 꼭 직접 Redis를 사용한 기능을 쉽게, 재미있게 구현하기 위해서
Redis에 대해 알아보고 공부를 해 보았다.
Redis란?
- 레디스는 Remote Dictionary Server → 외부에 key-value(키-값) 구조로 저장하는 서버
- In-Memory 기반의 Data Structure Store
즉, 메모리에 데이터를 저장하는 key-value 기반의 NoSQL DBMS
Redis의 용도
- 캐싱, 임시 작업 큐, 실시간 채팅, 메시지 브로커 등
- Redis는 주로 캐시 용도로 많이 사용 됨.
- 캐시: 데이터나 계산 결과를 미리 저장해 빠른 액세스와 높은 성능을 제공하기 위한 저장소
- 캐시 활용
- 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우(서버의 균일한 API 데이터)
- 반복적으로 동일한 결과를 돌려주는 경우(이미지나 썸네일 등)
- 캐시의 구현 방법: Redis, Memcached, Local Memory cache 등
Redis의 특징
- 성능
- In-Memory 기반의 특성으로 인해 디스크가 아닌 메모리에 저장되어 빠른 속도로 접근 가능 → 대기 시간을 낮추고 처리량을 높임.
- 평균적으로 읽기 및 쓰기의 작업 속도가 1ms로 디스크 기반 데이터베이스보다 빠름.
- 데이터 구조
- key-value 기반 구조
- value에는 다양한 자료 구조가 제공이 되어 개발의 편의성 증가, 비즈니스 로직에 집중할 수 있음
- 제공되는 자료구조 종류
- key: 기본적으로 String으로 제공
- value: Hash, List Set, Sorted Set 등등..
-
- key-value 기반 구조
- 싱글 스레드
- 한 번에 하나의 명령만을 처리 → Race Condition이 거의 발생하지 않음
- Race Condition이란? → 두 개 이상의 프로세스가 동시적으로 하나의 리소스에 접근하려고 서로 경쟁하는 상태
- 영속화 기능
- 메모리에 데이터를 저장한다고 해서 휘발되는 것이 아닌 메모리에 저장된 데이터를 디스크에 영속화하여 서버에 치명적인 문제가 발생해도 복구 가능
- RDB(Redis Database Backup)
- 특정한 간격으로 현재 Redis의 메모리에 존재하는 데이터의 스냅샷을 남기는 방식
- 장점: 압축하여 저장하기 때문에 AOF 보다 크기가 작음, 로딩&복구 속도가 빠름
- 단점: 백업 중 서버가 다운 될 경우, 최신 데이터 유실 가능성 존재
-
- **AOF(Append Only File)**
- 입력(Insert) / 수정(update) / 삭제(delete) **명령이 실행 될 때 마다 LOG 파일에 기록**
- 장점: **저장 속도 빠름**, 실시간 데이터 백업 가능, 데이터 손실 거의 없음
- 단점: 명령 실행 기록을 모두 기록하기 때문에 파일 크기가 큼, **복원 소요시간 김**
- 데이터 유실은 없지만, 지금까지 수행한 Write 작업을 다시 수행해야 하기 때문.

Redis 사용을 잘 하는 법
- 데이터 타입에 따른 적절한 자료구조 사용
- 최근 검색 목록 표시
- user_id 가 1, 2, 3인 사용자의 최근 검색 목록 조회
- 최근 검색 목록 표시
| id | user_id | keyword | reg_date |
| --- | --- | --- | --- |
| 1 | 123 | Redis | 2023.08.01 |
| 2 | 234 | Cache | 2023.08.02 |
| 3 | 123 | Cache | 2023.08.03 |
| 4 | 123 | Redis | 2023.08.03 |
```jsx
SELECT * FROM recent
WHERE user_id = 123
ORDER BY reg_date DESC
LIMIT 5
```
user_id로 5개의 제이터 제한 걸고 검색 날짜로 정렬하는 쿼리
추가로 중복 데이터 제거, 사용자 별로 데이터 개수 확인 → 오래된 검색어 삭제 작업 필요
<aside>
💡
Redis의 **Sorted Set 자료구조 사용** → 중복허용 X, 정렬되어서 저장
Sorted Set 특징: 가중치를 기준으로 오름차순 정렬
</aside>
- 가중치를 시간 값으로 사용한다면 가장 나중에 들어온 아이템이 맨 마지막 인덱스에 저장되는 것을 확인 가능
recent:member:123 **→**
| Index | Keyword | Time |
| --- | --- | --- |
| [0] | Sorted | 1690983952 |
| [1] | Set | 1690983975 |
| [2] | Data | 1690983986 |
| [3] | Cache | 1690983990 |
- O(N) 명령어 주의
- Redis는 Single Thread로 동작을 함.
- KEYS / FLUSHALL, FLUSHDB
Delete Collections / Get All Collections와 같은 O(N) 명령어의 경우 해당 명령이 처리 될 때 까지 다음 명령어들이 대기 상태로 전환 되는 문제 발생 → 오히려 성능 저하로 이어짐
- 메모리 관리
- Redis는 In-Memory Data Store라서 메모리 관리는 필수적임.
- 메모리 단편화 발생이란? → 메모리가 작은 공간으로 나뉘어져 관리되어서 사용 가능한 공간이 충분함에도 해당 메모리를 할당하지 못 하는 상태를 의미..
- 해당 메모리 단편화 문제로 인해 Redis는 7KB를 사용 중이라고 파악하지만 실제로 차지하는 공간은 10KB라고 인지하게 되는 문제 발생 → 실제 물리 메모리 사용량을 나타내는 RSS값을 모니터링 하여서 메모리 관리를 해주어야 함.
-
- Redis의 목적성
- 캐시 용도로 사용할지, 저장소 용도로 사용할지 분명히 해야함.
- Persistence 기능 (RDB, AOF) → 장애 발생 가능성이 높음
- Redis에 저장되었던 데이터가 없어져도 문제가 없는지, 일부 값이 유실되어도 치명적이지 않은지 판단해서 캐시용으로만 사용을 하게 된다면? Pesistence 기능을 OFF 해야함.
정리
- 어떤 데이터가 캐시의 대상이 될 수 있는지, 어떤 패턴으로 캐시를 구성할 수 있을지, 캐시를 위해서 어떤 시스템을 선택할지 등을 고려해 Redis 캐시를 사용해야 한다.
Reference
7 Redis Data Types: Commands & Data Structures Guide 2024
[10분 테코톡] 저문, 라온의 Cache & Redis