본문 바로가기

카테고리 없음

분산 서버 환경에서 세션 불일치 문제 해결하기

티켓팅 서비스 사이드 프로젝트를 Scale Out으로 확장을 하려 했지만 여러 문제가 발생했습니다. 그중 하나가 세션 불일치 문제였는데 세션 같은 경우 각각의 서버에서 세션 객체를 보관합니다. 만약 로드밸런서에 의하여 클러스터링 된 서버 중 A 서버에 요청을 하면 로그인과 관련된 세션 객체가 생성되었다고 할 때 다시 로드밸런서가 서버에 요청을 할 때 B 서버에 요청이 갈 수 있습니다. 결국 B 서버에는 로그인과 관련된 세션 객체가 저장되어 있지 않으므로 세션의 정합성 문제가 발생할 수 있습니다. 이러한 문제를 해결하기 위한 방법이 몇 가지 있는데 소개해드리겠습니다.

 

 

sticky session

 

sticky session 이란 접착한다는 말로서 클라이언트가 어떤 서버에 고정된 통신을 하는 방법입니다. 사진처럼 user1은 serverC랑만 통신을 하고 user2, user3또한 serverB, serverA와 통신을 합니다. 이러한 방식은 로드밸런서가 요청받은 쿠키를 확인하거나 ip 주소 통해 그에 맞는 server에 전달을 해줄 수 있습니다. 하지만 서버들이 불균등하게 통신을 할 가능성이 있습니다. 예를 들어 이미 존재하는 서버로 클라이언트와 매칭을 시켜 줬는데 서버를 더 추가해야 할 일이 발생해 서버를 추가시켜주지만 이미 매칭된 서버로만 통신을 하여 불균등하게 분배될 수 있습니다. 또한 여러 사설 ip를 사용하면 하나의 공인 ip로 전환해 요청을 보내기 때문에 로드밸런서는 공인 ip를 확인해서 한쪽의 서버에만 요청을 보내는 일이 발생할 수 있습니다. 그리고 서버가 장애가 발생할 때 그 서버에 있는 세션이 손실될 수 있는 위험도 있어 가용성이 떨어집니다.

 

 

session-clustering

Session-clustering 이란 여러 서버들이 동일한 세션을 관리해 준다는 뜻으로 톰켓은 All-to-all 방법과 BackupManager 방법을 제공해 줍니다.

 

 

All-to-all

 

 

All-to-all 방식은 클러스터링 된 서버마다 세션 객체를 전부 복제 시켜주는 방식입니다. 따라서 로드밸런서가 아무 서버에 요청을 보내도 원하는 세션 값을 얻을 수 있습니다. 그뿐만 아니라 한 서버가 장애가 발생해도 다른 서버에 세션 값을 보관하고 있으니 가용성도 증가시킬 수 있습니다. 따라서 sticky session의 단점인 한쪽 서버만 부화가 발생할 수 있는 점과 가용성이 떨어지는 단점을 해결해 줄 수 있습니다. 하지만 서버마다 세션 객체를 전부 복제해서 용량 부족 현상이 발생할 수 있습니다. 그래서 톰켓은 서버 4대 이상일 경우 이 방법을 추천하지 않고 BackupManager 방법을 추천하고 있습니다.

 

 

BackupManager

 

 

BackupManager 서버 한대에만 세션 객체를 복제시켜 주고 다른 서버에는 키값만 부여를 해줍니다. 만약 로드밸런서가 key 값만 있는 서버에 요청을 하게 된다면 그 서버는 세션 객체가 보관되어 있는 서버에서 key 값을 통해 value 값을 얻어오게 됩니다. 따라서 정합성 문제를 해결해 줄 수 있고 서버 한대에 세션 객체를 복제 시켜주니 가용성도 증가시켜 줄 수 있습니다. 그뿐만 아니라 All-to-all 방식처럼 세션 객체를 전부 복제 시켜주지 않고 key 값만 전달해 주니 용량에도 더 효과적입니다. 하지만 key 값을 통해 세션 객체를 보유하고 있는 서버에서 value 값을 얻어 오므로 네트워크 비용이 발생하고 처음에 key 값을 각 서버마다 부여할 때도 네트워크 비용이 발생하므로 서버가 대규모로 확장 시 성능에 떨어질 수 있습니다.

 

 

session storage 

마지막으로 session storage를 따로 구축하는 방법이 있습니다. 클러스트링 된 서버중 하나가 세션객체를 생성하고 session storage에 복제시켜 줍니다. 그리고 다른 서버가 그 세션값을 받고싶을때 session storage에서 얻을 수 있으므로 정합성 문제를 해결 할 수 있습니다. 따라서 sticky session처럼 서버와 클라이언트를 매칭 시켜주지 않아도 되기 때문에 한 서버에 부하가 발생하지 않고 session clustering처럼 서버별로 세션 객체를 복제할 필요가 없기 때문에 용량 부담도 줄여줄수 있습니다. 이번 사이드 프로젝트에서는 서버를 무한으로 확장해도 문제가 없도록 하는게 목표였습니다. 따라서 위의 장단점을 고려해 session storage를 구축하기로 결정했습니다.

 

사이드 프로젝트

github.com/f-lab-edu/show-ticketing-service

 

참고

vaadin.com/blog/session-replication-in-the-world-of-vaadin

 

Session Replication in the World of Vaadin

We often get questions about how to use session replication together with Vaadin. Many of Vaadin's unique capabilities are based on the way the entire UI state is stored in a server-side user session. For this reason, our recommendation is to...

vaadin.com

smjeon.dev/web/sticky-session/

 

Sticky Session과 Session Clustering

배경

smjeon.dev

tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html

 

Apache Tomcat 8 (8.5.63) - Clustering/Session Replication How-To

Simply add to your or your element to enable clustering. Using the above configuration will enable all-to-all session replication using the DeltaManager to replicate session deltas. By all-to-all, we mean that every session gets replicated to all the other

tomcat.apache.org