본문으로 건너뛰기

1.1. 세션 클러스터링 개요

어떤 문제를 푸는가

웹 애플리케이션은 로그인 상태, 장바구니, 입력하던 내용 같은 사용자별 정보를 세션에 담습니다. 세션은 기본적으로 그 요청을 처리한 WAS(Web Application Server) 인스턴스의 메모리에만 있습니다. 그래서 다음 일이 생깁니다.

WAS 한 대가 멈추면 그 인스턴스가 들고 있던 세션이 함께 없어집니다. 사용자는 로그인 화면으로 돌아가고, 담아 둔 장바구니와 입력하던 내용을 잃습니다. 장애 직후에는 그 사용자들이 한꺼번에 다시 접속하므로 남은 인스턴스에 부하가 몰립니다.

배포할 때마다 같은 일이 반복됩니다. 애플리케이션을 새로 올리려면 인스턴스를 재시작해야 하는데, 그때도 세션이 사라집니다. 그래서 배포를 사용자가 적은 시간대로 미루게 됩니다.

인스턴스를 늘려도 세션 때문에 걸립니다. 접속이 몰릴 때 WAS 를 추가하면 처리 능력은 늘지만, 세션이 각 인스턴스에 흩어져 있어 로드 밸런서가 같은 사용자를 항상 같은 인스턴스로 보내야 합니다(고정 세션). 그 인스턴스가 멈추면 그 사용자들만 영향을 받고, 부하도 고르게 나뉘지 않습니다.

WAS 자체 세션 복제는 대안이 되기 어렵습니다. 인스턴스끼리 세션을 복제하면 인스턴스 수가 늘수록 복제 트래픽이 늘고, 세션 데이터가 각 인스턴스의 힙 메모리를 함께 차지해 접속이 많아질 때 메모리 부족(OOM)과 긴 가비지 컬렉션(GC)으로 이어집니다. 서로 다른 WAS 제품이나 서로 다른 웹 애플리케이션 사이에서는 세션을 공유할 수도 없습니다.

제품 소개

OPENMARU Cluster는 WebLogic, JEUS, Tomcat, JBoss EAP 등 WAS의 세션 클러스터링을 위한 모듈입니다. WAS의 세션 클러스터링 기능을 In Memory Data Grid(IMDG) 기술을 사용하여 구축할 수 있도록 합니다. 기존 애플리케이션의 변경없이 web.xml 파일에 서블릿 필터 설정만 추가하고 필요 라이브러리를 추가하면 됩니다.

Java EE 표준 필터를 구현하였기 때문에 애플리케이션의 코드 변경은 없습니다.

이 문서에서는 In Memory Data Grid(IMDG)를 데이터그리드로 줄여 씁니다.

어떨 때 쓰는가

다음에 하나라도 해당하면 검토 대상입니다.

상황왜 필요한가
접속이 몰리는 시기가 있습니다 (쇼핑몰 행사, 수강 신청, 예매)인스턴스를 늘려도 세션이 흩어져 있으면 효과가 제한됩니다
무중단으로 배포하고 싶습니다재시작해도 세션이 남아 있어야 사용자가 로그인 상태를 유지합니다
서로 다른 웹 애플리케이션이 로그인 상태를 함께 써야 합니다애플리케이션마다 따로 로그인하지 않게 합니다
Apache Tomcat 을 씁니다이종 WAS·애플리케이션 사이의 세션 공유 수단이 필요합니다
한 계정으로 여러 곳에서 동시에 로그인하는 것을 막아야 합니다중복 로그인 방지 기능을 씁니다
세션이 지금 몇 개인지, 메모리를 얼마나 쓰는지 봐야 합니다세션 지표를 MBean 으로 확인합니다

세션 클러스터링 구성방법

OPENMARU Cluster는 다음의 두가지 방법으로 WAS의 세션 클러스터링을 구축할 수 있습니다. 아래 두가지 방법을 혼용하여 사용할 수도 있습니다.

  • WAS내의 메모리를 사용하는 방법
  • 별도의 서버들에 데이터그리드를 구성하여 세션을 그곳에 저장하는 방법

WAS간 세션 클러스터링

WAS간 세션 클러스터링 구성도

세션을 WAS 인스턴스의 메모리에 그대로 두고, 인스턴스끼리 복사본을 주고받는 방식입니다. 별도의 서버를 두지 않습니다.

