[CS Study] Database - Redis

Frye 'de Bacon·2023년 12월 12일
0

Computer Science(CS)

목록 보기
28/40

Redis

Redis의 개요

Redis는 REmote DIctionary Server의 약어로, 이름에서 알 수 있듯 Key-Value 형태의 딕셔너리 구조로 데이터를 저장하고 관리하는 서버를 말한다. Redis 공식 홈페이지에서는 Redis의 핵심 기능을 다음과 같이 설명한다.

Redis는 데이터베이스, 캐시, 메시지 브로커 및 스트리밍 엔진으로 사용되는 오픈소스(BSD 라이선스), 인메모리 데이터 구조 저장소입니다.

Redis는 문자열, 해시, 목록, 집합, 범위 쿼리가 있는 정렬된 집합, 비트맵, 하이퍼로그 로그, 지리 공간 인덱스 및 스트림과 같은 컬렉션을 제공합니다.

Redis에는 복제, Lua 스크립팅, LRU 축출, 트랜잭션 및 다양한 수준의 디스크 지속성이 내장되어 있으며 고가용성을 제공합니다.

Redis Sentinel 및 Redis 클러스터를 통한 자동 파티셔닝을 제공합니다.

여기서 주로 살펴봐야 할 것은 캐시와 인메모리 데이터 저장소, 컬렉션 등이 될 것이다. 우선 인메모리라는 개념부터 살펴보자.

In-memory

인메모리란 컴퓨터의 주기억장치인 메인 메모리(Memory)에 데이터를 적재하여 서용하는 방법을 말한다. 앞서 OS에 대한 포스트들에서도 살펴봤지만, 보조기억장치가 발전했다고는 해도 여전히 메인 메모리에 비해서는 속도가 느릴 수밖에 없다. 따라서 OS도 프로그램을 실행할 때 메모리를 활용하여 실행 속도를 증가시키고, 이를 위해 문맥 교환이나 페이징 등 다양한 기법들을 활용하고 있다.

즉, Redis가 인메모리 데이터 저장소라는 것은 HDD, SSD 등의 보조기억장치를 데이터 저장소로 활용하는 다른 DMBS들과 달리 Redis는 데이터를 주기억장치인 메모리에 저장하며, 따라서 데이터를 다루는 속도가 수백배 이상 빠르다. 따라서 Redis는 빠른 속도를 큰 강점으로 한다.

그러나 메모리는 휘발성이며, 따라서 서버에 문제가 발생하여 프로세스가 종료되는 등의 일이 생긴다면 데이터는 모두 사라질 것이다. 데이터가 사라지는 데이터베이스는 어불성설이며, 따라서 Redis는 데이터의 영속성을 확보하기 위한 몇 가지 솔루션도 제공하고 있다.


Redis의 영속성(Persistence)

Redis에서 데이터를 영구적으로 저장하는 방법으로 크게 Snapshot 방식과 AOF 방식 두 가지를 제공하고 있다.

Snapshot

인메모리 데이터를 주기적으로 파일로 저장하여 Redis가 장애로 종료되더라도 해당 파일을 로드하여 이전의 상태를 복구하는 방법이다. 메모리 전체를 그대로 디스크에 저장하므로 프로세스가 재시작되더라도 해당 파일을 불러오는 것만으로도 메모리의 복구가 가능한 편리한 방법이다. 일반적으로 Redis는 .rdb 파일에 인메모리 데이터를 저장하도록 디폴트로 설정되어 있다.

그러나 이 방식은 몇 가지 단점이 있는데, 우선 snapshot을 추출하는 데 꽤 긴 시간이 걸린다는 점이다. 그리고 다른 하나는 일정 시점마다 rdb 파일을 생성하므로 해당 rdb 파일 생성 이후의 데이터에 대해서는 복구가 불가능하다는 것이다.

Append Only File(AOF)

AOF 방식은 Redis의 모든 연산(단순 조회를 제외한 write, update, delete 등의 연산) 자체를 모두 log 파일에 기록하는 것이다. 그리고 서버 프로세스가 재시작되면 해당 log 파일에 기록된 연산들을 재실행하는 형태로 데이터를 복구한다. 즉, 다음과 같은 형태로 데이터를 저장한다.

  1. 클라이언트가 Redis에 명령을 요청한다.
  2. Redis는 해당 명령을 aof 파일에 저장한다.
  3. 로그의 저장이 완료되면 Redis는 실제로 해당 명령을 수행하고 메모리의 내용을 변경한다.

AOF 방식은 operation이 발생할 때마다 해당 연산을 log 파일에 기록하므로 항상 현재 시점까지의 데이터를 보존할 수 있으며, log 파일만 수정하기 때문에 데이터의 백업 속도도 빠르다. 또한 AOF 파일은 기본적으로 text 파일이므로 편집이 가능하다는 장점도 있다.

그러나 모든 연산을 log 파일에 남기므로 log 데이터의 양이 굉장히 많고, 복구 시 저장된 연산들을 모두 다시 실행하기 때문에 데이터의 복구에 시간이 오래 걸린다는 단점이 있다. 이를 보완하기 위하여 특정 시점마다 데이터를 모두 지우고 최종 데이터만 기록하는 rewrite 기능을 제공한다.

