본문 바로가기
프로젝트/Careers

Session Storage 선택과정

by 에어컨조아 2021. 7. 29.

Storage라 하면 크게 SQL, NoSQL을 생각해볼 수 있습니다.

SQL databases

  • Db2
  • MySQL
  • PostgreSQL
  • Oracle Database
  • Microsoft SQL Server

NoSQL databases

  • Redis
  • MongoDB
  • Elasticsearch
  • Memcached

하지만 Session을 저장하기위해 사용하는 부분인 만큼 빠른 응답속도가 뒷받침되어야 했습니다. 여기서 잠깐 정리하자면 왜 빨라야 할까요?

현재 제가 토이 프로젝트로 진행하고있는 Careers에서는 로그인 세션을 저장하고 관리할 Storage를 찾고 있습니다.

당연히 서비스를 이용하기 위해서는 로그인을 한 상태여야 하며, 이는 서버가 모든 요청이 들어올 때 마다 Session Storage에 가서 Set-Cookie에 들어있는 세션정보랑 일치하는지 비교해야 한다는 것을 뜻합니다.

일반적으로 사용하고 있는 Mysql, MongoDB 등은 영속성을 지원하기위해 HDD 에 데이터를 보관합니다. 즉 Mysql, MongoDB를 사용하면 모든 요청마다 아래 순서대로 동작합니다.

  1. WAS가 DBMS에게 쿼리전송
  2. DBMS는 운영체제에게 데이터 요청
  3. 운영체제는 HDD에서 요청한 데이터를 수신
  4. 운영체제가 수신된 데이터를 DBMS → WAS 순으로 전달

여기서 Disk I/O가 발생하게되며, 이는 곳 엄청난 성능저하를 발생시키는 주범이됩니다.

그렇다고 세션을 저장하지 않을 수도 없으니 Memory에 저장하게 되면 Disk I/O보다 훨씬 더 빠르기 때문에 In-Memory 기반의 DB들로 결정하게 되었습니다.

그런데 In-Memory기반이면 휘발성 아닌가? 🤔

맞습니다. 기본적으로는 In-Memory기반 DB들은 시스템이 재부팅 되거나, 오류가 나서 프로세스가 종료가 된다면 저장하고 있던 데이터들이 모두 사라지게 됩니다.

하지만 무엇을 저장하느냐에 따라 해당 문제가 크리티컬 할지 아니면 크게 문제가 없는지 판단할 수 있습니다.

현재 저장할 데이터는 세션입니다. 세션 데이터 특성상 영속성을 지원하면 좋긴 하지만 그렇다고 무조건 지원해 줘야 하는 데이터는 아닙니다. 그 이유는 세션 데이터는 사용자가 로그아웃을 통해서 세션 삭제를 요청할 수도 있습니다. 또한 Session Timeout에 걸려서 세션 데이터가 삭제될 수 있기 때문입니다.

그래서 최종적으로 In-Memory기반의 DB들을 사용하기로 결정하였습니다. 🔨

Redis vs Memcached

그래서 Session storage로 둘 중 하나를 사용하기로 결정 하였습니다.

우선 이 둘의 차이점을 확인해 보고 장단점을 비교한 뒤 가장 적합한 스토리지를 선택하기로 생각했습니다.

아마존에서 두 스토리지 비교에 대해서 표로 잘 정리되어 있어서 해당 부분을 참고하여 차이점에 대해서 정리한 후 결정을 하면 되겠다 생각했습니다.

해당 표를 보시면 Redis는 기본적으로 Single Thread 구조로 동작하기 때문에 이 부분만 지원하지 않고 나머지 기능들은 모두 지원하는 것으로 확인했습니다.

얼핏 보면은 더 많이 지원해 주는 Redis를 사용하는 것이 더 좋을 것 같았지만 해당 프로젝트에 반영하기엔 과할지도 모른다는 생각으로 몇몇 기능들을 뽑아서 비교해 보았습니다.

Advanced data structures

Redis, Memcached 모두 기본적으로 Key-value 방식의 저장소 입니다.

