Redis에 대해 본격적으로 알기전에 Cache, Memcached에 대해 알고 넘어가자..!!
1. Cache 란?
Cache란 나중에 요청할 결과를 미리 저장해둔 후 빠르게 서비스해 주는 것을 의미한다. 미리 결과를 저장하고 나중에 요청이 오면 그 요청에 대해서 DB 또는 API를 참조하지 않고 Cache를 접근하여 요청을 처리하는 기법이다.
이러한 Cache가 나온 배경에는 파레토 법칙이 있다.
(파레토 법칙이란 80%의 결과는 20%의 원인으로 인해 발생한다는 뜻이다.)

Cache는 모든 결과를 캐싱할 필요가 없으며 서비스를 할 때 많이 사용되는 20%만 캐싱함으로써 전체적으로 효율을 끌어올릴 수 있다.
2. Cache의 사용 구조

- 클라이언트로부터 요청을 받는다.
- Cache와 작업을 한다.
- 실제 DB와 작업한다.
- 다시 Cache와 작업한다.
클라이언트가 웹 서버에 요청을 보내면, 웹 서버는 데이터를 DB에서 가져 오기 전에 캐시에 데이터가 있는지 확인하고,
있다면 바로 클라이언트에게 저장된 데이터를 반환한다. 이를 Cache Hit라고 한다.
반대로 캐시 서버에 데이터가 없으면 DB에 데이터를 요청하여 원하는 데이터를 조회한 후 그 데이터를 클라이언트에게 제공하는데, 이를 Cache Miss라고 한다.
위 flow에서 캐시를 어떻게 사용하느냐에 따라서 look aside cache와 write back으로 나뉜다.
1. Look Aside Cache (Lazy Loading)
- 캐시에 데이터 존재 유무 확인
- 데이터가 있다면 캐시의 데이터 사용
- 데이터가 없다면 캐시의 실제 DB 데이터 사용
- DB에서 가져 온 데이터를 캐시에 저장
look aside cache는 캐시를 한 번 접근하여 데이터가 있는지 판단한 후, 있다면 캐시의 데이터를 사용하고 없으면 실제 DB 또는 API를 호출한다. 대부분의 캐시를 사용한 개발이 해당 프로세스를 따른다.
2. Write Back
- 모든 데이터를 캐시에 저장
- 캐시의 데이터를 일정 주기마다 DB에 한꺼번에 저장 (배치)
- DB에 저장한 데이터를 캐시에서 제거
write back은 주로 쓰기 작업이 굉장히 많아서, INSERT 쿼리를 일일이 날리지 않고 한꺼번에 배치 처리를 하기 위해 사용한다.
DB에서 디스크를 접근하는 횟수가 줄어들기 때문에 성능 향상을 기대할 수 있지만, DB에 데이터를 저장하기 전에 캐시 서버가 죽으면 데이터가 유실된다는 문제점이 있다.
3. Local Cahe VS Global Cache
- Local Cache
- Local 장비 내에서만 사용 되는 캐시
- Local 장비의 Resource를 이용한다 (Memory, Disk)
- Local에서 작동 되기 때문에 속도가 빠르다.
- Local에서만 작동되기 때문에 다른 서버와 데이터 공유가 어렵다
- Global Cache
- 여러 서버에서 Cache Server에 접근하여 사용하는 캐시
- 데이터를 분산하여 저장 할 수 있다.
- Replication - 데이터를 복제
- Sharding - 데이터를 분산하여 저장
- Local Cache에 비해 상대적으로 느리다 (네트워크 트래픽)
- 별도의 Cache Server를 이용하기 때문에 서버 간 데이터 공유가 쉽다.
>> redis는 Global Cache에 적합함
1. Memcached란 무엇일까?
Memcached는 무료로 사용할 수 있는 오픈 소스이며 분산 메모리 캐싱 시스템이다. DB의 부하를 줄여 동적 웹 애플리케이션의 속도 개선을 위해 사용하며, DB나 API 호출 또는 렌더링 등으로부터 받아오는 결과 데이터를 key - value 형태로 메모리에 저장한다.