일반적으로는 Snapshot 방식으로 주기적인 데이터 백업을 실시하고, Snapshot과 다음 Snapshot 사이의 데이터를 AOF 방식으로 저장하는 방식을 많이 사용한다. 데이터의 유실 방지와 서버 프로세스 재시작 속도 제고를 모두 확보하는 것이다.


Cache

Redis는 데이터를 영속적으로 저장하기 위한 방법들을 제공하지만, 인메모리 방식 자체가 데이터를 '빠르게' 가져오는 것이 목적인 만큼 일반적인 데이터베이스로서 Redis를 활용하는 것은 썩 적절하지 않은 방법일 수 있다. 실제로 Redis를 가장 많이 사용하는 방식 중 하나는 캐싱 서버로 활용하는 방법이다.

앞서 캐시 메모리 포스트에서 살펴보았듯, 캐시는 자주 사용되는 데이터로서 캐시 메모리에 저장되는 데이터를 말한다. 매번 보조기억장치에서 데이터를 가져오는 것은 속도 면에서나 장치의 부하 면에서나 문제가 발생할 수 있으므로 자주 사용되는 데이터를 캐시 메모리에 얹어 빠르게 가져오는 개념이다.

서버에서의 캐싱 서버 역시 마찬가지로 이해할 수 있다. 규모가 작거나 사용자가 많지 않다면 Web - WAS - DB의 구조로도 서비스를 운영할 수 있지만, 사용자가 늘어나거나 데이터가 커진다면 데이터를 가져오기 위해 매번 DB에 접근하는 것이 DB에 과부하를 일으킬 수 있다. 이때 캐싱 서버를 도입하여 자주 사용되는 데이터를 캐싱 서버에 저장함으로써 DB의 부하를 줄이는 것이다. 그리고 이때 많이 사용되는 것이 바로 Redis이다.

Redis에서 사용하는 캐시의 구조는 크게 두 가지로 나눌 수 있다.

Look aside cache

Look aside cache는 캐시에 접근하여 데이터가 존재하는지 확인하고, 없을 경우 DB 혹은 API를 호출하는 방식이다. 일반적으로 캐시를 사용하는 개발이 이 프로세스를 따르고 있다.

  1. WEB 서버에서 필요한 데이터가 Cache에 존재하는지 먼저 확인한다.
  2. Cache에 데이터가 있다면 가져온다.
  3. Cache에 데이터가 없을 경우 DB에서 데이터를 가져온다.
  4. 3에서 가져온 데이터를 Cache에 저장한다.

Write back

Write back은 Looak aside cache와 달리 데이터를 쓰거나 업데이트할 때 사용할 수 있는 방식이다. 클라이언트가 추가한 데이터를 바로 DB에 저장하는 것이 아니라 일정 시간 동안 캐시에 모아 두었다가 주기적으로 DB에 반영하는 방식이다. 이 경우 매번 DB에 데이터를 저장하는 것보다 속도 면에서 이득을 볼 수 있다. 단, 장애가 발생하여 서버 프로세스가 재시작될 경우 캐시에 저장되어 있던 데이터는 유실된다는 단점이 있다.

이 방식은 로그 등을 DB에 자주 저장할 때 주로 사용되는 방식이다.


Redis의 자료 구조

이번에는 Redis의 특징 중 두 번째 항목을 자세히 살펴보자.

Redis는 문자열, 해시, 목록, 집합, 범위 쿼리가 있는 정렬된 집합, 비트맵, 하이퍼로그 로그, 지리 공간 인덱스 및 스트림과 같은 컬렉션을 제공합니다.

기본적으로 Redis는 Key-Value 형태의 자료 구조로 구성된다. 즉, 키 하나에 데이터형 하나가 저장되는 단순한 구조이다. 이는 직관적이며 사용이 쉽다는 장점이 있지만, 저장된 데이터를 가공하는 데는 제한이 있다는 단점이 있다. Redis는 다양한 종류의 데이터형과 명령들을 제공함으로써 이를 보완하고 있다.

문자열(Strings)

문자열 타입은 Redis의 가장 기본적인 데이터형으로, Key-value 형식을 따르고 있다. 키와 밸류에는 어떤 데이터형도 매치될 수 있다.

리스트(Lists)

리스트 타입은 Linked list와 유사한 형태이며, 따라서 Head와 Tail에서 데이터를 추가/삭제/조회하는 것은 O(1)의 속도를 가지지만 중간의 특정 index를 조회할 때는 O(N)의 속도를 가지는 단점을 동일하게 가지고 있다. 따라서 Queue의 형태로 사용하는 것이 적합하다.

셋(Sets)

셋 타입은 순서가 보장되지 않는 문자열의 집합 자료 구조이다. 중복을 허용하지 않으며, 추가/삭제/조회 등에 대해 O(1)의 속도를 보장한다. 팔로워 리스트나 친구 리스트 등 특정 그룹의 데이터를 저장할 때 적절하다.

