인메모리 DB의 필요성
성능 개선을 위한 방법 중 하나로 인메모리 DB를 많이 사용합니다. 전체 서비스 흐름에서 데이터 입출력이 차지하는 비중을 생각해보면, 인메모리 DB의 필요성은 더욱 커질 수밖에 없습니다. 인메모리 DB는 데이터를 디스크 대신 메모리에 저장함으로써 I/O 성능을 수십 배에서 수백 배까지 끌어올립니다. 다만 메모리 특성상 데이터의 영구성이 보장되지 않기 때문에 필요에 따라 적절한 백업 시스템을 구축해야 합니다.
인메모리 DB 서버를 구축하기 위한 오픈소스로는 주로 Redis와 MemCached가 사용되고 있습니다. AWS의 캐시 서비스인 ElastiCache도 Redis용과 MemCached용으로 제공됩니다. 보통은 MemCached보다 다양한 기능이 지원되는 Redis를 사용하는 경우가 많으며, 각 서비스마다 안정성과 비용 등을 고려하여 ElastiCache 관리형 서버와 EC2 설치형 서버를 선택하여 사용합니다.
Redis 서버 구축 시 고려사항
Redis 서버를 구축할 때 우선순위로 고려해야 할 내용은 아래 그림과 같이 세 가지로 분류할 수 있습니다. 이 세 가지는 Redis 구성의 핵심이라고 할 수 있습니다.
1. 데이터 관리
서두에 언급했듯이 인메모리 DB를 사용하는 이유는 데이터 I/O 성능을 극대화하기 위함입니다. 그렇다면 무슨 데이터를, 어떻게 사용하고 싶기 때문일까요? 여기서 데이터 관리에 대한 고민을 하게 됩니다.
Redis 서버를 구축하기로 결정했다면 데이터 관리 방식을 결정해야 합니다. 데이터 관리 방식은 크게 두 가지로 나누어 생각할 수 있습니다. 첫 번째는 데이터 캐싱 전략이고, 두 번째는 데이터 백업 여부입니다.
- 데이터 읽기/쓰기는 어떻게?
Redis 서버의 사용 목적이 분명하게 정의되고, 그에 따라 어떤 데이터를 읽고 쓸지 명확해지면 캐싱 전략을 선택할 수 있습니다. 캐싱 전략은 크게 Cache Aside, Read Through, Write Back, Write Through 등 4가지로 구분하는데, 보통 읽기와 쓰기 패턴을 고려하여 4가지 전략 중 한 가지를 택하거나 2가지 이상의 전략을 결합하여 사용합니다.
- 데이터 백업이 필요한가?
앞서 언급한 것처럼 데이터를 메모리에 저장하면 입출력 성능이 급격하게 증가하지만 영속성은 보장되지 않습니다. 이러한 데이터 휘발성을 보완하기 위해 Redis에서는 MemCached와 달리 RDB(Redis Database)와 AOF(Append Only File)라는 백업 옵션을 지원합니다.
RDB는 특정 시점에 메모리에 저장된 전체 데이터를 바이너리 파일로 저장하는 방식이며, AOF는 데이터 변경이 있을 때마다 별도의 파일에 해당 내용을 추가하는 방식입니다. 메모리 상의 데이터를 백업해야 한다면 RDB와 AOF 중에 각각이 전체 성능에 미치게 될 영향을 고려하여 적절한 옵션을 선택해야 합니다. Redis 서버에 저장하는 데이터의 중요도가 낮다고 판단될 경우 RDB나 AOF와 같은 별도의 백업 옵션은 신경쓰지 않을 수도 있습니다.
2. 스탠드얼론 vs 센티널 vs 클러스터
Redis에서 사용할 수 있는 모드는 스탠드얼론, 센티널, 클러스터 등 3가지로 분류합니다. 세 가지 모드의 특징은 아래와 같이 구분할 수 있습니다.
위의 표에서 볼 수 있듯이 스탠드얼론 모드의 경우 마스터 1대만 운영하기 때문에 가용성, 이중화, 샤딩 기능이 모두 지원되지 않습니다. 따라서 해당 서비스가 기능하는 데 필요한 데이터가 많지 않고 서버 장애 시 서비스에 대한 영향이 크지 않은 경우에 선택합니다. 센티널 모드의 경우 마스터, 슬레이브와 함께 센티널 노드를 설치합니다. 센티널 노드는 마스터 노드를 감시하고 있다가 장애가 발생하면 슬레이브를 마스터로 승격시켜 가용성을 보장합니다.
클러스터 모드는 센티널 모드에서 더 나아가 데이터 규모가 커질 경우 샤딩 기능까지 지원하는 모드입니다. 클러스터 모드에서는 모든 데이터가 16,384개의 해시슬롯으로 나누어 저장됩니다. 이 해시슬롯은 마스터 노드를 자유롭게 이동할 수 있기 때문에 쉽게 확장할 수 있습니다. 또한 TCP 연결을 통해 모든 노드가 연결되어 서로 장애를 감지하기 때문에 센티널 노드가 별도로 필요하지 않습니다. 클러스터 모드는 사실상 센티널 모드의 업그레이드 버전이기 때문에 요즘은 센티널 모드를 사용하지 않는 추세입니다.
자주 사용되는 클러스터 구성 방식으로 아래 그림과 같은 방식이 있습니다. 즉 마스터와 슬레이브를 1대1로 구성하여 인스턴스 1대에 마스터와 슬레이브를 1개씩 설치하는 것입니다. 마스터와 슬레이브의 배치는 순차적으로 물리도록 구성합니다. 첫 번째 인스턴스에 있는 마스터를 두 번째 인스턴스의 슬레이브에서 복제하고, 마지막 인스턴스에 마스터를 첫 번째 인스턴스에 있는 슬레이브가 복제하는 방식입니다.
이와 같이 구성할 경우 각 노드의 maxmemory를 설정할 때는 인스턴스 1대에 2대의 노드가 작동한다는 점 등을 고려하여 인스턴스 타입에 따라 30~40%로 여유 있게 설정하는 것이 좋습니다. 인스턴스 타입을 선택할 때에도 메모리 최적화 인스턴스를 선택하는 것이 바람직합니다.
3. 관리형 vs 설치형
Redis 서버 아키텍처가 구성되었다면 호스팅 방식을 선택해야 합니다. 클라우드 플랫폼에서 제공하는 완전 관리형 서버를 운영할 것인가, 처음부터 끝까지 직접 관리하는 자체 호스팅 서버를 운영할 것인가. 이런 문제는 언제나 많은 고민 거리를 안겨줍니다. 고려할 것이 매우 많지만, 정답이 없기 때문이지요.
관리형 Redis 서버의 대표적인 케이스인 ElastiCache와 EC2 설치형 서버를 기준으로 관리형과 설치형의 장단점을 아래와 같이 구분해봤습니다.
표의 내용을 종합해보면 관리형이냐 설치형이냐를 선택하기 위한 고려사항은 크게 ‘비용’과 ‘관리 효율’로 나누어 생각해볼 수 있을 것 같습니다. 즉 비용을 높이는 대신 관리 효율을 높일 것이냐, 그 반대를 택할 것이냐의 문제로 귀결된다고 할 수 있습니다.
마치며
위에서 다룬 굵직한 내용들에 대해 어느 정도 결정이 되었다면 데이터 구조, 네트워크 설정, 메모리 관리 방식, 보안 설정 등 세부적인 설정으로 들어갈 수 있습니다. 기회가 된다면 이 부분에 대해서도 차후에 다뤄볼 계획입니다. Redis 서버 구축에 대한 감을 잡으시는 데 오늘의 글이 도움이 되었길 바랍니다.