본문 바로가기
기타

다중 서버에서의 Session 불일치 현상과 해결 방법

by jaee_ 2021. 11. 7.

이제 막 프로젝트를 시작하며 가장 먼저 구현하려고 생각한 것은 회원 로그인 기능입니다. 이 로그인 기능을 구현하기에 앞서, 만약 내가 만든 서비스가 하나의 서버로 감당할 수 없을만큼 성장했을 경우엔 어떻게 해야할까? 부터 고민을 하기 시작했습니다. 

 

이 고민에 대해서 생각하며 Scale-up 과 Scale-out에 대해 알아보았고, Scale-up 을 사용한다면 하나의 서버로 모든 트래픽을 감당해야하기 때문에 위험부담이 크다는 생각이 들었습니다. 그렇기에 Scale-out 방식을 고려하다 보니, 서버가 여러대일 때 Session은 어떻게 관리가 되는지에 대한 질문부터 어떻게 해결해야하는지 고민하는 시간을 가졌습니다. 고민하는 과정과 이를 알아가는 과정을 적어보겠습니다. 


Session에 대해 그리고 다중서버에서 Session이 왜 문제가 될까? 

위의 사진처럼 하나의 서버에 수많은 사용자의 요청이 들어오게 되면 서버는 감당할 수 없을 것 입니다. 그렇기 때문에 실제 운영하는 서비스에서는 서버를 2대 이상 두고 사용하며, 하나의 서버에 요청이 몰리지 않도록 로드밸런서를 통해 적절히 분배해줄 수 있도록 해줍니다. 

더보기

💡 로드밸런싱(Load Balancing)이란?
대용량 트래픽을 장애 없이 처리하기 위해 여러 대의 서버에 적절히 트래픽을 분배하는 것이다. 로드밸런싱(Load Balancing)을 해주는 소프트웨어 혹은 하드웨어 장비를 로드밸런서(Load Balancer)라고 합니다.

세션은 사용자와 서버간의 상태를 유지시키기 위해 사용되는 기술로 쿠키와 달리 웹서버에 저장이 되며 브라우저를 닫았을 때 또는 세션의 시간이 만료되면 자동으로 없어지는 것 입니다. 보통 로그인 상태를 기억할 때 많이 사용됩니다. 

 

세션은 다음과 같이 동작합니다. 

1. 사용자가 웹브라우저에 접속 시 서버는 cookie의 header에 session-id를 확인합니다. 

2. session-id가 있으면 SESSIONID cookie를 생성하여 response로 같이 보냅니다. (session-id가 없을 경우엔 웹서버에서 생성하여 보내줍니다. )

3. 사용자는 웹 브라우저에 접속할 때마다 session-id를 서버로 같이 보내고, 서버는 요청으로 받은 session-id값을 확인하여 사용자를 구분합니다. 

 

위에서 설명했듯이 세션은 웹서버에 저장이 됩니다. 이는 A,B,C로 총 세개의 서버가 있는 다중 서버 환경에서는 다음과 같은 문제를 야기합니다. 

 

1. 사용자1은 A서버에 접속하여 서비스를 이용합니다. (A 서버에 session-id 저장)

2. 사용자1은 다른 페이지로 넘어갑니다. 이 때, 로드밸런서의 알고리즘에 의해 B 서버로 사용자1의 요청이 넘어갑니다. 

3. 요청을 받은 B 서버는 header에 session-id를 확인합니다. 하지만, 사용자1의 session-id 정보는 A 서버에 저장이 되어있기 때문에  session-id를 새로 생성하여 보내줍니다. 

4. 사용자는 다시 로그인을 해야합니다. 

 

만약 사용자가 다른 페이지로 접속할 때마다 다른 서버로 연결이 된다면 사용자는 매번 로그인을 해주어야 하는 번거로움을 겪게 됩니다. 

 

그렇다면 이와 같은 세션 정합성(불일치) 문제를 어떻게 해결해야할지 알아보겠습니다. 


1. Sticky Session 방식 

Sticky Session이란 고정된 세션을 의미합니다. 사용자가 요청을 보내면 로드밸런서가 session cookie가 존재하는지 확인을 하고 존재한다면 해당 요청을 처음 처리한 서버로만 보내는 방식으로 동작합니다. 즉, 로드밸런서가 사용자1의 요청일 땐 "너의 세션은 A서버가 가지고 있으니까 A서버로 가!" 라고 정해놓은 것입니다.  

 

이 방식을 사용하면 사용자1의 정보를 알고 있는 A서버로만 연결이 이루어지기 때문에 세션의 정합성 문제를 해결할 수 있습니다. 하지만, 대량의 요청이 들어왔을 경우 특정 서버에만 과부하가 올 수 있고, 특정 서버가 다운되었을 때 세션이 소실될 수 있습니다. 즉, 가용성이 떨어진다는 단점이 존재하는 것 입니다. 

 

