세션은 웹서버에 웹컨테이너(ex.톰캣)의 상태를 유지하기 위한 정보를 저장한다. 하지만 만약 웹서버에 갑자기 많은 트랙픽이 몰리게 되면 하나의 서버만으로는 감당이 안되기 때문에 scale-up이나 scale-out하는 경우가 많다. 즉, 한 서버를 업그레이드 하거나 여러개의 서버를 만드는 것이다. 하나의 서버에 문제가 발생해 장애가 나더라도 다른 서버로 대체할 수 있다는 이유로 대부분 scale-out 하는 경우가 많다. 하지만 여러 서버로 운영되다 보니 세션 불일치문제가 발생하는 것이다. 친구들과의 대화는 세션 불일치에서 시작되었다.
세션 불일치문제를 해결하기 위해서는 세션을 동기화하는 방법이 있는데 총 3가지 이다.
💡 세션을 동기화시킬 수 있는 방안
- Sticky Session : 클라이언트별로 담당 처리 서버를 지정하는 방법
- Session Clustering : 서버끼리 자기 서버에 보관하고 있는 세션의 변경사항을 실시간으로 주고받는 방법
- Session Server :세션 정보를 서버가 아닌 다른 외부 저장소에 저장하는 방법
하지만 이전에 내가 세션 불일치에 대해 쓴 게시물에 나온 것처럼
https://velog.io/@sweet_sumin/%EC%84%B8%EC%85%98-%EB%B6%88%EC%9D%BC%EC%B9%98-%EC%9D%B4%EC%8A%88
세가지 경우 모두 단점이 존재한다. 그나마 세번째 방법인 세션 서버가 다른 2가지를 보완한 방법이지만 만약 세션 서버조차도 날라간다면???? 현실에 발생할 수도 있을 상황 아닌가?
짧게 생각해보면, reflection방법도 있을 것이다. 한 redis를 master로 놓고, 다른 redis를 slave으로 두어 만약 master가 날아간다면 slave 서버 중 하나를 올리면 되니까 말이다. 하지만 slave 서버 조차도 다 날아간다면? 클라이언트에게 500에러를 결국 보내야만 하는가? 안된다. 우리의 손님들은 인내심이 없을 것이다. 왜냐, 나부터도 인내심이 없기 때문이다^^ 한번 에러난 서비스는 잘 안쓰기 마련이다ㅠㅠ
그렇다면 500에러를 클라이언트에게 보내는 방법보다는 클라이언트에게 늦게 응답을 하더라도 빠르게 재복구하여 응답을 하긴 하게 만드는 것이 더 나은 선택일텐데 빠르게 재복구할 수 있는 구조는 없을까?
우리들의 대화에서 나온 위의 질문에 대한 대안은 redis로 세션저장소로 만들되, 혹시 모를 경우를 대비하여 MySQL을 이용한 RDB 세션저장소를 따로 백업으로 만들어 놓는 구조를 생각해냈다. redis는 속도가 빠르지만 만약 한번 날아가면 세션 정보가 다 날라가버리니 영속성으로 데이터를 가지는 RDB를 백업으로 둔다면 재복구는 가능하지 않을까 하는 생각에서 비롯되었다. 물론, radis와 RDB를 같이 쓰게 되면 radis 세션 정보와 RDB의 세션 정보의 불일치현상이 발생하긴 하겠지만 radis 자체에도 캐시 솔루션을 아무리 써도, 불일치 시점의 간극은 존재하고, 이러한 모든 상황이 클라이언트에게 500에러를 보내는 것보다는 낫다는 생각이다.
하지만, 사실 정답은 없다. 회사에 따라, 상황에 따라 방법의 장단점이 바뀌기 때문에 레플레카든, RDB를 따로 두든, 내가 할 수 있는 것은 이러한 방법 존재에 대한 인식일뿐이다.
번외지만, 짧게 나마 세션 저장소를 정리해보았다.
세션 저장소는 3가지 종류가 있다.
1) 톰캣(WAS)세션
2) MySQL과 같은 RDB를 세션 저장소로 만든다.
3) redis와 같은 메모리를 세션 저장소로 만든다.