안녕하세요. J4J입니다.
이번 포스팅은 redis 사용하기 첫 번째인 redis란 무엇인가에 대해 적어보는 시간을 가져보려고 합니다.
Redis란 ?
redis는 key-value 형태의 오픈 소스 데이터베이스 중 하나로 대중적으로 많이 알려진 mysql, mongo 등과 같은 데이터 주 저장소가 디스크 기반이 아닌 메모리 기반의 데이터베이스 중 하나입니다.
메모리 기반의 redis를 사용하는 주 목적은 캐싱 처리를 통해 더 빠른 속도로 비즈니스 로직 처리를 수행하기 위함입니다.
디스크보다는 메모리로 접근하는 것이 더 빠르기 때문에 읽기 및 쓰는 속도가 메모리 기반의 데이터베이스가 아닌 것들보다 더 빠르게 동작됩니다.
또한 한번 처리가 완료된 결과물을 캐싱 처리하여 동일한 목적의 요청이 전달될 경우 캐싱되어 있는 정보를 바로 전달하기 때문에 비즈니스 로직 처리를 다시 수행하지 않아도 됩니다.
하지만 메모리에 데이터를 저장하기 때문에 디스크에 저장되는 것보다 데이터 유실 확률이 더 높습니다.
서버 다운으로 인한 재 시작 등과 같이 메모리가 비워지는 상황이 발생되면 저장되어 있는 데이터는 모두 삭제가 됩니다.
그러다 보니 redis의 주 사용 용도로는 위에서 얘기한 캐싱 처리를 포함하여 세션 관리 / 분석 결과 저장 등과 같이 데이터 유실이 되어도 상관없으면서 반복적이거나 로직 처리가 오래 걸리는 데이터들을 관리할 때 사용되고는 합니다.
그래도 redis에서는 이와 같은 상황을 개선하기 위해 다음과 같은 영속성 기능을 제공해주고 있습니다.
- RDB Snapshot → 일정 주기별로 데이터를 snapshot 형식으로 디스크에 저장
- AOF 로그 파일 → 모든 write 작업을 로그 파일에 기록
이와 같은 영속성 기능을 제공해주고 있기 때문에 메모리가 비워져 데이터가 손실되는 상황이 발생되더라도 손실이 되지 않도록 도와줍니다.
하지만 메모리가 비워지기 전 최종 상태를 최대한 보장해 줄 뿐이지 모든 데이터에 대해 손실을 항상 보장하지는 않습니다.
추가적으로 특징에 대해서 더 얘기를 해보면 다음과 같습니다.
RDB Snapshot은 다음과 같은 특징을 가지고 있습니다.
- 데이터 싱크를 맞출 때 속도가 빠름
- 데이터가 유실될 정도가 높음
- 영속성 유지를 위한 작업이 가벼움
반대로 AOF 같은 경우 다음과 같은 특징을 가지고 있습니다.
- 데이터 싱크를 맞출 때 속도가 느림
- 데이터가 유실 될 정도가 적음
- 영속성 유지를 위한 쓰기 작업으로 redis에 부하를 발생시킬 수 있음
각각의 특징들이 위와 같이 존재하기 때문에 redis를 어떤 목적으로써 사용하는지에 따라 선택해 볼 수 있습니다.
Redis 특징
redis의 특징은 다음과 같습니다.
[ 장점 ]
- 메모리 기반의 저장소 활용으로 읽기 및 쓰기 속도가 매우 빠름
- String / Hash / List / Set 등 다양한 데이터 구조를 지원
- 영속성 기능을 지원하여 데이터 손실을 최대한 방지
- master - slave 기반의 replication을 통해 고가용성 처리
[ 단점 ]
- 메모리가 비워지는 경우 데이터 손실이 발생될 수 있음
- 데이터 크기가 메모리를 초과하는 경우 성능에 영향을 줄 수 있음
- single thread 구조로 한 번에 하나의 명령만 처리하기 때문에 병목 현상이 발생할 수 있음
Java용 Redis 클라이언트 라이브러리
redis는 클라이언트 관점에서 redis를 다루기 위한 다양한 클라이언트 라이브러리를 제공해주고 있습니다.
언어 별로 다양한 라이브러리들이 존재하는데 그중 java를 위한 목적으로는 대표적으로 다음과 같이 2가지가 존재합니다.
- Jedis
- Lettuce
spring 진영에서는 위의 두 가지 라이브러리 중 lettuce의 사용을 권장하고 있습니다.
spring boot 2.0 이상 버전부터 jedis를 대신하여 lettuce를 기본 사용하는 것으로 변경되기도 했습니다.
왜 spring에서는 이런 선택을 하게 되었는지 각 특징들에 대해 정리해 보면 다음과 같습니다.
먼저 jedis의 특징은 다음과 같습니다.
- blocking 방식만을 활용하여 redis 서버와 통신
- 동기 처리 방식만 활용 가능
- connection 처리와 관련되어 멀티 스레드 환경에서 thread-safe 하지 않음
- redis 운영 방식인 sentinel과 cluster 환경 모두 지원을 하지만 추가 작업이 필요
반대로 lettuce의 특징은 다음과 같습니다.
- blocking / non-blocking 방식을 활용하여 redis 서버와 통신
- 동기 / 비동기 처리 방식 활용 가능
- connection 처리와 관련되어 멀티 스레드 환경에서 thread-safe 함
- redis 운영 방식인 sentinel과 cluster 환경 모두 지원을 하며 별도의 작업이 필요하지 않음
특징들을 살펴보면 lettuce가 다양한 운영 방식에 대한 추가 설정이 필요 없고 멀티 스레드 환경에서도 이점이 있는 것을 확인할 수 있습니다.
또한 non-blocking 및 비동기 처리가 가능하기 때문에 트래픽이 많아지는 경우 더 빠른 성능을 보여주고 있습니다.
비록 jedis가 lettuce에 비해 더 가볍겠지만 결과적으로 다양한 부분을 바라보면 lettuce의 사용을 권장합니다.
추가적으로 java를 위한 클라이언트 라이브러리 중 redisson이라는 것이 더 존재합니다.
redisson은 lettuce와 비슷한 특징들을 가지고 있지만 클라이언트가 분산 처리되어 있는 환경에서 더 강력한 기능을 제공합니다.
lettuce도 spin lock을 활용하기는 하지만 동시에 읽기 / 쓰기 작업을 수행하는 경우 동기화 처리가 올바르게 수행되지 않을 수 있습니다.
하지만 redisson은 pub/sub 기반의 DB lock을 활용하여 읽기 / 쓰기 작업에서도 자원에 대한 동기화 처리를 제공해주고 있습니다.
또한 락을 점유하고 있는 시간에 대한 설정도 할 수 있기 때문에 데드락이 발생되는 것도 방지할 수 있습니다.
그래서 분산 처리에 대해서도 고민을 해야 될 때 lettuce 대신 redisson을 사용하는 것은 하나의 선택지가 될 수 있습니다.
Redis 운영 방식
위에서 간단하게 얘기한 것처럼 redis 운영 방식은 다음과 같이 2가지가 존재합니다.
- Sentinel
- Cluster
위의 운영 방식들은 모두 redis를 분산 처리하여 사용되는 환경에서 활용하는 방식들입니다.
물론 redis를 단일 인스턴스로만 처리해서도 사용할 수 있습니다.
하지만 과도한 트래픽과 안정적인 redis 서버 운영을 위해 redis를 분산 처리해야 되는 상황이 필요한데 이런 경우 운영 방식 중 하나를 선택해서 활용할 수 있습니다.
먼저 sentinel 방식에 대해서 얘기를 해보겠습니다.
sentinel은 redis의 고가용성을 위해 사용되는 것으로 master / slave 서버를 두고 이를 모니터링하고 있는 sentinel 서버를 배치하는 방식입니다.
sentinel의 동작 방식은 다음과 같습니다.
- redis에서 발생되는 모든 읽기 / 쓰기 작업은 기본적으로 master 서버 한 곳에서만 이루어짐
- master 서버에 문제가 발생되지 않는지 sentinel 서버에서 주기적으로 모니터링
- sentinel 서버에서 master 서버가 문제가 발생되었다고 판단하면 slave 중 1개를 master로 승격시켜 요청 처리
sentinel의 특징은 다음과 같습니다.
- master 장애 감지 및 장애 복구를 통한 고가용성 제공
- sentinel을 통한 redis의 상태를 모니터링하고 장애가 발생할 경우 알림 제공
- cluster 운영 방식에 비해 수직 확장 (scale-out)에 대한 장벽이 존재
- cluster 운영 방식에 비해 비용적인 측면 이점이 존재
다음은 cluster 방식에 대해서 얘기해 보겠습니다.
cluster도 sentinel과 동일하게 고가용성을 위해 사용되며 cluster 기반으로 그룹화하여 관리하는 방식입니다.
cluster의 동작 방식은 다음과 같습니다.
- redis에 발생되는 모든 요청은 각 master 서버에 분산되어 작업 처리
- 각 master는 자신의 slave를 배치할 수 있고 slave는 gossip protocol을 통해 master의 장애를 감지할 경우 master로 승격
cluster의 특징은 다음과 같습니다.
- multi master 구조 제공 가능
- redis에 저장되는 데이터를 샤딩을 활용하여 master에 분산 저장
- 수직 확장 (scale-out) 이 용이하며 최대 1000개의 노드까지 확장 가능
- sentinel 운영 방식에 비해 구성을 위한 더 많은 비용이 필요
위와 같이 sentinel과 cluster는 각 특징들을 명확하게 가지고 있습니다.
어떤 운영 방식을 활용해야 할지는 redis를 사용하고자 하는 서비스의 구조에 맞게 적절히 선택해서 사용할 수 있습니다.
보통 대규모 데이터를 기반으로 한 높은 처리량과 함께 수직 확장이 필요한 경우는 cluster를 사용하면 됩니다.
하지만 반대로 비용적인 측면도 무시할 수 없기 때문에 작은 규모의 데이터 처리가 필요한 프로젝트를 수행하는 경우는 sentinel도 사용해볼 수 있습니다.
Spring에서 Redis 사용 방식
spring에서 redis 사용 방식은 다음과 같이 존재합니다.
- Redis Repository
- Redis Template
- Redis Cache Manager
각각의 특징과 spring에서 어떻게 사용하는지에 대해서는 다음 글들을 통해 작성해 보겠습니다.
이상으로 redis 사용하기 첫 번째인 redis란 무엇인가에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Spring > SpringBoot' 카테고리의 다른 글
[SpringBoot] Redis 사용하기 (3) - Redis Template 사용하기 (0) | 2024.05.13 |
---|---|
[SpringBoot] Redis 사용하기 (2) - Redis Repository 사용하기 (0) | 2024.05.12 |
[SpringBoot] SSE (Server-Sent Events) 사용하여 실시간 통신하기 (0) | 2024.05.07 |
[SpringBoot] @DataJpaTest In-Memory DB를 활용하여 테스트하기 (0) | 2024.05.06 |
[SpringBoot] Thread Local을 이용하여 Thread 별 독립적으로 변수 관리하기 (0) | 2024.05.04 |
댓글