티스토리 뷰

4. 세션 스토리지로 어떤 것이 더 적합한가?2 - Redis VS Memcached

저번 글에서는 Disk Based Database와 In Memory Database, 두 가지 방식의 데이터베이스를 비교해보았고 내가 진행하

는 SNS 서비스 프로젝트에서는 빠른 요청 처리, 저장할 데이터인 세션의 특징 등의 이유로 인메모리 데이터베이스가 세

션 스토리지에 적합하다고 판단했다. 이제 마지막으로 인메모리 데이터베이스 중에서도 어떤 종류의 데이터베이스가 좋

을지 알아보도록 하자.

 

왜 사람들은 Redis와 Memcached를 선호할까?

구글 검색창에 Redis만 치면 Memcached가 자동 완성이 될 정도로 사람들은 이 두 데이터베이스를 놓고 어떤 것을 인메

모리 데이터베이스로 선택할 지 많이 고민한다. 이를 입증하든 AWS나 Azure 같은 서비스에서도 이를 위한 엔진으로

Redis와 Memcached를 지원하고 있다. 인메모리 데이터베이스 종류는 다양한데 Redis와 Memcached를 사람들이 유독

선호하는 이유는 무엇일까?

 

 

Redis와 Memcached는 인메모리 데이터베이스이면서 NoSQL의 한 종류이다. NoSQL은 다시 데이터를 어떤 구조로 저장

하느냐에 따라 Key-Value, Document, Graph 등으로 나뉘어진다. 그 중에서도 Redis와 Memcached가 속한 Key-Value

Store는 말 그대로 Key와 Value의 쌍으로 데이터가 저장되는 데이터베이스이다. 단순한 구조를 갖고 있어 일반적인 SQL

처럼 여러 테이블에 걸친 복잡한 연산을 수행할 수는 없지만, Key 하나로 데이터에 빠르게 접근 가능하기 때문에 일반적

으로 다른 유형의 NoSQL보다 읽기/쓰기를 빠르게 수행할 수 있다. 특히, 우리가 저장할 세션 데이터는 웹 어플리케이션의

매 기능마다 사용되는데도 주로 단순한 연산만 필요로 하기 때문에 다른 데이터베이스에 비하여 오버헤드가 적은 Key-

Value Store가 세션 스토리지로 많이 사용될 수 밖에 없는 것이다.

 

그 외에도 Redis와 Memcached가 가지고 있는 공통적인 장점은 다음과 같다.

 

  1. 데이터 파티셔닝이 가능하여 여러 노드에 데이터를 쉽게 분산시킬 수 있다.
  2. 문법적으로 복잡하지 않고 개발코드 양 또한 적어 개발이 용이하다.
  3. Java, Python, C, C++, C#, JavaScript, Node.Js, Ruby 등 다양한 언어에서 Redis나 memcached의 client를 지원한다.

 

그리고 Redis와 Memcached의 차이점을 간단하게 표로 정리하면 다음과 같다.

  Memcached Redis
다양한 데이터 타입 X O
멀티 스레드 아키텍처 O X
스냅샷 X O
복제 X O
트랜잭션 X O
Pub / Sub X O
Lua Scripting X O
지리 데이터 관련 지원 X O

 

해당 표에 나온 주요 차이점들을 하나씩 자세하게 살펴보도록 하자.

 

Memcached

Memcached는 Redis와 비교했을 때 메모리 관리 측면에서 효율적이다. Memcached는 데이터 별로 메모리를 할당하는 대

slab allocator 을 사용한다.

 

 

slab 은 일종의 메모리 할당 단위로 이는 다시 일정한 크기의 메모리인 여러 개의chunk 로 이루어져있다. Memcached에 데이터를 저장할 경우 먼저 저장하려는 데이터 크기보다 같거나 큰 chunk 를 가진 slab 이 있는지 찾는다. 만약 적합한 slab 이 있으면 이를 반환하고 그렇지 않으면 특정 크기의 chunk 로 구성된 새 slab 을 생성한다. 이렇게 사용가능한 메모리를 미리 할당해 두고 사용하기 때문에 Redis의 jemalloc 알고리즘보다 빠른 할당이 가능하며, 메모리 단편화를 방지할 수 있다.

 

 

하지만 Memcached의 메모리 관리 효율성은 데이터 크기가 동적일 때 빠르게 감소한다. 데이터의 크기가 달라지면 해당

데이터가 저장된 chunk 의 크기가 변하는 것이 아니라 데이터를 다시 적합한 크기의 chunk를 가진 slab으로 재할당되

기 때문이다. 또한 기존에 만들어진 chunk 에 데이터를 저장하는데 활용되지 못한다면 많은 메모리가 낭비 될 수 있다.

 

 

Memcached는 멀티 스레드를 지원하기 때문에 쉽게 확장하여 더 많은 작업을 처리 할 수 있다. 그러나 Replication을 지원

하지 않는다. 대신 Consistent Hashing 모델에 따라 캐시 데이터를 저장하기 때문에 분산 서버에서는 데이터 손실을 최

소화할 수 있다. Consistent Hashing 이란 데이터를 노드의 수에 따라 균등하게 분배하여 저장하는 것이다. 보통의

Hashing 알고리즘은 서버에 장애 발생으로 인해 서버의 수가 달라졌을 때 모든 데이터들을 달라진 서버의 수에 맞게 재분

배해야한다. 이는 대량의 캐시 데이터 유실로 이어질 수가 있다. 그러나 Consistent Hashing 알고리즘은 장애가 발생한

서버의 데이터만 유실되고 나머지 서버들은 데이터를 그대로 유지한 채 운영할 수 있다. 또한 서버의 수를 늘린다면 서버

한 대당 저장하는 데이터가 줄어들기 때문에 피해를 줄일 수 있다.

 

 

이러한 특징들로 Memcached는 다음과 같은 경우에 사용하기를 권장한다.

 

  • 가능한 가장 단순한 모델이 필요한 경우
  • 여러 코어 또는 스레드가 있는 큰 노드를 실행해야 하는 경우
  • 시스템의 요구 사항이 증가하고 감소함에 따라 노드를 추가 및 제거하는 확장 및 축소 기능이 필요한 경우

 

Redis

가장 먼저 눈에 띄는 차이점은 문자열만 지원하는 Memcached와 달리 Redis는 문자열, List, Set, Sorted Sed 등 다양한 데

이터 타입을 지원한다는 것이다. 하지만 이 점은 Redis를 캐싱 솔루션으로 사용할 때 발휘하는 장점이라고 생각하기 때문

에 중점적으로 다루지 않을 계획이다.

 

 

Redis는 장애 발생시 이로 인한 영향을 최소화하는데 강점을 가지고 있다. 그 중 하나로 Redis는 디스크에 데이터를 저장

하여 데이터를 지속적으로 보존할 수 있다는 점이다. 디스크에 데이터를 기록하는 방법은 스냅샷과 AOF, 두 가지가 있다.

스냅샷은 사용자가 설정한 특정 시간 조건을 만족할 때 메모리상에 저장되어 있는 모든 데이터에 대해서 복사본을 만들어

저장되는 파일이다. 스냅샷에 저장된 Key-Value들을 읽어 메모리에 저장하는 방식으로 복구 작업이 진행된다. 반면 AOF

파일은 Redis가 수신한 명령 중 메모리 내부 데이터에 수정이 이루어진 명령이 기록된 파일이다. AOF 파일에 기록된 로그

를 순차적으로 읽으면서 초기화된 데이터베이스에 명령어를 재실행하는 방법으로 복구 작업이 수행된다. 이러한 옵션들

은 서버 오류로 인해 강제로 종료되더라도 데이터 손실없이 다시 복구시킬 수 있다. 그러나 디스크에 기록하는 연산을 추

가로 수행해야하기 때문에 성능이 저하되는 요인이 될 수 있다.

 

 

다른 하나는 Redis가 Replication을 지원한다는 점이다. 마스터 / 슬레이브 Replication을 설정하면 마스터로부터 전체 데

이터베이스의 초기 복사본을 받게 된다. 마스터에서 쓰기 작업이 수행되면 스냅샷과 쓰기 명령 로그를 마스터와 연결된

모든 슬레이브로 전송하고 슬레이브는 기존의 데이터를 지우고 전송된 덤프 파일을 로드한다. 이와 같은 복제 프로세스를

통해 마스터와 슬레이브 간 데이터를 실시간으로 동기화할 수 있다. 문제가 발생하여 이에 대한 처리를 해야하거나 혹은

