Redis란??
Redis는 Remote Dictionary Server의 약자로, 원격에 위치하고 프로세스로 존재하는 In-Memory 데이터베이스이자 Dicionary(key-value) 구조 데이터 관리 Server 시스템이다. 일반 데이터베이스 같이 디스크에 데이터를 쓰는 구조가 아니라 메모리(dram)에서 데이터를 처리하기 때문에 작업속도가 빠르다.
DB, Cache, Message Queue, Shared Memory 등으로 사용한다.
캐시(Cache)란?
캐시란 데이터나 계산 결과를 미리 저장하여 빠른 액세스와 높은 성능을 제공하기 위한 저장소를 말한다.
즉, 미리 결과를 저장하고 나중에 요청이 오면 해당 요청에 대해 DB를 참조하지 않고 캐시에 접근하여 요청을 빠르게 처리하는 것을 말한다. 같은 요청이 여러 번 들어오는 경우 매번 DB를 거치는 것이 아니라서 DB의 부하를 줄이고 서비스의 속도가 느려지지 않는다는 장점이 있다.
캐시가 나온 배경에는 파레토의 법칙이 있다. 파레토의 법칙이란 80%의 결과는 20%의 원인으로 인해 발생됨을 뜻하는 법칙이다. 웹 사이트에 대한 접근도 파레토의 법칙이 딱 들어맞아, 인터넷 통신의 80%가 불과 20%의 사이트에 대한 액세스로 추정되며, 이 20%의 웹 사이트 데이터를 캐 해두면 효율을 극적으로 향상시킬 수 있다고 한다. 따라서 모든 결과를 캐싱 할 필요 없이 서비스를 할 때 많이 사용되는 20%만 캐싱함으로써 효율을 끌어올릴 수 있다.
캐시는 Redis나 Memcached 등으로 구현 가능하다.
캐시 구조 패턴
Look aside Cache 패턴
캐시에 접근하여 데이터가 있는지 확인한 후, 있다면 캐시의 데이터를 사용하고 없다면 DB에서 데이터를 조회하여 캐시 서버에 저장하고 결괏값을 반환해 주는 패턴으로, 일반적으로 가장 많이 사용하는 패턴이다.
- 클라이언트가 데이터 요청
- 서버에서 데이터 존재 유무 캐시에 먼저 확인
- 캐시에 데이터가 있으면 DB에 접근하지 않고 캐시에 있는 데이터를 클라이언트에게 바로 반환(Cache Hit)
- 캐시에 데이터가 없으면 DB에서 데이터를 조회하여 캐시에 저장하고 결괏값을 클라이언트에게 반환(Cache Miss)
Write Back 패턴
주로 쓰기 작업이 굉장히 많아서 INSERT 쿼리를 일일이 날리지 않고 특정 시점마다 한꺼번에 배치 처리하기 위해 사용하는 패턴이다. INSERT 쿼리를 500번 수행하는 것보다 500개를 한 번에 삽입하는 것이 훨씬 빠르기 때문에 훨씬 빠른 속도로 서비스가 가능하다.
하지만 메모리의 특성상 휘발성이 있기 때문에 중간에 서버가 다운되면 데이터가 유실된다는 문제점이 있다. 그래서 다시 재생 가능한 데이터나 혹은 극단적으로 heavy한 데이터를 저장할 경우 사용한다.
보통 로그를 저장하는 작업에 유용하게 쓰인다.
- 모든 데이터를 캐시에 저장
- 캐시의 데이터를 일정 주기마다 DB에 한꺼번에 저장 (배치)
- DB에 저장한 데이터를 캐시에서 제거
Redis의 영속성(Persistence)
Redis는 메모리에 데이터를 저장한다고 했다. 그렇다면 중간에 서버에 문제가 생겨서 데이터가 유실된다면 어떻게 할까?
다행히 Redis는 영속성 옵션을 제공해서 서버에 문제가 생겨 데이터가 유실되더라도 복구가 가능하다.
Redis가 제공하는 영속성 옵션은 RDB, AOF 총 2가지가 있다.
RDB(Redis Database Backup)
RDB는 특정한 간격으로 현재 Redis의 메모리에 존재하는 데이터의 스냅샷을 남기는 방식이다.
데이터를 모두 압축하여 저장하기 때문에 AOF보다 크기가 작고, 데이터 자체를 저장하기 때문에 로딩/복구 속도가 빠르다는 장점이 있다. 하지만 백업 중에 서버가 다운될 경우 특정한 간격으로 저장하기 때문에 그 사이에 발생한 데이터에 대한 유실 가능성이 존재한다.
AOF(Append Only File)
AOF는 데이터 변경이 일어나는 입력/수정/삭제 명령이 실행될 때마다 해당 명령어들을 로그 파일에 기록하는 방식이다.
저장 속도가 빠르고, RDB와 달리 실시간 데이터 백업이 가능하여 데이터 손실이 거의 없다는 장점이 있다. 하지만 명령 실행 기록을 모두 기록하기 때문에 RDB보다 파일 크기가 크고 데이터 자체를 저장하는 것이 아니라서 복원 소요 시간이 길다는 단점이 있다.
Memcached와 Redis?
Memcached는 무료로 사용할 수 있는 오픈소스이며 분산 메모리 캐싱 시스템으로, Redis처럼 In-Memory 저장소이다. DB의 부하를 줄여 동적 웹 애플리케이션의 속도 개선을 위해 사용하며, DB나 API 호출 또는 렌더링 등으로부터 받아오는 결과 데이터를 key-value 형태로 메모리에 저장한다. 그렇다면 둘의 차이점은 무엇일까?
Redis | Memcached | |
저장소 | In Memory Storage | |
저장 방식 | Key-Value | |
데이터 타입 | String, List, Set, Sorted Set 등 | String |
데이터 저장 | Memory, Disk | Only Memory |
스레드 | Single Thread | Multi Thread |
트랜잭션 지원 | O | X |
Publisher/Subscriber | O | X |
Memcached는 2003년에 나온 고성능 캐싱 솔루션이다. Redis는 비교적 최근(2009년)에 나왔으며, 여러 기능을 탑재한 캐싱 솔루션이다.
- 데이터 타입
- Memcached는 데이터를 문자열로만 저장하는 반면, Redis는 더 다양한 자료형을 지원한다.
- Memcached를 사용할 때는 JSON.stringfy 등의 메서드를 통해 데이터를 전부 변환하여 저장하고, 가져올 때도 파싱을 해야 하는 반면 Redis는 바로 원하는 데이터를 다룰 수 있다.
- 데이터 영속성
- Memcached는 영속성을 지원하지 않지만 Redis는 영속성을 지원(RDB, AOF)한다.
- Memcached는 이러한 특성 때문에 데이터를 유실할 위험성이 높다.
- 데이터 길이
- Redis의 key 또는 string은 512MB에 달하는 크기를 가질 수 있는 반면 Memcached의 key는 250 Byte의 크기밖에 갖지 못한다.
Memcached는 상대적으로 작고 정적인 데이터를 캐싱하는 경우, 메타 데이터에 대한 메모리 리소스를 비교적 적게 소비하여 간단한 사용에 적합하다.
Redis는 문자열, 해시, 리스트 등과 같은 복잡한 데이터 유형이 필요한 경우, 데이터를 정렬하거나 순위를 지정해야 하는 경우, 백업 및 복원 기능이 필요하거나 여러 데이터베이스를 지원해야 하는 경우에 사용하기 적합하다.
Redis 주의할 점
O(N) 명령어 주의
Redis는 싱글 스레드이므로 O(N)의 시간이 걸리는 명령어(KEYS / FLUSHALL / FLUSHDB 등)를 사용할 경우, 해당 명령이 처리될 때까지 다음 명령어들이 대기 상태로 전환되는 문제가 발생한다. 빠른 성능을 위해 Redis를 사용하였지만 오히려 더 느린 성능이 제공될 수 있다.
메모리 관리
Redis의 경우 In-Memory 저장소이므로 메모리 관리가 필수적이다. Maxmemory를 설정하더라도 이보다 더 사용할 가능성이 크다. 메모리 특성상 메모리 단편 화가 발생하기 때문이다. 메모리 단편화란 메모리가 작은 공간으로 나누어져 관리되어서 사용 가능한 공간이 충분한데도 불구하고 해당 메모리를 할당하지 못하는 상태를 의미한다. 위의 그림처럼 Redis는 7KB를 사용 중이지만 실제로 차지하는 공간은 10KB라고 인지하게 되는 문제가 발생한다. 따라서 RSS(Resident Set Size, 실제 물리 메모리 사용량)값을 모니터링하여 메모리 관리를 해주어야 한다.
[Reference]
'Development > 데이터베이스' 카테고리의 다른 글
JPA, Spring Data JPA 차이점 (0) | 2025.07.11 |
---|---|
왜 데이터베이스 인덱스로 B tree 계열을 사용할까? (0) | 2025.01.07 |
JPA와 MyBatis (0) | 2024.12.13 |
RDB와 NoSQL (0) | 2024.11.23 |