서버

Scale out에 적합한 로그인 환경에 대해 검토한 글

_soboro 2022. 9. 11. 02:02

소개

세션 불일치 문제는 유저의 쿠키에 있는 세션 데이터와 서버가 가지고 있는 세션 데이터가 일치하지 않는것을 말합니다.

문제 상황 시나리오

아래 사진을 보시면 파란색, 오렌지색 서버가 있습니다. 트래픽의 증가로 인해 하나의 서버를 Scale out한 상태이기 떄문에 서버가 두 대로 늘어났습니다. 사용자 A는 제 어플리케이션을 이용하기 위해 요청을 시도합니다.

 

 

  1. 사용자 A가 로드밸런서에게 로그인을 요청합니다.
  2. 로드밸런서는 알고리즘에 맞게 파란색 서버에게 로그인을 요청합니다.
  3. 파란색 서버는 로그인을 성공한 유저 A의 쿠키에 자신만 해독할 수 있는 세션 데이터를 로드밸런서를 통해 유저 A에게 전달합니다.
  4. USER A가 오렌지색 서버를 통해 마이페이지를 이용해서 개인정보를 확인하기 위해 로드밸런서에게 요청을 보냅니다.
  5. 로드밸런서는 오렌지 서버에 마이페이지 접근 요청을 보냅니다.
  6. 오렌지색 서버는 USER A가 쿠키에 담아 보낸 세션 데이터와 일치하는 데이터가 없는것을 확인합니다. 그리고 로그인이 필요하다는 메시지를 유저에게 보냅니다.

최악에 상황에 생기는 문제

최악의 경우 트래픽이 증가해서 서버가 두대보다 많아졌을때, 유저 A의 쿠키에 있는 세션 데이터와 일치하지 않는 데이터를 가진 서버가 계속 늘어나게 됩니다. 결국 서버들은 의미없는 데이터를 계속 저장하게 됩니다. 그리고 사용자 A는 로드밸런서가 자신과 일치하는 세션 데이터를 가진 서버를 찾을때까지 로그인을 다시 해야 합니다.

문제 해결 방법

이 문제를 해결하기 위해서는 사용자의 쿠키에 있는 세션과 사용자가 요청하는 서버의 세션이 어플리케이션이 동작할때 동기화 되도록 하면 됩니다.

동기화를 할 수 있는 방법을 저는 세가지를 생각했습니다.

  1. Sticky Session
  2. Session Clustering
  3. In memory DB를 통한 세션 데이터 공유

Sticky Session

Sticky session은 클라이언트의 request을 session이 끝날때까지 특정 Server에만 보내는 기술입니다. 일반적으로 Client의 Cookie를 통해서 Loadbalancer가 어떤 Server에게 Request를 보낼지 알 수 있습니다.

 

 

상단 첫번째 이미지를 보시면 Sticky session을 적용하지 않았을때의 구조를 나타냅니다. 오렌지색의 사용자 Request가 모든 Server에게 가는것을 확인할 수 있습니다.

반면 두번째는 특정 사용자의 Request가 정해진 Server에게만 향하고 있습니다.

Why Use

비교적 적은 트래픽, 메모리 사용을 통해서 Client와 Server의 Session을 유지시킬 수 있습니다. LoadBalancer가 모든 서버에 사용자의 Request를 보내지 않기 때문입니다.

Problem

사용자와 연결된 서버에 장애가 발생한다면, 사용자는 로그인을 다시 해야 합니다. 해당 사용자의 세션을 다른 서버들은 가지고 있지 않기 때문입니다.

제 서비스를 통해 Sticky Session을 사용했을때, 최악의 상황을 가정해 보겠습니다. 만약 사용자가 책을 결제 하는 도중에 로그인이 끊긴다면, 결제 내용을 다시 입력하는 불편함이 생길 수 있습니다.

다른 문제는 사용자의 요청에 따라 하나의 서버에 부하가 집중될 수 있는것입니다. 예를들어 아래 이미지를 보시면 세대의 서버가 책 조회, 결제, 장바구니 요청을 처리합니다. 그리고 해당 기능에서 로그인 경로로 redirect된 사용자에 대한 세션 발급을 각 기능을 담당하는 서버가 합니다.

최악의 상황을 고려했을때, 모든 사용자가 책 조회중에 로그인을 하게 되면 A서버에 부하가 집중되고 다른 서버들의 자원이 낭비됩니다. 사용자의 모든 세션을 A서버가 가지고 있기 때문입니다. 이렇게 되면 부하를 분산해주는 로드밸런서의 사용 의미도 없어집니다.

이 문제를 Session Clustering, inmemory DB를 통한 세션 공유를 통해서 해결할 수 있을것 같습니다.

Session Clustering

Session Clustering은 제가 사용하고 있는 Tomcat을 기준으로 설명 드리겠습니다.

Tomcat은 Sticky Session의 문제를 Session data를 복제해서 Server들이 공유하는 방법을 통해 해결합니다.

Session Replication(복제)는 Membership이라는 단위에 해당하는 was들에 제공됩니다. Membership은 TCP 포트를 통해서 multicasting을 받고있는 was들을 말합니다.

자세히 말하면 Membership에 해당하는 was들에 주기적으로 ping을 사용해서 서로의 멤버들을 계속 확인 합니다. 만약 한 서버가 죽게되면 멤버에서 탈락합니다. 세션은 Membership에 해당되는 서버에게 복제가 됩니다.

Why & Problem

이처럼 서버 한대가 문제가 생겼을때 다른 서버에 사용자의 세션이 복제가 되어있기 때문에 Sticky Session이 가지고 있던 문제를 해결할 수 있습니다.

그러나 Session Clustering의 문제는 Membership을 유지하기 위해 multicasting을 주기적으로 한다는 것입니다.

만약 트래픽이 더 늘어나서 서버가 추가된다면, 연결을 유지하기 위한 비용은 더 늘어날 것 입니다

Inmemory DB를 통한 세션 공유

아래 사진을 보면 서버가 클러스터 환경을 유지하기 위해서 연결을 맺는 과정이 사라진것을 확인할 수 있습니다. 이유는 Inmemory DB를 통해 서버가 세션을 공유하고 있기 때문입니다.

memory는 disk보다 memory가 빠르게 데이터를 전달하고 저장 할 수 있습니다. 사용자가 빠르게 원한 데이터를 전달 받기 위해서 inmemory 기반 dbms를 사용하는게 좋아 보입니다.