정렬 셋(Sorted sets)

셋 타입의 자료 구조에 Score를 추가로 기록하여 Score가 낮은 데이터부터 오름차순으로 정렬되는 자료 구조이다. Sets 구조이므로 마찬가지로 중복이 허용되지 않으나, Score는 동일할 수 있다. 랭킹을 나타내는 데이터에 적합하다.

해시(Hash)

해시 타입은 value로 또 다른 key(field)-value 맵을 가지는 자료 구조이다. 필드는 문자열로 구성되며, 어떤 데이터들을 특정한 분류로 묶을 때 유용한 자료 구조이다.


Redis 운영 시의 주의 사항

메모리 관리

Redis는 메모리에 데이터를 적재하기 때문에 메모리 관리가 매우 중요하다. 메모리의 용량을 넘어서는 크기의 데이터를 처리할 경우 Swap을 사용하는데, Swap 사용 시에는 보조 기억 장치에 데이터를 저장하거나 로드해야 하므로 지연(Latency)이 발생할 수 있다.

또한 메모리를 사용하는 만큼 메모리의 파편화 문제도 발생할 수 있다. 따라서 이를 해결하기 위한 방안들도 함께 고려해야 한다.

덧붙여 휘발성을 갖는 메모리의 특성상 서버 장애 발생 시 데이터 유실 등의 위험이 있으므로 이에 대한 플랜이 반드시 필요하다.

O(N)의 명령어 사용 자제

Redis의 중요 특징 중 하나가 싱글 쓰레드라는 것이다. 즉, Redis는 한 번에 하나의 명령어만을 처리할 수 있으며, 따라서 시간이 오래 걸리는 명령어를 사용할 경우 그 명령어를 처리하는 동안 다른 명령어를 처리하지 못해 전체적인 동작이 느려질 수 있다. 따라서 시간이 오래 걸리는 요청이나 명령은 가능한 사용하지 않는 것이 좋다.


CAP

Redis의 주요 특징 중 한 가지는 Consistent hashing 또는 Master-Slave 형태로서 여러 대의 서버를 구성할 수 있어 분산 처리가 가능하다는 것이다. 그리고 분산 컴퓨팅 시스템을 설명하는 주요 이론 중 하나가 바로 CAP 이론이다.

CAP 이론은 Consistency, Availability, Partition Tolerance를 동시에 지원하는 분산 시스템은 없으며, 이 중 두 가지만을 선택적으로 만족시킬 수 있다는 이론이다.

예를 들어 현재 가장 많이 사용되는 RDBMS는 일관성(Consistency)과 가용성(Availability)을 만족시키는 CA에 해당하고, Redis는 일관성과 분할 허용성(Partition tolerance)을 만족시키는 CP에 해당한다.

그러면 이 세 가지 속성에 대해 자세히 살펴보자.

일관성(Consistency)

일관성은 동시성 또는 동일성이라고도 하며, 다중 클라이언트에서 같은 시간에 조회하는 데이터는 항상 동일한 데이터임을 보증하는 것을 의미한다. 즉, 모든 읽기에 대하여 DB 노드가 항상 동일한 데이터를 가지고 있어야 한다는 것이다.
RDBMS의 경우 일관성을 기본적으로 지원하지만, NoSQL의 경우 빠른 분산 처리를 위해 일관성이 희생되는 경우도 있다.
트랜잭션의 ACID 원리에서 의미하는 일관성과 동일하며, 따라서 어떤 DB 속성에 C가 있다면 해당 DB는 트랜잭션 혹은 그와 비슷한 매커니즘이 존재한다는 의미가 된다.

가용성(Availability)

가용성은 모든 클라이언트의 읽기와 쓰기 요청에 대하여 항상 응답이 가능한 것을 보증하는 것으로, 따라서 내고장성이라고도 한다. 가용성을 가진 NoSQL은 클러스터 내에서 몇 개의 노드가 망가지더라도 정상적인 서비스가 가능하다.
몇몇 NoSQL은 가용성 보장을 위해 데이터 복제를 사용하는데, 데이터를 중복 저장하는 방법으로는 동일한 데이터를 가진 저장소를 하나 더 생성하는 Master-Slave 방식과 데이터를 데이터 단위로 중복 저장하는 Peer-to-Peer 복제 방법이 있다.

분할 허용성(Partition tolerance)

분할 허용성은 지역적으로 분할된 네트워크 환경에서 동작하는 시스템에서 두 지역 간 네트워크가 단절되거나 네트워크 데이터의 유실이 일어나더라도각 지역 내의 시스템은 정상적으로 동작해야 한다는 것을 의미한다.

참고로 CAP 이론의 등장 이후 시간이 지남에 따라 그 한계를 드러냈으며, 이를 보완하기 위하여 PACELC 이론이 등장하였다. 이는 이후 별도로 다루어 볼 것이다.


참고 자료

profile
AI, NLP, Data analysis로 나아가고자 하는 개발자 지망생

0개의 댓글