Session Storage? Redis : Memcached

Kereu_·2021년 12월 28일
1

Careers 프로젝트

목록 보기
4/4
post-thumbnail

앞선 포스팅에서 다루었던 다중 서버 환경 세션 불일치 문제 해결하기 위해서 별도의 세션 스토리지를 구성하여 세션의 정합성 문제를 해결하려고 할 때, 과연 세션 스토리지로 적합한 데이터베이스는 무엇이 있을까요?

우선 데이터베이스는 크게 SQL(RDB)와 NOSQL을 생각할 수 있습니다.

SQL(RDB)

  • Oracle Database
  • MySql
  • PostgreSQL
  • Microsoft SQL Server

NOSQL

  • MongoDB
  • Redis
  • HBase
  • Azure Cosmos DB

선택기준

비인가된 사용자 포함한 모든 사용자가 접근할 수 요청과 다르게 인가된 사용자만 접근할 수 있는 요청을 처리할 때는 매번 세션 저장소에서 해당 로그인 세션이 존재하는지 확인하는 작업을 진행해야 하므로 성능에 악영향을 주지 않도록 빠르게 세션 정보를 찾아서 제공해야 합니다.
즉 성능/응답속도를 선택에 최우선 조건 되어야 한다.

Disk based DB vs In-memory DB

그렇다면 세션 정보를 빠르게 제공해주기 위해서는 데이터베이스가 어디에 위치하고 데이터를 어디에 저장 하는것이 중요하게 됩니다.
저장 위치에 따라 In-memory DB와 Disk based DB로 분류됩니다.
전자는 데이터를 메모리에 저장하여 관리하고, 후자는 데이터를 디스크에 저장하여 관리합니다.

Disk based DB

먼저 Disk based DB의 접근 과정을 알아보자.
Disk based DB라고 해서 조회한 정보를 디스크에서 직접 찾는 것이 아닌 우선 메모리에 버퍼라는 임시 저장공간에서 저장된 데이터를 먼저 탐색 후 해당 데이터가 없을 때만 디스크에 저장된 데이터를 버퍼에 데이터를 페이지(블록) 단위로 읽어오는 방식이다.
이러한 방식을 사용하는 이유는 기본적으로 메모리 I/O 작업이 디스크 I/O 작업보다 약 10,000배 이상 속도로 빠르기 때문이다.

하지만 이러한 방식에도 디스크에서 데이터를 찾아 페이지 단위로 버퍼로 전송하는 시간이 발생하기 때문에 여러 I/O 작업 처리에서 병목 현상이 발생하게 된다.

그렇기 때문에 세션이 존재를 반복적으로 확인하는 작업이 필수적인 서비스에서는 세션 스토리지로 Disk based DB를 사용하는 것은 성능적인 측면에서 사용이 어렵다.

In-memory DB

In-memory DB는 Disk I/O 작업이 필요없이 모든 데이터를 메모리에 저장하기 때문에 디스크 기반의 데이터베이스에서 발생하는 병목 현상을 피할 수 있다.

그렇다면 병목없이 발생하지 않고 빠르니 무조건 적으로 disk-based DB보다 in-memory DB가 더 좋을까?

그건은 현재 사용하는 목적과 상황에 따라 다르다.

우선 in-memory DB는 기본적으로 영속성(persistence)을 보장하지 않는다.
에러를 통해 예상치 못하게 프로세스 종료가 된 경우, 현재 데이터가 모두 유실될 수도 있다.

그렇다면, session을 저장하는 저장소로는 적합할까?

세션은 HTTP의 비연결 지향(Connectionless)과 상태없음(Stateless)과 같은 특성을 보완하기 위해 사용하는 것이다. 세션에는 주로 로그인한 사용자의 정보를 저장하는데, 이 정보는 영원히 저장되어야 하는 정보가 아니다. 사용자가 로그아웃을 하거나 개발자가 설정해놓은 세션의 timeout에 따라서 세션이 제거된다.

세션에 저장되는 데이터의 위와같은 특성 덕분에 데이터 유실로 인해 발생하는 피해가 다른 데이터에 비해 적다.

그리고 In-memory DB는 세션 스토리지 서버에 문제로 인해 데이터 유실을 방지하기 위해 동일한 데이터를 또 다른 세션 스토리지에 복사하는 [마스터-슬레이브] 복제 방법을 사용하거나 'Consistent Hashing' 알고리즘을 사용하여 가용성을 보장하기도 한다.

