[zookeeper] SessionTimeoutException vs SessionExpiredException

SessionTimeoutException과 SessionExpiredException의 차이에 대해 정리해둡니다.

먼저, Session timeout은 주키퍼 클라이언트와 주키퍼 클러스터(ensemble) 사이의 연결(Connection)이 끊겼다는 것을 나타냅니다.
클라이언트측에서 감지하여 발생시키는 예외로, 서버와는 무관합니다.

Session expired는 주키퍼 클러스터에 대해 클라이언트의 세션이 만료되었다는 것을 나타냅니다.
Session expired의 경우는 Session timeout 과는 조금 다른 방식으로 처리되는데, Session timeout이 순수하게 클라이언트에서 timeout 감지하여 처리하는 반면, Session expired의 경우는 서버로부터 한번 더 결과를 얻어와서 처리를 하게 됩니다. 자세히 살펴보기 위해 소스를 곁들입니다.

// ClientCnxn.java

void readConnectResult() throws IOException {
	...
	ConnectResponse conRsp = new ConnectResponse();
	conRsp.deserialize(bbia, "connect");
	negotiatedSessionTimeout = conRsp.getTimeOut();
	if (negotiatedSessionTimeout <= 0) {
		zooKeeper.state = States.CLOSED;

		eventThread.queueEvent(new WatchedEvent(
			Watcher.Event.EventType.None,
			Watcher.Event.KeeperState.Expired, null));
		eventThread.queueEventOfDeath();
		throw new SessionExpiredException(
			"Unable to reconnect to ZooKeeper service, session 0x"
			+ Long.toHexString(sessionId) + " has expired");
	}
	...

과정은 다음과 같습니다.

  1. 클라이언트가 서버와 연결을 맺고 “connect” 요청을 보냄.
  2. 응답을 받은 후 자신의 세션이 만료되었음을 감지.
  3. throw Exception

Session expired는 서버와의 통신이 일어나야만 발생합니다. 즉, 서버가 클라이언트에게 expired를 알려주어야만 발생한다는 것이죠. 또한 클라이언트 입장에서 랜선을 뽑아버린다거나 서버의 하드웨어에 장애가 생겨서 TCP 통신을 할 수 없는 경우라면 Session expired는 발생하지 않습니다.
주키퍼 클라이언트를 사용하는 경우, 두 예외에 대해 동일하게 대응하는 경우가 많은데 이 두 예외의 차이점을 고려해야 합니다.

주키퍼 클러스터와 클라이언트가 단절된 경우
> Session timeout이 지속적으로 발생하지만 Session Expired는 발생하지 않습니다. 즉, 클라이언트끼리는 정상적으로 통신하고 있을 수 있습니다. 따라서 클라이언트는 주키퍼 클러스터에 연결할 때, Session Expired가 아니면 계속 연결을 시도할 가치가 있습니다.

주키퍼 클러스터와 클라이언트의 단절이 오래 지속되는 경우
> 주키퍼 리더는 해당 세션을 삭제합니다. 주키퍼와 통신하는 다른 클라이언트는 Session Expired를 받게 됩니다. 원래의 클라이언트가 죽었다고 간주할 수 있습니다.

Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

%d 블로거가 이것을 좋아합니다: