Redis

기술노트

Redis

Redis는 빠른 오픈 소스 인 메모리 키-값 데이터 구조 스토어입니다. 일반적인 데이터베이스는 하드 디스크나 SSD에 데이터를 저장하지만, Redis는 메모리(RAM)에 저장하기 때문에 디스크 스캐닝이 필요 없어 매우 빠른 성능을 제공합니다.

Redis는 캐싱 기능도 갖추고 있어 실시간 채팅에 적합하며, 세션 공유를 위한 세션 클러스터링에도 활용됩니다.

Redis의 데이터 영속성

RAM은 휘발성 메모리이기 때문에 시스템 종료 시 데이터가 손실될 수 있습니다. Redis는 이를 방지하기 위한 백업 방법을 제공합니다:

  • 스냅샷(Snapshot): 특정 시점의 데이터를 디스크에 백업하는 방식입니다.
  • AOF(Append Only File): 실행된 명령(쿼리)들을 저장해두고, 서버가 종료되면 이 명령들을 다시 실행하여 데이터를 복구하는 방식입니다.

Redis의 데이터 구조

Redis는 key/value 값으로 이루어진 비정형 데이터를 저장하는 비관계형 데이터베이스 관리 시스템입니다. Redis는 다양한 데이터 타입의 value를 지원합니다:

1. String: 텍스트나 바이너리 데이터로, 최대 512MB까지 저장 가능합니다. 2. Set: 문자열의 집합입니다. 3. Sorted Set: 정렬된 Set입니다. 4. Hash: 필드-값 쌍의 컬렉션입니다. 5. List: 양방향 연결 리스트가 가능합니다.

인메모리 데이터베이스의 필요성

인메모리 데이터베이스는 주로 속도 측면에서의 성능 향상을 위해 사용됩니다. 메모리(RAM)에 데이터를 저장하여 엑세스하는 방식은 SSD나 HDD와 같은 디스크 스토리지에서 데이터를 가져오는 것보다 수백 배(HDD 기준) 이상 빠릅니다.

다만, RAM은 용량이 제한적이라는 단점이 있어 메인 데이터베이스로 사용하기에는 한계가 있습니다. 또한 용량이 큰 RAM을 구매하는 것은 비용 측면에서 큰 부담이 될 수 있습니다.

Redis의 적합한 사용 사례

Redis는 다음과 같은 경우에 사용하기 적합합니다:

  • 대용량 데이터 중 소규모의 데이터만을 추출해야 할 때
  • 값의 변경이 빈번하지 않고 데이터 크기가 작을 때
  • 예시: 백만 명의 사용자가 있는 게임에서 상위 100위 랭커를 보여주는 기능

캐시

캐시란 자주 사용하는 데이터나 값을 미리 복사해 놓는 임시 저장소를 말합니다. 캐시에 존재하는 데이터는 최소한의 비용으로 반복적 접근이 가능하다는 장점이 있습니다.

Local Cache vs Global Cache

캐시는 크게 두 가지 종류로 나뉩니다:

  • Local Cache
    • Local 환경에서만 작동합니다.
    • Local 장비의 리소스(메모리, 디스크)를 활용합니다.
    • Local에서만 작동하기 때문에 속도가 빠릅니다.
    • 다른 서버와 데이터 공유가 어렵습니다.
  • Global Cache
    • 데이터의 분산 저장이 가능합니다.
    • 여러 서버에서 접근할 수 있습니다.
    • Local Cache에 비해 속도가 느립니다.
    • 별도의 캐시 서버를 이용하기 때문에 서버 간 데이터 공유가 쉽습니다.

Redis는 Global Cache에 적합합니다.

Redis의 동시성 이슈

Redis는 싱글 스레드 기반으로 데이터를 처리합니다. 그러나 여러 클라이언트에게 동시에 응답할 수 있는 것은 실제 명령에 대한 작업이 커널 레벨에서 멀티플렉싱(Multiplexing)을 이용해 동시성을 보장하기 때문입니다.

즉, 유저 레벨에서는 싱글 스레드로 작동하지만, 커널 I/O 레벨에서는 스레드 풀을 이용합니다. 이러한 동시성 특성 때문에 동시성 관련 에러가 발생할 수 있으므로 적절한 동시성 처리가 필요합니다.

Redis의 트랜잭션 처리

Spring Data Redis를 기준으로 트랜잭션을 처리하는 방법은 두 가지가 있습니다:

1. SessionCallback 인터페이스 사용: 여러 명령을 하나로 묶어서 처리하는 방법으로, 인터페이스를 통해 직접 Redis 명령어를 사용하여 트랜잭션 경계를 설정합니다. 2. @Transactional 어노테이션 사용: 더 간편하게 트랜잭션을 처리할 수 있는 방법입니다.

관련 항목