초창기의 캐시 시스템은 [그림 1]과 같이 각 노드가 완전히 독립적으로 운영되어 데이터를 조회하거나 저장 시 어느 서버를 이용할지 관리해야 하고, 용량의 제한으로 인해 비생산적이며 자원 낭비적인 시스템으로 구성되었다.
Memcached는 이러한 제약 사항을 해결하기 위해 [그림 2]와 같이 consistent hash 알고리즘을 사용하여 물리적인 별도의 캐시 서버를 로직 상 하나의 서버로 보고 사용할 수 있도록 하였다. 즉, 개발자는 서버가 몇 대든 상관없이 한 개의 객체만을 활용하여 저장 및 조회할 수 있으므로 능률적이고 대용량의 캐시 시스템을 갖게 되는 것이다. 또한, 기업의 입장에서는 오래된 저사양 서버의 남는 메모리를 활용할 수 있기 때문에 비용 면에서 효율적일 수 있다.
- Memcached의 특징
- 처리속도가 빠르다 - 데이터가 메모리에만 저장되므로 빠르다. 즉, 속도가 느린 Disk를 거치지 않는다
- 데이터가 메모리에만 저장된다.
- 당연히 프로세스가 죽거나 장비가 shutdown되면 데이터가 사라진다
- 만료일을 지정하여 만료가 되면 자동으로 데이터가 사라진다.
- 이름에서도 느껴지듯이 cached이다.
- 저장소 메모리 재사용
- 만료가 되지 않더라도 더 이상 데이터를 넣은 메모리가 없으면 LRU(Least recently used) 알고리즘에 의해 데이터가 사라진다.
- LRU : 가장 오랫동안 사용되지 않은 것을 삭제
- 만료가 되지 않더라도 더 이상 데이터를 넣은 메모리가 없으면 LRU(Least recently used) 알고리즘에 의해 데이터가 사라진다.
1. Redis란 무엇일까?
Redis는 오픈 소스로서 NoSQL로 분류되기도 하고, Memcached와 같이 인 메모리 솔루션으로 분류되기도 한다. 성능은 Memcached에 버금가면서 다양한 데이터 구조체를 지원함으로써 DB, Cache, Message Queue, Shared Memory 용도로 사용될 수 있다.
Redis는 Remote Dictionary Server의 약자로 외부에서 사용 가능한 Key-Value 쌍의 해시 맵 형태의 서버라고 생각할 수 있다. 그래서 별도의 쿼리 없이 Key를 통해 빠르게 결과를 가져올 수 있다.

Redis는 단어의 의미에서 보면 외부에 key-value를 저장하는 서버를 말한다.
Redis.io 에는 다음과 같이 Redis를 소개한다.
Redis는 In-Memory 데이터 구조 저장소로, 데이터베이스, 캐시, 메시지 브로커로 사용한다고 말한다.
2. Redis 데이터 구조

이렇게 다양한 자료구조를 지원하게 되면 개발의 편의성이 좋아지고 난이도가 낮아진다는 장점이 있습니다.
어떤 데이터를 정렬을 해야하는 상황이 있을 때, DBMS를 이용한다면 DB에 데이터를 저장하고, 저장된 데이터를 정렬하여 다시 읽어오는 과정은 디스크에 직접 접근을 해야하기 때문에 시간이 더 걸린다는 단점이 있습니다.
이 때 In-Memory 데이터베이스인 Redis를 이용하고 레디스에서 제공하는 Sorted-Set이라는 자료구조를 사용하면 더 빠르고 간단하게 데이터를 정렬할 수 있습니다.
3. Redis 특징
- 영속성을 지원하는 인메모리 데이터 저장소
- 읽기 성능 증대를 위한 서버 측 복제를 지원
- 쓰기 성능 증대를 위한 클라이언트 측 샤딩(Sharding) 지원
- 다양한 서비스에서 사용되며 검증된 기술
- 문자열, 리스트, 해시, 셋, 정렬된 셋과 같은 다양한 데이터형을 지원. 메모리 저장소임에도 불구하고 많은 데이터형을 지원하므로 다양한 기능을 구현
최종적으로 Redis를 아래와 같이 한 문장으로 정의할수 있습니다.
Redis는 고성능 키-값 저장소로서 문자열, 리스트, 해시, 셋, 정렬된 셋 형식의 데이터를 지원하는 NoSQL이다.
4. Redis 영속성(Persistence)
Redis는 영속성을 보장하기 위해 데이터를 디스크에 저장할 수 있다. 서버가 내려가더라도 디스크에 저장된 데이터를 읽어서 메모리에 로딩한다. 데이터를 디스크에 저장하는 방식은 크게 두 가지가 있다.
- RDB(Snapshotting) 방식
- 순간적으로 메모리에 있는 내용 전체를 디스크에 옮겨 담는 방식
- AOF(Append On File) 방식
- Redis의 모든 write/update 연산 자체를 모두 log 파일에 기록하는 형태
4. Redis 싱글 스레드 사용

