Redis
Redis란?
Remote dictionary server의 약자인 레디스(Redis)는 고성능 키-값 유형의 인메모리(in-memory) NoSQL 데이터베이스로, 오픈 소스 기반의 데이터 저장소다.
특징
실시간 응답 (빠른 성능)
대부분의 데이터베이스는 온디스크(disk-based) 형태다. 온디스크 형태의 데이터베이스에서 데이터는 영구적으로 디스크에 저장된다. 자주 사용되는 데이터는 캐싱돼 메모레이 올라와 있는 경우도 있지만, 그렇지 않은 데이터를 찾고자 할 때에는 직접 디스크에 가서 데이터를 검색하는 과정을 거쳐야 한다. 이때 디스크에 저장된 데이터는 바로 찾을 수 없으며, 디스크의 데이터를 페이지 단위로 메모리에 올린 뒤 메모리에서 데이터를 찾고, 없는 경우 다시 다른 페이지를 디스크에서 가져와 메모리에 올린 뒤 찾는 과정을 반복한다. HDD와 SSD와 같은 디스크에 접근하는 속도는 RAM과 같은 메모리에 접근하는 속도보다 현저히 느리다. 디스크에 접근하는 빈도가 증가할수록 시스템의 성능은 저하된다.
인메모리 형태의 데이터베이스에서는 모든 데이터가 컴퓨터의 메모리에서 관리된다. 디스크에 접근하는 과정이 필요 없기 때문에 데이터의 처리 성능이 굉장히 빠르다는 장점이 있다.
단순성
레디스는 키-값 형태로 데이터를 관리할 수 있는 데이터 저장소다. 키에 매핑되는 값에는 문자열뿐만 아니라 hash, set 등 더욱 복잡하고 다양한 데이터 구조를 저장할 수 있도록 지원하며, 이런 데이터 타입은 프로그래밍의 기본 자료 구조와 밀접한 관련이 있어 추가적인 데이터의 가공 없이 애플리케이션에서 쉽게 사용할 수 있다.
임피던스 불일치(Impedance mismatches)란 기존 관계형 데이터베이스의 테이블과 프로그래밍 언어 간 데이터 구조, 기능의 차이로 인해 발생하는 충돌을 의미한다. 레디스는 내장된 다양한 자료 구조를 통해 임피던스 불일치를 해소하고 개발을 편리하게 할 수 있도록 지원한다.
레디스는 싱글 스레드로 동작한다는 점이다. 정확히 말하자면 메인 스레드 1개와 별도의 스레드 3개, 총 4개의 스레드로 동작한다. 하지만 클라이언트의 커맨드를 처리하는 부분은 이벤트 루프를 이용한 싱글 스레드로 동작한다. 최소 하나의 코어만 있어도 레디스를 사용할 수 있어 배포가 쉬우며, CPU가 적은 서버에서도 좋은 성능을 낼 수 있다. 또한 멀티스레드 애플리케이션에서 요구되는 동기화나 잠금 메커니즘 없이도 안정적이고 빠르게 사용자의 요청을 처리할 수 있다.
그러나 싱글 스레드로 동작한다는 것은 한 사용자가 오래 걸리는 커맨드를 사용한다면, 다른 사용자는 그 쿼리가 완료될 때까지 대기할 수 밖에 없다는 것이다.
고가용성
레디스는 자체적으로 HA(High Availability) 기능을 제공한다. 복제를 통해 데이터를 여러 서버에 분산시킬 수 있으며, 센티널(sentinel)은 장애 상황을 탐지해 자동으로 페일오버(fail-over)를 시켜준다. 애플리케이션이 센티널을 이용해 레디스에 연결하는 구조에서는 마스터에 장애가 발생하더라도 레디스로의 엔드 포인트를 변경할 필요 없이 페일오버가 완료돼 정상화된 마스터 노드를 사용할 수 있다.
Redis Sentinel은 장애 발생 시 운영 서비스에 영향이 없도록 (=고가용성) 레디스 마스터 모니터링 및 자동 장애 극복 조치 (=fail-over)해주는 서비스이다.
확장성
레디스에서 클러스터 모드를 사용한다면 손쉬운 수평적 확장이 가능하다. 데이터는 레디스 클러스터 내에서 자동으로 샤딩된 후 저장되며, 여러 개의 복제본이 생성될 수 있다. 이 데이터의 분리는 데이터베이스 레이어에서 처리되며 애플리케이션에서는 대상 데이터가 어떤 샤드에 있는지 신경 쓰지 않아도 되므로, 레디스를 사용할 때와 동일하게 데이터를 가져오고 저장할 수 있다. 클러스터 구조에서 모든 레디스 인스턴스는 클러스터 버스라는 프로토콜을 이용해 서로 감시하고 있으며, 이를 이용해 클러스터의 마스터 노드에 문제가 발생하면 자동으로 페일오버를 시켜 고가용성을 유지할 수 있다.
클라우드 네이티브 - 멀티 클라우드
클라우드 네이티브는 클라우드 환경에 특화된 애플리케이션의 개발 및 운영 방식을 의미한다. 이 방식은 마이크로 서비스, 컨테이너, 오케스트레이션 그리고 데브옵스와 같은 현대의 개발 및 운영 패러다임을 포용하며, 빠른 배포와 확장성, 높은 복원력을 중심으로 한 애플리케이션을 추구한다. 레디스는 이러한 클라우드 네이티브 환경에서 빠른 데이터 액세스 및 처리를 지원하는 구조로 인해, 마이크로 서비스 아키텍처와의 연계에서 큰 장점을 지닌다.
멀티 클라우드는 여러 클라우드 제공업체의 서비슬르 동시에 혹은 혼합해 활용하는 전략을 의미한다. 이 전략은 단일 클라우드 환경의 장애나 제한된 자원에 대한 의존성을 줄이며, 각 클라우드 서비스 제공자의 강점을 활용할 수 있게 해 준다. 또한 멀티 클라우드를 사용하면 데이터가 특정 지역이나 국가 내에 물리적으로 위치하도록 조절할 수 있어, 더 가까운 저장소에서 데이터를 처리하게 되므로 대기 시간을 줄이고 장애 상황에 더욱 강건하게 대응할 수 있다. 레디스는 멀티 클라우드 전략에서 그 중요성을 발휘해, 여러 클라우드 환경에 걸쳐 일관된 성능과 기능을 제공함으로써 서비스의 연속성과 데이터의 일관성을 보장한다.
마이크로서비스 아키텍처와 레디스
레디스는 마이크로서비스 아키텍처에서 데이터 저장소 그 이상으로 활용될 수 있는 유연한 데이터베이스다.
데이터 저장소로서의 레디스
레디스는 마이크로서비스 아키텍처에서 각 서비스별 개별 저장소로 사용하기에 알맞다. 설치가 간편하고, 최소한의 리소스로 막대한 처리량을 낼 수 있으며, 다양한 자료 구조를 제공하면서도 사용이 간단하기 때문에 마이크로서비스의 요구 사항에 맞는 데이터를 저장하기에도 편하다. 또한 고가용성을 위해 로드 밸런서나 프록시 등 추가적인 서비스를 설치할 필요가 없어 하나의 저장소로서 역할을 수행하기에 충분하다.
메모리에 있는 데이터가 영구 저장되지 않기 때문에 데이터 저장소로 사용하기 위해 레디스의 도입을 고민할 때 데이터 영속성을 고민할 수 있으나, 레디스의 데이터는 AOF(Append Only File) 와 RDB(Redis DataBase) 형식으로 디스크에 주기적으로 저장할 수 있다. 레디스에 장애가 발생해 데이터가 유실되더라도 백업 파일을 이용하면 다시 복구할 수 있다.
메시지 브로커로서의 레디스
레디스는 NoSQL 데이터 저장소로 알려져 있기 때문에 단순하게 데이터를 저장할 수 있는 저장소로만 생각하기 쉽지만 사실 레디스는 서비스 간 메시지를 전달할 때 매우 유용하게 사용될 수 있다.
레디스의 pub/sub기능은 가장 간단한 메시징 기능으로, 굉장히 빠르게 동작하며 간단하게 사용할 수 있다. 1개의 채널에 데이터를 던지면 이 채널을 듣고 있는 모든 소비자는 데이터를 빠르게 가져갈 수 있다. pub/sub에서 모든 데이터는 전달된 뒤 삭제되는 일회성으로, 모든 메시징 상황에 적합하진 않지만 fire-and-forget 패턴이 필요한 간단한 알림 서비스에서는 유용하게 사용될 수 있다.
레디스의 list 자료 구조는 메시징 큐로 사용하기 알맞다. list에서 데이터는 빠르게 push/pop을 할 수 있으며, 애플리케이션은 list에 데이터가 있는지 매번 확인할 필요 없이 대기하다가 list에 새로운 데이터가 들어오면 읽어 갈 수 있는 블로킹 기능을 사용할 수 있다.
레디스의 stream 자료 구조를 이용하면 레디스를 완벽한 스트림 플랫폼으로 사용할 수 있다. stream은 아파치 카프카 시스템에서 영감을 받아 만들어진 자료 구조로, 데이터는 계속해서 추가되는 방식으로 저장된다.(append only). 카프카처럼 저장되는 데이터를 읽을 수 있는 소비자와 소비자 그룹이 존재해 데이터의 분산 처리도 가능하며, 저장된 데이터를 시간대별로 검색하는 것도 가능하다.