Redis (Remote Dictionary Server)
Redis는 원격(Remote)에 위치하며 프로세스가 실행되는 In-Memory 기반의 Dictionary(key-value) 구조 데이터 관리 서버 시스템입니다. 여기서 key-value 구조 데이터란 MySQL과 같은 관계형 데이터베이스가 아닌 비관계형 구조로, 데이터를 단순히 key-value 형태로 저장하는 방식을 의미합니다.
따라서 관계형 데이터베이스처럼 복잡한 쿼리 연산을 지원하지 않으나, 데이터의 고속 읽기와 쓰기에 최적화되어 있습니다. 이러한 이유로 Redis는 일종의 NoSQL 데이터베이스로 분류됩니다.
💡 NoSQL이란?
NoSQL은 "Not Only SQL"의 약자로, 기존 관계형 데이터베이스(RDBMS) 보다 더 융통성 있는 데이터 모델을 사용하고 데이터 저장 및 검색에 특화된 메커니즘을 제공하는 데이터 저장 기술을 의미합니다.
NoSQL 데이터베이스는 단순 검색 및 추가 작업에 최적화된 key-value 저장 기법을 사용하여 응답 속도와 처리 효율 면에서 매우 뛰어난 성능을 보여줍니다.
Redis는 In-Memory 솔루션으로 분류되며, 다양한 데이터 구조체를 지원하며 데이터베이스(DB), 캐시(Cache), 메시지 큐(Message Queue), 공유 메모리(Shared Memory) 등 여러 용도로 활용될 수 있습니다. 또한 일반 데이터베이스처럼 디스크(SSD)에 데이터를 저장하는 방식이 아닌 메모리(DRAM)에 데이터를 처리하기 때문에 작업 속도가 훨씬 빠릅니다.
Redis의 주요 특징을 정리하면 다음과 같습니다.
- In-Memory 데이터 저장: Redis는 모든 데이터를 메모리에 저장하므로 매우 빠른 읽기와 쓰기 속도를 제공
- key-value 데이터 구조: 데이터를 키(key)와 값(value)의 쌍으로 저장하며, 비관계형 데이터 저장 방식
- 다양한 데이터 타입 지원: 다양한 자료구조 지원 (String, List, Set, Hash...)
- 영속성 옵션: 데이터를 메모리에만 저장할 수도 있고, 디스크에도 저장할 수 있는 영속성 옵션이 제공
- Snapshot: 데이터를 디스크에 옮겨 담는 방식 SAVE(blocking), BGSAVE(non-blocking)
- AOF(Append Only FIle): 모든 write/update 연산을 log 파일 형태로 기록하는 방식
- 트랜잭션 지원: 여러 프로세스의 명령어를 하나의 트랜잭션으로 묶어 원자성(Atomic)을 보장하는 기능을 제공
- 레디스 클러스터링: 여러 대의 Redis 인스턴스를 클러스터로 구성하여 데이터의 높은 가용성과 확장성
- 단일 스레드: 기본적으로 1개의 싱글 스레드로 수행되며, 비동기식 입출력 모델과 내부 최적화 기법을 활용
- 단일 스레드 기반이기 때문에 서버 하나에 여러 개의 서버를 띄우는 것이 가능
- Master-Slave 형식으로 구성하여 Master Server가 다운되도 Slave Server로 접속하여 서비스 유지
Redis 활용 - 캐시(Cache)
캐시(Cache)란 한번 조회된 데이터를 미리 특정 공간에 저장해 놓고, 동일한 요청이 발생되면 다시 서버에 요청하지 않고 특정 공간에 저장된 데이터를 제공하여 빠르게 서비스를 제공하는 기법을 말합니다. 즉, 데이터베이스나 API를 다시 참조하지 않아도 저장된 결과를 바로 제공함으로써 요청 처리를 최적화하는 방식입니다.
작은 인프라를 가진 서비스는 WEB <-> WAS <-> DB 정도로 구축되지만, 사용자가 증가하면 데이터베이스의 처리량이 많아져 부하가 커지기 시작합니다. 데이터베이스는 데이터를 물리 디스크에 직접 쓰기 때문에 데이터의 안정성은 보장되나, 매 트랜잭션마다 디스크를 접근하기 때문에 성능이 저하될 수 있습니다.
Redis Cache는 메모리(In-Memory)에 위치하여 데이터 접근 속도가 매우 빠릅니다. 따라서 데이터가 메모리 용량을 초과하지 않는 선에서 빠른 데이터 처리가 가능하며, 사용자 증가에 따라 처리해야 할 데이터 양이 많아질 경우 Redis를 도입하는 것을 추천합니다.
Redis 캐시 활용 사례
Twitter는 140자 정도의 짧은 글을 올릴 수 있는 소셜 네트워킹 서비스(SNS)로 타임라인(Timeline)을 통해 사용자가 팔로우하는 사람들의 최신 트윗을 볼 수 있습니다. 2012년 당시, Twitter는 15만 명의 실시간 사용자와 초당 30만 건 이상의 타임라인 요청을 처리해야 했습니다. 이는 요청마다 데이터베이스에 직접 접근하여 처리하면 속도가 떨어지는 문제가 발생하였습니다.
이를 해결하기 위해 메모리 기반 NoSQL 기술인 Redis를 도입합니다. Twitter의 데이터 센터에 있는 방대한 양의 Redis 클러스터는 각 사용자의 타림라인에 노출될 트윗 정보(트윗 ID, 작성자 ID)를 약 800개 정도 리스트 형태로 캐싱합니다.
타임라인이 요청이 발생하면, 데이터베이스는 직접 접근하는 대신 Redis에 캐싱된 정보를 먼저 가져옵니다. 이틀 통해 쿼리를 단순화하여 데이터베이스에 접근하고 요청을 처리함으로써, 데이터베이스의 부하를 줄이고 응답 시간을 크게 개선할 수 있었습니다.
그러나 모든 사용자의 타임라인을 캐싱하면 메모리 부족이 일어날 수 있어, 로그인을 안 한 30일 이상 안 한 사용자는 Redis Cluster에 삭제하게 됩니다. 30일이 지나 삭제된 사용자는 다시 로그인할 시 Redis Cluster에 재성성되며, 이때 데이터베이스에 직접 접근하는 과정이 필요하게 됩니다.
이처럼 Redis는 Remote Dictionary로서 RDBMS의 캐시 솔루션으로 사용됩니다.
Redis의 문제점 (주의사항)
메모리 파편화
Redis는 메모리를 할당 받고 해제하는 과정에서 다음과 같이 부분마다 빈 공간이 생기게 됩니다.
4번과 같이 새로운 메모리를 할당할 때 빈 공간이 발생될 수 있습니다. 이러한 현상이 지속되면 실제 물리 메모리가 부족해져 프로세스가 종료될 수 있습니다. 또한, 쓰기 연산이 Copy-on-Write 방식으로 작동하기 때문에 최대 메모리 사용량이 2배 이상 될 수 있습니다. 따라서, Redis를 사용할 때는 메모리를 적절히 여유 있게 할당하는 것이 좋습니다.
시간 복잡도, O(N) 관련 명령어는 주의
Redis는 싱글 스레드이므로 Buffer에 쌓인 요청을 하나씩 처리해야 합니다. 따라서 처리하는데 시간이 오래 걸리는 요청이 온다면 뒤에 쌓인 요청들은 모두 대기해야 하므로 O(N) 관련 명령어는 피해야 합니다.
대표적인 O(N) 명령어는 다음과 같습니다.
- KEYS: 모든 키를 검색, 큰 데이터셋에서는 성능 문제가 발생
- FLUSHALL: 모든 데이터베이스의 모든 키를 삭제
- FLUSHDB: 현재 선택된 데이터베이스의 모든 키를 삭제
- 큰 컬렉션의 데이터를 모두 가져오는 명령어
참조
'ETC' 카테고리의 다른 글
hELLO 스킨에 mac 코드 스타일 적용 오류 해결 방법 (0) | 2024.01.23 |
---|---|
코드 블럭 테스트 (0) | 2024.01.23 |