필자는 새로운 프로젝트를 시작함에 있어서, AWS Aurora mysql에 Replication을 적용했다.
Master DB, Slave DB로 나눠 동일한 데이터를 가지고 있게 한 후, select요청은 Slave DB에서만 담당하게 하고, CUD요청은 Master DB에서 담당하게 한다. Master DB는 CUD를 처리한 후 Slave DB에 데이터를 동기화 시킨다. 경우에 따라 slave DB를 여러개 두기도 하지만, 우리는 각각 하나씩 둔 상태이다.
일반적으로 이러한 replication 적용을 springboot를 통해 구현할려고 할 떄, datasource를 2개 등록해준다고 알고 있다. (master용과 slave용도) 그리고 AbstractRoutingDataSource라는 인터페이스를 통해, Transaction 속성을 통해서, 처리를 분리한다.
그런데 구현을 위해 자료를 찾아보던 중, 뭔가 특이한 점들을 발견하게 됐다. 몇 가지 자료 중, 이러한 분기 라우팅을 자동으로 구현해주는 인터페이스가 JDBC 내에 존재한다는 것이다.
LoadBalacing 기능이 mysql Connector에 존재한다는 것이다. 실제로 테스트를 해보았다.
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:replication://{clustring master host}:3306,{clustring slave host}:3306/test?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8
username: "{username}"
password: "{password}"
hikari:
maximum-pool-size: 5
@Test
fun readWriteReplicationTest(){
readReplicaUrl()
writeReplicaUrl()
}
@Transactional(readOnly = true)
fun readReplicaUrl(){
val connection = dataSource.getConnection()
println("read cluster url")
println(connection.metaData.url)
}
@Transactional
fun writeReplicaUrl(){
val connection = dataSource.getConnection()
println("write cluster url")
println(connection.metaData.url)
}
찍히는 connection이 달라졌다.. 장기적으로 봤을 때, 이렇게 마법을 통해서 구현하기보다 custom하게 직접 만드는 게 나은 방향이 아닌가 하지만.. 당장은 이런 식으로 구현해도 문제가 없을 것 같다..