Memcached는 key-value 둘 다 String으로 지원합니다.

Redis에서는 좀 더 다양한 자료구조(lists, sets, sorted sets, hashes, bit arrays 등) 타입으로 제공해 줍니다.

Multithreaded architecture

Redis는 기본적으로 싱글 스레드로 구현되어 있습니다. 반대로 Memcached는 멀티 스레드로 처리합니다.

하지만 Redis 6.0이상부터는 부분적으로 multithread를 지원한다고 합니다.

  • 클라이언트가 전송한 명령을 네트웍으로 읽어서 파싱하는 부분
  • 명령이 처리된 결과 메시지를 클라이언트에게 네트웍으로 전달하는 부분

그런데 소량의 데이터 즉 100k 이하의 데이터들을 처리할 때에는 Redis를 사용하고, 대용량의 데이터를 처리할 때에는 Memcached가 더 높은 성능을 낸다고 합니다.

Redis는 왜 Memcached보다 대용량 처리 시 느릴까요? 🤔

아마도 메모리 할당 때문으로 보입니다.

Redis는 c언어에서 메모리 할당 및 해제할 때 사용하는 malloc, free를 사용하여 할당을 하게 됩니다. 이로 인해 메모리 파편화가 발생하게 되며, 파편화로 인해 메모리 할당 시 딜레이가 되어 응답속도에 영향을 주게 될 것 같습니다.

메모리 할당의 문제라면 Memcached는 Redis보다 왜 느리지 않을까요?

Memcached는 효율적인 메모리 할당을 하기 위해 Slab이라는 기술을 통해서 파편화를 줄인다고 합니다.

그래서 Redis보다는 Memcached가 대용량의 데이터를 처리할 때 안전하게 처리하는 것 같습니다.

Replication

위에서In-Memory기반 DB들은 기본적으로 영속성을 지원하지 않는다고 말씀드렸습니다.

하지만 Redis는 영속성을 지원하기 위해서 Replication이라는 기술이 있습니다.

Replication은 번역하면 복제라는 뜻으로 Master, Slave 개념으로 나누어서 Master의 모든 데이터를 Slave로 복제하여 이중화를 구성하는 것을 말합니다. 당연히 서로 다른 서버에 두어야겠죠?

Memcached는 Replication 지원을 하지 않고 Consistent Hashing 개념을 사용하여 장애가 발생한 서버의 데이터만 사라지고 나머지 서버의 데이터들은 그대로 사용이 가능하게 합니다.

결론

Redis와 Memcached의 성능을 비교해보았습니다.

비교를 하면 할수록 뭔가 Redis가 Memcached의 웬만한 기능들은 다 지원하는 상위 호환 같은 존재 같았습니다.

성능상으로는 딱히 어떤게 더 우위에 있다고 단정지을 수 없을 것 같아 그럼 개발의 편의성 등 다른 방향으로 생각을 해보았습니다.

현재 Spring boot를 사용하고 있으므로 간단하게 의존성 빌드 및 애노테이션만 변경하면 Redis를 가장 빠르게 사용할 수 있습니다.

또한 장애상황이 발생 할 경우 Replication기능이 있는 Redis를 사용하는 것이 안정적인 서비스를 제공할 수 있는 한걸음 인 것 같아 Redis를 사용하기로 결정했습니다.🔨

Reference

아마존에서 비교한 스토리지 (https://aws.amazon.com/ko/elasticache/redis-vs-memcached/#Sub-millisecond_latency)
https://charsyam.wordpress.com/2020/05/05/입-개발-redis-6-0-threadedio를-알아보자/
https://d2.naver.com/helloworld/151047
https://redis.io/topics/replication

'프로젝트 > Careers' 카테고리의 다른 글

Jenkins를 사용한 CI 구성  (0) 2021.08.05
CI/CD 왜 필요한가?  (0) 2021.08.05
Jenkins를 통한 CI/CD 도입  (0) 2021.07.07
Java CheckStyle 적용  (0) 2021.06.10
대규모 서버들의 세션 처리방법  (0) 2021.04.29

댓글