Redis 자료구조는 Atomic 하다는 특징 때문에 이런 race condition 을 피할 수 있다. 즉, Redis Transaction 은 한번의 딱 하나의 명령만 수행할 수 있다. 이에 더하여 single-threaded 특성 을 유지하고 있기 때문에 다른 스토리지 플랫폼보다는 이슈가 덜하다고 한다.
하지만 이 특징이 더블클릭 같은 동작으로 같은 데이터가 2번씩 들어가게 되는 불상사는 막을 수 없기 때문에 별도 처리가 필요하다.
* Race Condition이란 두 개 이상의 cocurrent한 프로세스(혹은 스레드)들이 하나의 자원(리소스)에 접근하기 위해 경쟁하는 상태를 말합니다.
5. O(N) 관련 명령어는 지양하자
주요 특징중 하나로 redis는 싱글 스레드(single thread)로 동작한다. 동시에 처리할 수 있는 명령어의 갯수는 한번에 하나이다.
* 실제 명령어 동작은 packet단위로 전달되며 packet이 쌓여 명령 command가 완성되면 명령을 실행한다.
왜 시간복잡도 O(N)을 사용하면 문제가 될까? 예를 들어, CPU 성능에 따라 차이가 있지만 가장 간단한 get/set 과 같은 명령어 기준 1초에 약 10만건의 명령어를 처리 할 수 있다. 그런데 동시에 10만건의 명령이 전달되었다. 그 중 첫번째 명령어가 3초가 걸린다면? 나머지 99,999건의 명령이 3초를 기다리게 되는 상황이 발생한다.
- KEYS
- >> SCAN명령으로 끊어서 key값 조회
- FLUSHALL, FLUSHDB
- Delete Collections
- Get All Collections
- >> 컬렉션의 일부만 가져오기
- >> 컬렉션을 한번에 저장하지 말고 나눠서 저장하기
위 명령어들이 대표적인 O(N) 명령어들로 꼭 필요한 경우가 아니라면 사용을 하지 않는 편이 좋다.
6. Redis 예상 면접 질문 및 답변
1. Redis 란?
Redis는 고성능 키-값 저장소로서 String, list, hash, set, sorted set 등의 자료 구조를 지원하는 NoSQL이다.
2. Redis는 언제 사용하는가?
DB, Cache, Message Queue, Shared Memory 용도로 사용될 수 있다. 주로 Cache 서버를 구현할 때 많이 쓴다.
3. Redis 특징은?
- 영속성을 지원하는 인 메모리 데이터 저장소
- 다양한 자료 구조를 지원함.
- 싱글 스레드 방식으로 인해 연산을 원자적으로 수행이 가능함.
- 읽기 성능 증대를 위한 서버 측 리플리케이션을 지원
- 쓰기 성능 증대를 위한 클라이언트 측 샤딩 지원
- 다양한 서비스에서 사용되며 검증된 기술
4. Redis는 왜 Thread Safe 한가?
싱글 스레드 방식이어서 연산을 하나씩 처리한다.
* 스레드 안전(thread 安全, 영어: thread safety)은 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음을 뜻한다.
5. Redis는 왜 속도가 빠른가?
Key-Value 방식이므로 쿼리를 날리지 않고 결과를 얻을 수 있다.
6. Redis는 영속성을 어떻게 보장하는가?
RDB 또는 AOF 방식을 통해 영속성을 보장한다.
- RDB(Snapshotting) 방식
- 순간적으로 메모리에 있는 내용 전체를 디스크에 옮겨 담는 방식
- AOF(Append On File) 방식
- Redis의 모든 write/update 연산 자체를 모두 log 파일에 기록하는 형태
7. Redis와 Memcached의 차이는 무엇인가?
| Redis | Memcached | |
| Thread | 싱글 | 멀티 |
| 데이터 구조 | list, string, hashes, sorted sets 등 다양한 자료구조 지원 |
string, integers만 지원 |
| 데이터 저장 | Memory, Disk | Only Memory |
| 처리 속도 | Memcached보다는 느리지만 큰 차이는 없다. |
디스크를 거치지 않아 redis보다 더 빠르다. |
| 영속성(Persistence) | 영속성이 있는 데이터 사용 | 지원 X |
| Replication | 지원 | 지원 X |
| Partitioning method | 지원 | 지원 X |
https://steady-coding.tistory.com/586
https://zangzangs.tistory.com/72
https://devlog-wjdrbs96.tistory.com/374
https://velog.io/@swhan9404/Redis-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80
'개발공부 > 개념정리' 카테고리의 다른 글
| SOLID - 객체지향적 설계 원칙 (0) | 2022.06.14 |
|---|---|
| OOP(Object oriented Programming) 객체지향 프로그래밍 (0) | 2022.06.13 |
| HTTP, HTTPS, SSL, TLS (0) | 2022.06.07 |
| @Annotation 개념 및 사용방법 (0) | 2022.04.20 |
| Spring - Filter, Interceptor, AOP 개념 차이 (0) | 2022.04.14 |