동작은 이렇습니다. 사용자가 로그인하면 그 요청을 처리한 인스턴스가 세션의 주인(Primary)이 되고, 다른 인스턴스 한 대가 복사본(Backup)을 함께 들고 있습니다. 주인 인스턴스가 멈추면 복사본을 들고 있던 인스턴스가 이어받아 세션이 사라지지 않습니다.

좋은 점은 준비할 것이 없다는 것입니다. 데이터그리드 서버를 따로 세우지 않아도 되고, 서버 비용과 관리 대상이 늘지 않습니다. 인스턴스가 두세 대뿐이고 세션 양도 많지 않은 환경이라면 이것으로 충분합니다.

대신 인스턴스가 늘어날수록 부담이 커집니다. 세션이 만들어지고 바뀔 때마다 복사본을 맞추는 통신이 오가는데, 인스턴스 수가 늘면 이 통신도 함께 늘어납니다. 세션 데이터가 애플리케이션과 같은 힙 메모리를 쓰기 때문에, 접속이 몰리면 애플리케이션이 쓸 메모리가 줄고 가비지 컬렉션(GC)이 길어집니다.

또 하나, 인스턴스가 멈추는 순간에는 복제 자체가 흔들릴 수 있습니다. 남은 인스턴스들이 사라진 인스턴스의 몫을 다시 나눠 가지면서 한꺼번에 복제가 일어나기 때문입니다. 장애가 난 그 시점이 가장 부하가 큰 시점이 됩니다.

WAS간 세션 클러스터링 및 데이터그리드 저장소 구성

WAS간 세션 클러스터링과 데이터그리드 저장소를 함께 쓰는 구성도

자주 쓰는 세션은 WAS 메모리에 두고, 나머지는 데이터그리드에 맡기는 방식입니다. 위의 두 방식을 섞은 형태입니다.

동작은 이렇습니다. 방금 사용한 세션은 WAS 메모리에 남아 있어 곧바로 읽힙니다. 한동안 쓰지 않은 세션은 데이터그리드로 내려가고, 다시 필요해지면 그때 가져옵니다. WAS 메모리는 자주 쓰는 것만 들고 있으면 되므로 크게 부풀지 않습니다.

좋은 점은 속도와 확장성을 함께 가져간다는 것입니다. 대부분의 요청은 메모리에서 바로 처리되어 빠르고, 세션이 많아져도 데이터그리드가 받아 주므로 WAS 메모리가 한계에 부딪히지 않습니다. 인스턴스나 애플리케이션이 달라도 데이터그리드를 거쳐 같은 세션을 볼 수 있습니다.

대신 관리할 대상이 하나 늘어납니다. 데이터그리드 서버를 따로 세우고 운영해야 하며, 세션이 WAS 와 데이터그리드 두 곳에 나뉘어 있어 문제가 생겼을 때 어느 쪽을 봐야 하는지 판단이 한 단계 더 필요합니다.

세션 저장소로 데이터그리드만 구성

세션 저장소로 데이터그리드만 쓰는 구성도

세션을 WAS 에 두지 않고 전부 데이터그리드에 저장하는 방식입니다. WAS 는 요청을 처리할 때마다 데이터그리드에서 세션을 읽고 씁니다.

동작은 이렇습니다. WAS 인스턴스는 세션을 들고 있지 않으므로 어느 인스턴스가 요청을 받아도 결과가 같습니다. 로드 밸런서가 같은 사용자를 같은 인스턴스로 보낼 필요가 없고(고정 세션이 필요 없습니다), 인스턴스를 재시작하거나 늘리고 줄여도 세션은 영향을 받지 않습니다.

좋은 점은 WAS 와 세션이 서로를 방해하지 않는다는 것입니다. 애플리케이션이 쓸 메모리는 접속자 수와 무관하게 예측할 수 있고, 세션이 늘면 데이터그리드 노드만 추가하면 됩니다. 배포할 때 세션을 신경 쓰지 않아도 되므로 무중단 배포가 쉬워집니다. 서로 다른 WAS 제품과 서로 다른 웹 애플리케이션이 같은 세션을 함께 쓰는 것도 이 구성에서 가장 자연스럽습니다.

대신 세션을 읽고 쓸 때마다 네트워크를 한 번 거칩니다. 그래서 세션에 아주 큰 객체를 담거나 한 요청에서 세션을 여러 번 고쳐 쓰면 응답 시간에 영향이 있습니다. 데이터그리드 서버를 세우는 비용과 관리 대상도 늘어납니다.

이 문서의 설정 방법(2부)은 이 구성을 기준으로 설명합니다.

어느 구성을 고를까

위 세 가지는 세션을 어디에 두느냐로 갈립니다. 판단 기준은 세션 양, 인스턴스 수, 별도 서버를 둘 수 있는지 세 가지입니다.

WAS간 세션 클러스터링데이터그리드 저장소 함께 구성데이터그리드만 구성
세션이 있는 곳WAS 인스턴스 메모리WAS 메모리 + 데이터그리드데이터그리드
별도 서버필요 없음필요필요
인스턴스를 늘릴 때복제 트래픽이 함께 늘어남영향이 작음영향이 거의 없음
응답 속도가장 빠름(메모리에서 바로 읽음)빠름네트워크를 한 번 거침
어떨 때인스턴스가 적고 세션 양도 적을 때속도와 확장성을 함께 볼 때세션 양이 많고 인스턴스를 자주 늘릴 때

대부분의 운영 환경은 세 번째(데이터그리드만 구성)를 씁니다. WAS 의 힙 메모리와 세션 메모리가 분리되어 접속이 늘어도 애플리케이션 쪽 메모리 사용이 예측 가능해지고, 인스턴스를 늘리거나 재시작해도 세션이 영향을 받지 않기 때문입니다. 이 문서의 설정 방법(2부)도 이 구성을 기준으로 설명합니다.

세션이 늘어 저장 공간이 부족해지면 데이터그리드 노드를 추가합니다. WAS 를 손대지 않고 저장 공간만 늘릴 수 있습니다.

데이터그리드는 몇 대로 구성하나

서버 2대 이상에 각각 인스턴스 2개씩, 모두 4개 인스턴스로 시작하기를 권장합니다.

데이터그리드는 세션마다 원본과 복사본을 서로 다른 인스턴스에 나눠 둡니다. 어느 한 인스턴스가 멈춰도 다른 인스턴스에 복사본이 있어 세션이 사라지지 않습니다.

그래서 서버가 한 대뿐이면 이 구조가 뜻을 잃습니다. 인스턴스를 두 개 띄워도 둘 다 같은 서버에 있으므로, 그 서버가 멈추면 원본과 복사본이 함께 없어집니다. 서버 자체를 두 대 이상으로 나누어야 서버 한 대가 멈추는 상황을 견딥니다.

한 서버에 인스턴스를 두 개씩 두는 이유는 두 가지입니다. 인스턴스 하나를 재시작하거나 점검할 때 그 서버의 몫이 통째로 빠지지 않고, 인스턴스마다 쓰는 메모리(자바 힙)를 적당한 크기로 나눌 수 있어 가비지 컬렉션(GC)이 길어지지 않습니다.

늘리면 무엇이 좋아지나

인스턴스를 늘릴수록 안정성이 커집니다. 세션이 더 많은 인스턴스에 나뉘어 저장되므로, 한 대가 멈졌을 때 남은 인스턴스가 나눠 받는 몫이 작아집니다. 인스턴스가 4개면 한 대가 멈질 때 나머지 셋이 그 몫을 나누지만, 8개면 나머지 일곱이 나눠 부담이 절반 이하로 줄어듭니다. 그만큼 장애가 난 순간의 충격이 작아지고 복구도 빨리 끝납니다.

저장 공간도 함께 늘어납니다. 접속자가 늘어 세션이 많아지면 WAS 를 손대지 않고 데이터그리드 인스턴스만 추가하면 됩니다.

구성서버 한 대가 멈지면
서버 1대 (인스턴스 2개)세션이 모두 없어집니다 — 권장하지 않습니다
서버 2대 (인스턴스 4개)세션은 유지되고, 남은 서버가 전체를 감당합니다
서버 3대 이상 (인스턴스 6개 이상)세션이 유지되고, 남은 서버들이 나눠 받아 서버당 부담이 작아집니다

실제 대수는 세션의 양과 보관 시간, 그리고 감당해야 하는 장애 범위에 따라 정합니다. 산정이 필요하면 담당 엔지니어에게 문의하십시오.