2013년 7월 6일 토요일

MySQL Replication 환경 하에서 Hibernate 사용하기

타 RDBMS 보다 MySQL이 좋은 점 중에 하나가 다중 서버 환경으로의 전환이 용이하고, 안정적이라는 점이다. 보통의 Legacy 시스템에서는 RDBMS 서버 한대를 두고, 백업 서버를 두는 방식을 택하고, 성능이 모자라면 scale up 을 수행하는데, MySQL은 Replication을 이용하여 scale out 을 수행하므로서 부하 분산으로 성능을 높히는 방식입니다.



Hibernate의 경우 SessionFactory가 RDBMS 와 1:1 매핑이 되는 관계라 위와 같이 멀티 서버의 경우에는 중간에 Proxy 서버를 두던가,  MySQL Replication Driver 를 이용해야 합니다.
Proxy 서버를 둔다는 것은 Clustering 을 구성하는 것과 같으니 Proxy 서버 주소만 알면 되지만, Replication Driver를 사용 시에는 Master / Slave 서버별로 작업의 특성에 따라 구분해 줘야 합니다.

즉 Master 서버는 Read/Write를 할 수 있지만, Slave 서버는 Read 작업만 수행해야 합니다. 이렇게 하려면 작업 전에 Connection 의 isReadOnly 속성을 변경하여, 원하는 종류의 서버를 선택하게끔 해야 합니다.

이를 위해 Spring AOP 를 이용하여, 작업 시작 전에 작업 종류에 따라 Connection 속성을 변경하는 interceptor 를 제작합니다.

ConnectionInterceptor.java

line 11 에 있는 @Arount 를 보시면,  ReadOnlyConnection 이라는 annotation 이 있는 메소드를 intercept 하도록 합니다.  이 메소드는 readonly 작업을 뜻하므로 connection의 readonly 값을 true 로 하여, MySQL 의 Slave 서버에 접속하도록합니다.

ReadOnlyConnection annotation은 메소드에만 적용되도록 합니다.

ReadOnlyConnection.java

자 이제 테스트를 위한 서비스를 제작해 봅시다.

SimpleEntityServiceImpl.java
서비스 클래스에서 조회 메소드에서 @ReadOnlyConnection 을 사용하므로서 AOP 를 통해 ConnectionInterceptor 를 통해, Slave 서버에 접속하도록 했습니다.

이를 통해 Master/Slave 를 구분하고,  여러대의 Slave 도 Replication Driver 가 RoundRobin 방식으로  서버를 지정해주니, Application 개발자는 RDBMS 환경에 크게 신경 쓰지 않고, 자신의 분야에만 집중 할 수 있게 될 겁니다^^

또 한가지 SessionFactory가 하나로 유지되므로, 2nd Cache 도 하나가 되므로, 성능상의 잇점과 Cache와의 불일치에 대해 다른 방식보다 어느 정도 잇점이 있을 것입니다

댓글 없음: