-
Redis를 이용하여 대용량 트래픽을 처리 가능한 세션 구조 만들기토이프로젝트/hi-bus-go 2020. 6. 21. 05:25
개요
일반적으로 로그인 세션 관리는 서버의 메모리에 저장하게 됩니다. 하지만 동시 접속자가 많아진다면 어떻게 될까요?. 서버 내의 리소스가 부족하게 되어 서버가 다른 작업을 수행하지 못하거나 다른 사용자가 로그인하지 못할 수도 있습니다.
서버 내의 리소스가 부족할 경우에는 어떤 해결책이 있을까요?
리소스 부족을 해결하기 위한 해결책에는 scale-up과 scale-out이 있습니다.
scale-up은 서버 한대의 하드웨어 성능을 높여 서버의 처리하는 성능을 높이는 전략입니다.
성능 증가폭이 크며, 일반적으로 비용 부담이 큰 특징이 있습니다. 또한 서버가 장애가 나면 전면 장애가 발생할 수 있습니다.
scalue-out은 여러 서버가 요청을 처리하여 서버 한대가 처리하는 용량을 줄임을 동시에 전체적인 성능을 높이는 전략입니다.
가성비가 높아지지만 서버를 구성하기에 힘들며 서버가 늘어나면 데이터가 불일치가 생길 수 있습니다.
그렇다면 서버를 어떻게 구성해야 비용적으로 효율적이면서 큰 효율을 낼 수 있을까요?. scale-up으로 서버의 리소스를 늘리는 방법이 해결책이 될 수도 있지만, 비용적으로 비쌀뿐더러 가격이 비싼 것에 비해 성능이 동일한 비율로 향상되지 않습니다.
결국 scale-up이 아닌 scalue-out을 통해 해결하는 것이 비용 및 성능에서 효율적이라고 할 수 있습니다. 또한 서버가 여러 대 이므로 하나가 서버가 장애가 나도 다른 서버가 역할을 대체할 수 있다는 장점이 있습니다.
그런데 scalue-out을 적용하려다 보니 서버 간 세션의 불일치가 발생하였습니다. 이를 해결하기 위해서는 sticky session,session-clutstering,인메모리 데이터 베이스 방식이 있다는 것을 알게 되었습니다.
sticky session은 서버마다 고정적인 세션을 관리하는 방법입니다. 세션마다 고정된 서버가 처리를 하다 보니 특정 서버가 과부하가 올 수 있습니다. 또한 특정 서버가 장애 시 해당 서버가 관리하는 세션이 소실될 수가 있습니다.
session-clustering은 여러 서버가 세션을 하나의 클러스터로 묶어서 관리하는 방법입니다. sticky session에 비해 특정 서버가 장애가 나도 세션이 소실되지 않습니다. 하지만 세션을 클러스터로 묶어서 관리하기 때문에 새로운 서버를 띄울 때마다 클러스터링 설정을 새로 해줘야 하고 기존 서버에 수정을 해야 합니다. 또한 was 마다 클러스터링 설정 방법이 다르기 때문에 was가 바뀐다면 매번 학습해야 합니다.
인메모리 데이터 베이스는 디스크가 아닌 메모리에 데이터를 저장하는 데이터 베이스를 의미합니다. 디스크보다 접근 속도가 빠르다는 장점이 있지만, 디스크가 아닌 메모리에 저장하기 때문에 안정성이 떨어진다는 단점이 있습니다. 그래서 보통 인메모리 데이터 베이스에는 세션정보와 같이 유실되어도 치명적이지 않은 임시성 데이터를 저장하여 빠르게 접근하도록 하는 경우가 많습니다.
또한 서버가 늘어나도 동일한 데이터 베이스를 바라보기 때문에 서버를 계속 늘릴 수 있다는 장점이 있습니다.
셋을 비교했을때 scale-out을 위해 서버 구성이 간단하며 속도 또한 빠른 이유로 인메모리 데이터 베이스가 가장 적합하다고 생각합니다.
redis vs memcahed
검색을 해보니 인메모리 데이터 베이스 중 redis와 memcahed를 자주 사용한다는 것을 알게 되었습니다. 이에 인메모리 데이터 베이스로 대표되는 둘의 특정을 정리해봤습니다.
redis memcached 저장소 in-memory, 저장소 in-memory 속도(QPS 초딩 쿼리 수) 초당 100,000QPS 이상 안정성 특성을 잘못 이해할 경우, 프로세스 장애 발생 장애 거의 없음 백업 및 복원 가능 불가능 응답속도의 균일성 Memcached에 비해서 균일성이 떨어질 수 있음 전체적으로 균일함 스레드 싱글 스레드 멀티 스레드 캐시용량 키, 캐쉬 각각 512MB 키 이름 250 byte, 캐시 값 1MB 출처 : AWS 공식 문서
1. 저장소
memcached는 메모리에 key-value로 저장
redis는 현재의 메모리 상태의 스냅숏을 남기는 RDB 기능과 지금까지 실행된 업데이트 관련 명령어 집합인 AOF 기능 지원
디스크를 사용해서 저장하는 만큼 성능 손실은 어느 정도 있을 수 있다.
2. 백업 및 복원
redis는 서버가 의도치 않게 오류나 셧다운이 발생하였을 때, 디스크에 저장한 메모리 상태의 스냅숏을 통해
데이터 복구 가능합니다.마스터/슬레이브 복제를 지원하여 마스터에 장애가 발생하면 슬레이브 서비스하거나, 마스터의 부하가 많을 경우
슬레이브를 이용해서 읽기 처리 가능합니다.
3. 응답속도의 균일성
응답속도는 memcached가 일정한 속도를 유지합니다. 그에 반해 redis는 대규모 트래픽으로 많은 데이터가 업데이트될 경우
속도가 일정하지 않게 됩니다. 이는 둘의 메모리 할당 구조가 달라서 발생하는 현상입니다.
redis는 jemalloc을 사용하는데, 매번 malloc과 free를 통해서 메모리 할당이 이루어집니다.
반면 memcached는 slab 할당자를 이 용하여, 내부적으로는 메모리 할당을 다시 하지 않고 관리하는 형태를 취합니다.
redis는 메모리 파편화가 발생하는 경우가 있어 할당 이용 때문에 응답 속도가 느려지는 경우도 있다고 합니다.
4. 스레드
memcahed는 멀티 스레드를 지원하기 때문에 싱글 스레드인 redis에 비해 scale-up에 유리하다는 장점이 있습니다.
멀티 스레드의 경우 읽고 쓰기 작업이 빈번하게 진행될 경우 데이터가 안정적이지 않다는 단점도 존재합니다.
redis는 단일 스레드를 지원하여 데이터 손실 없이 클러스터링을 통해 수평으로 확장할 수 있다는 장점이 있습니다.
싱글 스레드 모델을 사용하기 때문에 긴 transacion 작업 요청이 들어오면 요청 처리를 위해 다른 요청을 처리하지 못하는 단점이 있습니다.
결론
버스 터미널 어플을 개발하면서 많은 사용자의 요청을 어떻게 처리 할까 고민해봤습니다. 버스 터미널 어플은 사용자의 요청이 빈번하며 서버의 리소스가 부족 및 세션간 불일치 문제가 발생할 수다고 생각하였습니다. 고민한 결과 비용 및 성능을 고려하여 redis를 이용한 scale-out을 적용했습니다.
redis를 적용한 결과 scale-out을 하여 성능 향상 및 세션 간 불일치 문제를 해결하는 성과를 얻었습니다. 대용량 트래픽 문제를 해결하는 과정에서 redis를 고려해본다면 많은 성과를 얻을 수 있다고 생각합니다.
이외에도 redis와 memcahed를 비교해보니 속도 및 기능에서 큰 차이가 나지 않았지만, 스프링에서 redis를 지원한다는 점에서 차이가 있었습니다. 스프링에서 지원을 한다는 점에서 개발 편의성과 지속성이 좋다고 할 수 있습니다.
References
https://docs.aws.amazon.com/ko_kr/AmazonElastiCache/latest/mem-ug/SelectEngine.html
https://www.infoworld.com/article/3063161/why-redis-beats-memcached-for-caching.html
Project Github URL
'토이프로젝트 > hi-bus-go' 카테고리의 다른 글
대용량 트래픽에서 DB부하를 줄이고 성능 튜닝을 위한 캐싱 적용 (0) 2020.08.27