따라서 세션 스토리지로 In-memory DB의 사용이 적절하다고 생각한다.

In-memory DB에는 다양한 데이터베이스들이 존재한다. 세션 저장소로 용도 가장 많이 사용하는Redis와 Memcached에 대해서 알아보십다.

Redis

Redis의 공식 웹사이트 에는 Redis가 '데이터베이스, 캐시 및 메시지 브로커로 사용되는 오픈 소스(BSD 라이선스), 인메모리 데이터 구조 저장소'라고 설명하고 있습니다.
이를 조금 확장하기 위해 Redis는 목록, 집합 및 해시와 같은 다양한 데이터 유형을 선택하여 키-값 쌍을 저장하는 방법입니다.

Memcached

Memcached의 웹사이트 는 Memcached를 ' 무료 및 오픈 소스, 고성능, 분산 메모리 개체 캐싱 시스템 '으로 설명합니다. Redis와 마찬가지로 Memcached는 키 값 쌍을 메모리에 저장하는 오픈 소스 방식이므로 데이터가 매우 빠르게 검색됩니다.

공통점

  • NoSQL 분류, In-memory-DB
  • Key - Value 형식에 데이터 스토리지 시스템
  • 1ms 이하의 응답속도
  • 오픈 소스
  • 광범위한 프로그래밍 언어 지원

차이점

Redis
  • 다양한 데이터 구조(List, Set, 정렬된 Set, Hash, Bit 배열, hyperloglogs 등)
  • RDB 스냅샷
  • 복제(마스터-슬레이브)
  • 설치 및 사용 쉽다.
  • Pub / Sub messaging
  • 루아 스크립트 지원
  • 위치기반 데이터 타입 지원
Memcached
  • 데이터를 문자열로만 저장
  • 멀티스레드 아키텍처(더 많은 코어와 메모리를 제공)

정리하기

위의 특징만 보면, Redis는 확실히 더 유연하고 강력하지만 Memcached는 일부 목적을 매우 잘 수행 하며 때에 따라 더 나은 성능을 보여줍니다.

즉 Memcached 또는 Redis 사용은 애플리케이션에 따라 다릅니다.

그렇다면 세션 저장소는 어떤 In-memory-DB를 결정하자면 저는 현재 프로젝트에서는 Redis를 사용하기로 하였습니다.

Redis를 사용하고자 하는 이유는 다음과 같습니다.
우선 spring으로 개발할 때 관련 의존성을 빌드하면 레디스를 간편하게 사용할 수 있도록 지원해 준다는 장점입니다.

그리고 또한 장애가 발생한 경우 Replication을 통한 간편한 서버 복구 기능을 통해 안정적인 서비스를 제공할 수 있다고 생각했기 때문입니다.

물론 그 이외에 다양한 데이터 구조 지원과 루아 스크립트 지원 등의 더 많은 기능이지만 현재 세션 저장소로 필요한 기능만 비교하고자 항목에서 제외하였습니다.

참고

마지막으로 Redis 사용시 주의점을 적어보면 좋을 것 같아 이렇게 정리하게 되었습니다.
Redis는 싱글 쓰레드이기 때문에 1번에 1개의 명령어만 실행할 수 있습니다.
한 서비스에서 요청된 명령어에 대한 작업이 끝나기 전까진 다른 서비스에서 요청하는 명령을 못 받아들입니다.
Keys(저장된 모든 키를 보여주는 명령어)나 flushall(모든 데이터 삭제) 등의 명령어를 사용할 때, 맴캐쉬드의 경우 1ms 정도 소요되지만, 레디스의 경우 100만 건의 데이터 기준 1초로 엄청난 속도 차이가 있습니다.

또한, RDB 작업(특정 간격마다 모든 데이터를 디스크에 저장)이 매우 오래 걸립니다. AWS, 60기가 메모리 기준으로 10분이나 소요됩니다. Redis 장애에 원인의 대부분이 해당 기능 때문에 발생하기 때문에 사용할 때 주의해야 합니다.

신뢰할 만한 사람들이 모인 공간에서 비즈니스 인맥을 만들고,
업무 스킬 및 트렌드 정보를 공유하는 Careerly를 모티브로 한 API 서버 프로젝트입니다.

참조


profile
Issue_Save

0개의 댓글