읽기 전용 서버를 두어야 하는 등의 상황에서 마스터 / 슬레이브 Replication을 설정하면 읽기 성능과 가용성을 향상시킬

수 있다.

 

 

이러한 특징들로 Redis는 다음과 같은 경우에 사용하기를 권장한다.

 

  • 복잡한 데이터 구조가 필요한 경우
  • 데이터를 정렬하거나 순위를 지정해야 하는 경우
  • 저장소의 지속성을 원할 경우
  • 기본 항목에서 하나 이상의 읽기 전용 복제본으로 데이터를 복제해야 하는 경우
  • 기본 노드가 실패할 때 자동 장애 조치가 필요한 경우
  • 백업 및 복원 기능이 필요한 경우

 

어떤 것을 선택하는 것이 좋을까?

Redis와 Memcached의 성능 차이는 미미하다. 두 가지 모두 각자 장단점이 있기 때문에 단순히 이게 무조건 더 좋다라고

할 수 없으며 자신이 개발하고 있는 상황을 고려하여 더 적합한 인메모리 데이터베이스를 선택해야한다. 내가 진행하고

있는 sns 개발 프로젝트와 이에 대한 개발 환경을 고려하였을 때 다음과 같은 이유로 Redis를 선택했다.

 

  1. Redis가 Memcached에 비해 다양한 기능을 제공한다.

    : 애초에 Redis는 Memcached의 단점을 개선하여 만들어진 데이터베이스이다. 그렇기 때문에 Memcached에 비해 어플리케이션 운영에서 유용하게 쓰일 수 있는 편리한 기능들을 많이 제공한다. 특히, 이전 글에서 언급한 것처럼 SNS는 서비스가 중단되면 타격이 크기 때문에 자체 솔루션으로 쉽게 복구가 가능한 Redis를 사용하는 것이 유리하다고 생각한다.

  2. Spring Boot에서 Redis를 위한 API를 지원한다.

    : 현재 내가 진행하고 있는 프로젝트는 Spring Boot 프레임워크 위에서 개발하고 있다. Spring Boot에서는 Redis API를 지원하기 때문에 아무래도 Memcached를 사용하는 것보다는 Redis를 사용하는 것이 편리하게 개발할 수 있고 이에 따른 유지 보수성도 좋아질 것으로 생각한다.

 

따라서 Redis를 세션 스토리지로 선택하여 트래픽이 늘어나더라도 쉽게 확장할 수 있으면서도 세션을 효율적으로 처리할

수 있는 분산 처리 환경을 구성할 수 있게 되었다.

 

 


 

진행 프로젝트

github.com/f-lab-edu/sns-itda

 

f-lab-edu/sns-itda

Contribute to f-lab-edu/sns-itda development by creating an account on GitHub.

github.com

 

이어지는 글

chagokx2.tistory.com/92

 

분산 처리 환경에서 대용량 트래픽을 견디기 위한 로그인 기능 구현-1. 서버를 어떻게 확장시킬 �

1. 서버를 어떻게 확장시킬 것인가? - Scale Up VS Scale Out 만약에 내가 만든 이 서비스가 엄청 잘 돼서 사용자 수가 폭발적으로 늘어나고 이 많은 사람들이 동시에 접속한다면 서버 하나로 버틸 수 ��

chagokx2.tistory.com

 

chagokx2.tistory.com/93

 

분산 처리 환경에서 대용량 트래픽을 견디기 위한 로그인 기능 구현-2. 여러 대의 서버에 흩어져

2. 여러 대의 서버에 흩어져 있는 세션을 어떻게 관리할 수 있을까? 저번 글에서는 서버의 성능을 향상시킬 수 있는 두 가지 방법, Scale Up과 Scale Out에 대해 알아보았다. 각기 다른 장단 점이 있었�

chagokx2.tistory.com

 

chagokx2.tistory.com/94

 

분산 처리 환경에서 대용량 트래픽을 견디기 위한 로그인 기능 구현-3. 세션 스토리지로 어떤 것�

3. 세션 스토리지로 어떤 것이 더 적합한가? - Disk Based Database VS In Memory Database 저번 글에서는 Scale Out의 데이터 불일치 문제를 해결하기 위한 Sticky Session, Session Clustering, 세션 스토리지..

chagokx2.tistory.com

 

댓글