2. Session Clustering 

위의 가용성이 떨어지는 문제를 해결할 수 있는 방법 중 하나가 세션 클러스팅입니다. 우선 Clustering (클러스터링)이란 여러 대의 컴퓨터들이 하나의 시스템처럼 동작하도록 만드는 것을 의미합니다. TOMCAT(WAS)에서 세션 클러스터링을 제안하는 세션 클러스터링 방식으로  DeltaManager 사용하여 all-to-all 방식 제안합니다. all-to-all은 모든 세션이 클러스터의 다른 모든 노드 에 복제 됨을 의미합니다. 즉, A서버의 세션이 생성이 되거나 변경되는 요소가 발생하면 B서버, C서버, D 서버 모두 생성되거나 변경된 세션을 복제한다는 것입니다. 

 

이처럼 세션 클러스터링 방식을 이용하면 A,B,C 서버 모두 동일한 세션을 보유하고 있기 때문에 세션의 정합성 문제를 해결할 수 있지만, 이 방법에도 단점이 존재합니다. 모두 복제를 하여 A,B,C,D 서버에 동일한 세션을 보유하고 있기 때문에 메모리 상 비효율적이며, 많은 메모리가 필요합니다. 또한, 세션 하나를 생성 및 변경하기 위해선 다른 서버에도 복제를 해주는 방식이 반복이 되다보니 네트워크 트래픽이 증가하여 성능저하가 발생하게 됩니다. 때문에 all-to-all 방식은 소규모 클러스터에 적합합니다. 실제로 tomcat document에도 '소규모 클러스터에 적합하지만 노드가 4개 이상인 대규모 클러스터에는 권장하지 않습니다.' 라고 명시되어 있습니다.

 

만약 큰 클러스터의 경우 BackupManager를 사용하여 세션이 하나의 백업 노드에만 저장되는 primary-secondary 세션 복제 방식을 사용해야 합니다. 이 방식은 A서버를 primary서버 B서버를 secondary서버로 정해놓고 secondary서버에만 세션 전체의 객체를 복사하고 나머지 C,D의 서버에는 JSESSIONID(Key)만 복제하는 방법을 말한다. 세션 객체 전부를 A,B,C,D서버 전부에게 저장하는 것보다 시간도, 메모리도 절약될 것입니다. 하지만, 만약 로드밸런싱을 통해 서버 C에게 요청이 들어오면 A서버(primary)에게 JSESSIONID(Key)에 해당하는 정보가 뭐니?라고 요청하고 해당 객체를 받아오는 과정을 거치게 된다는 비효율적인 단점이 존재하게 됩니다. 

 

3.  Session Storage 

고정된 세션을 의미하는 Sticky session방식은 가용성이 떨어진다는 단점이, 세션을 복제하는 방식인 Session Clustering방식은 메모리를 많이 차지하며 시간적으로 효율적이지 못하다는 단점이 존재했습니다. 그렇다면 위의 그림처럼 세션을 관리하는 메모리를 따로 만들어서 사용하면 어떨까요?

 

Session Storage를 분리하여 사용하면 모두 동일한 세션을 공유하게 되니 원초적인 문제였던 세션의 정합성은 물론이고, A서버에서 장애가 발생하더라도 다른 서버에서 동일한 세션 스토리지를 사용하고 있기 때문에 가용성 문제도 해결됩니다. 또한, 복제할 필요가 없으니 시간적인 성능도 좋아집니다. 하지만 하나로 관리되는 Session Storage가 장애가 발생하여 문제가 생기게 되면 모든 세션은 이용이 불가능해진다는 단점도 존재합니다. 그럴 경우를 대비하여 Session Storage서버를 복제하여 구성하는 것이 좋습니다. 

 

🔍 이러한 Session Storage는 보통 Inmemory DB를 사용한다. Inmemory DB란 데이터 스토리지의 메인 메모리에 설치되어 운영되는 방식의 데이터베이스 관리 시스템으로 디스크에서 데이터를 읽어오는 것이 아니라 메모리에서 데이터를 읽어오기 때문에 조회 시 속도가 더 빠르다.또한, 메인 메모리에 설치되기 때문에 휘발성이라는 특징이 있다. 

참고한 사이트

https://hyuntaeknote.tistory.com/6?category=867120 

https://junshock5.tistory.com/84

https://88240.tistory.com/190

'기타' 카테고리의 다른 글

[CI/CD] CI/CD란? - 지속적 통합/지속적 배포  (0) 2021.12.28
Scale-up 과 Scale-out에 대해서 알아보자  (0) 2021.11.06
면접 질문 정리 (1)  (0) 2021.10.13
[8주차] 멘토링 키워드  (0) 2021.10.06
[7주차] 멘토링 키워드  (0) 2021.09.29

댓글