Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

유비무환

대용량 트래픽 처리를 위한 세션 관리 방법 본문

IT/개인 프로젝트

대용량 트래픽 처리를 위한 세션 관리 방법

키다리병장 2020. 6. 22. 17:29

스프링 부트로 만들고 있는 개인 프로젝트에 로그인 기능이 필요해서 개발을 진행했습니다. 로그인 기능을 개발한 이유는 특정 기능을 사용하기 위해선 회원 정보가 필요하기 때문입니다. 로그인을 한 이후에 고객은 자유롭게 애플리케이션을 이용할 수 있습니다.

 

만약 사이트를 이용하는 고객 입장에서 어떤 작업을 할 때마다 로그인을 반복해서 해야 한다면 더 이상 사이트를 이용하고 싶지 않을 겁니다. 이럴 때 세션을 통해 서버가 로그인 정보를 가지고 있음으로써 고객은 한 번의 로그인으로 사이트를 자유롭게 이용할 수 있게 됩니다. 물론 세션이 만료되기 전까지만요.


세션 불일치

지금까지 한 대의 서버에서 세션을 사용한 경우를 생각해봤다면 지금부터는 여러 대의 서버에서 세션을 사용할 경우를 생각해봐야 합니다. 클라이언트와 서버가 일대일 관계라면 문제가 없을 겁니다. 클라이언트가 서버에 요청을 하면 서버는 세션을 갖게 되고 이후에는 세션을 사용하기만 하면 되기 때문입니다. 하지만 일대다 관계라면 모든 서버가 클라이언트에 대한 세션을 가지고 있지 않을 겁니다. 만약 세션을 가지지 않은 서버가 요청을 처리한다면 로그인이 필요하다고 할 것이고 이런 상황을 '세션 불일치'라고 합니다.

 

그림1. 세션 불일치로 인한 요청 성공/실패 여부

 

이를 해결하기 위한 여러 가지 방안이 있지만 그중에서 세션 클러스터링과 레디스가 어떤 것이고 각각 어떤 특징을 가지고 있는지 살펴보고 최종적으로 레디스를 선택한 이유를 이야기해보겠습니다.


세션 클러스터링

세션 클러스터링은 서버가 가지고 있는 세션 정보를 여러 서버에서 공유하기 위한 방식입니다. 톰캣 문서에 따르면 클러스터는 DeltaManager와 BackupManager 두 가지 방식을 통해 만들어집니다.

 

먼저 DeltaManager는 클러스터에 존재하는 모든 노드에 세션을 복제하는 방식입니다. 이 방식은 소규모 클러스터에 적합하지만 4개 이상의 노드를 가진 대규모 클러스터에는 권장하지 않습니다. 그 이유는 애플리케이션이 배포되지 않은 노드 또한 세션 복제 대상이 되기 때문입니다. 즉, 모든 노드가 세션을 가져야 하기 때문에 많은 메모리를 사용하게 되고 네트워크 트래픽이 증가하게 됩니다.

 

그림2. DeltaManager 방식

 

BackupManagerDeltaManager가 가진 문제를 해결하기 위한 방식으로 세션 데이터를 하나의 백업 노드와 애플리케이션을 배포한 노드에만 복제하는 방식입니다. 세션이 복제되지 않는 노드는 세션을 가지는 노드의 위치를 가지고 있다가 이후 클라이언트의 요청을 받으면 위치에 해당하는 노드에게 요청해서 작업을 처리합니다.

 

그림3. BackupManager 방식

 

세션 클러스터링은 세션 동기화를 위해 많은 통신이 필요한 기술입니다. BackupManager를 사용하더라도 이후에 세션이 변경되거나 세션을 갖지 않는 노드가 요청을 받게 되면 불가피하게 통신이 일어날 수밖에 없습니다. 또한 모든 데이터 통신이 TCP를 통해 이루어지는데 TCP는 전달 확인 및 순서 보장을 위한 핸드 셰이크 과정이 동반되기 때문에 그만큼 오버헤드를 발생시킬 수 있습니다.

 

소규모의 서버일 경우라면 통신에서 발생하는 오버헤드를 감당할 수 있겠지만 서버가 점차 증가하게 된다면 네트워크 통신 횟수가 늘어나면서 성능 저하를 일으킬 수 있습니다. 만약 다중 서버 환경을 구성하려고 한다면 확장성 측면에서 고려해보면 좋을 것 같습니다.


레디스

레디스는 key-value 구조로 데이터를 저장하고 관리하기 위한 인메모리 디비입니다. 인메모리 디비는 메모리에 데이터가 저장되기 때문에 휘발성을 가지고 있기 때문에 전원이 소실될 경우나 고의적인 상황 등에서 저장된 데이터가 손실될 수 있습니다. 즉, 중요한 데이터를 저장하기에는 적합하지 않습니다.

 

다행히도 세션은 회원 정보와 같이 손실될 경우 큰 영향을 끼치는 데이터를 저장하는 것이 아니라 손실되어도 문제없는 데이터를 저장합니다. 그 이유는 세션에는 만료 시간이 존재하고 브라우저가 종료되는 시점에 세션이 없어지기 때문입니다. 따라서 세션은 레디스에 저장하기에 적합한 데이터라고 판단할 수 있습니다.

 

세션 클러스터링의 경우 서버 내부에 있는 메모리에서 세션을 관리한다면 레디스는 외부 저장소에서 세션을 관리하는 구조입니다. 이 경우에 그림 4와 같이 모든 서버는 레디스를 통해 세션을 가져오게 됩니다.

 

그림4. 레디스를 사용해 세션을 관리하는 구조


마무리

세션 클러스터링을 사용했을 때 얻을 수 있는 장점에 비해 많은 통신 횟수로 인한 단점이 더 크다고 판단했습니다. 반면에 레디스를 사용하면 서버의 수에 관계없이 세션 동기화를 위해 서버 간에 통신이 필요하지 않고 그저 레디스와의 통신 한 번으로 세션을 가져올 수 있습니다. 물론 인메모리 디비는 휘발성 특징으로 인해 데이터 손실이라는 단점을 가지지만 세션은 치명적인 정보를 가지지 않기 때문에 손실되더라도 큰 영향을 미치지 않을 것이라고 생각했습니다.

 

외부 저장소(레디스)를 사용해서 세션을 관리함으로써 각 서버는 세션을 유지하기 위해 사용하던 메모리를 줄일 수 있었고 서버가 확장되더라도 레디스와의 통신을 통해 손쉽게 세션 정보를 가져올 수 있기 때문에 확장성을 높일 수 있었습니다.

 

참고

http://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html

Comments