AlwaysOn 가용성 그룹의 주서버/보조서버 활용하기
ㆍ주 서버(Primary) vs 보조서버(Secondary)
AlwaysOn 가용성 그룹으로 구성된 서버는 일반적으로 온라인 운영을 위한 주서버(Primary) 와 보조서버(secondary)로 구성된다. 주 서버가 모든 운영(데이터처리)에 대한 전반적인 처리를 담당하며, 보조서버는 failover를 위한 주 서버 복제(Replica) 와 대기를 하게된다.
개발시점에서 보면, 사용자를 통해 발생되는 모든 CRUD 는 주 서버를 통해 이루어지고 보조서버는 놀고 있는것 처럼 보인다. 개발단 에서 다루는 데이터의 양이나, 쿼리 복잡도(조인,커서,트리거등) 또는 업무의 복잡성에 따라 DB 에 주는 부하는 커지게 되며, DB에 직접적인 영향을 주게 된다. 이러한 업무를 주서버와 보조서버 분산을 통해 전략적 사용한다면,
보다 빠른 성능으로 업무를 처리할 수 있게 된다.
ㆍ주서버와 보조서버 분산을 통한 사용 전략
AwlaysOn 가용성 그룹, 온라인 상태에서의 주 서버의 역할은 모든 데이터를 다뤄야하기때문에 읽기/쓰기가 가능하며,
보조서버의 역할은 failover를 위한 대비서버로 일관성을 위해 주 서버를 통해서만 Write가 이루어 져야 하기 때문에
Read 만 가능하다.
이를 이용하여, 업무처리에 따라 Write 가 필요 한 곳과 Read 가 필요한 업무를 구분하여 처리 할 수 있다면, 큰 효율성을
가져올수 있게된다.
ㆍRead And Write 와 ReadOnly
위에서 말한 Read 와 Write 를 DB 의 업무에 매칭시켜보면, Read – Select / Write – Insert , Update , Delete 가 될 것이다.
서버 입장에서의 업무로 보자면, 주서버 – Select, Insert, Update, Delete , 보조서버 – Select 가 될 것이다.
주 서버는 모든 작업이 가능하기때문에 , ReadOnly 시점에서 업무를 분석해보면, 전략고민이 간단하게 해결된다.
그렇다, 오직 조회만 하는 페이지 또는 업무에서는 보조서버를 통해 쿼리한다면 부하가 분산되게 된다.
R/W 서버 와 ReadOnly 서버를 구분하여 작업을 처리하는것은 물리적으로 연결을 다르게 하여 , 연결객체를 생성하는 것이다.
[Read/Write 용 연결 스트링]
conn = “provider=SQLOLEDB;Data Source=아이피;initial Catalog=Db명;user id=아이디;password=패스“
[ReadOnly 용 연결 스트링]
conn = “provider=SQLOLEDB;Data Source=아이피;initial Catalog=Db명;user id=아이디;password=패스;Application Intent=ReadOnly“
위의 연결스트링에서 ReadOnly 용의 경우에만 Application Intent=ReadOnly 옵션을 추가해주면 읽기전용 커넥션 객체가 만들어진다.
이때 주의해야할 점은, “Application Intenet” 작성시 반드시 띄어쓰기를 주의해야한다. 나머지는 모두 같다.
위의 2개 연결스트링을 이용해여 2개의 연결 객체를 만들어 놓고
Insert/update/Detete 가 필요할땐, R/W 용 커넥션 객체를, Select 할때는 ReadOnly용 객체를 사용하면,
자동적으로 쿼리처리를 위한 비용이 분산 될뿐 아니라, 서버가용에 있어 어느정도 LB(?) 와 같은 효과를 가져오므로,
퍼포먼스 측면에서도 상당이 도움이 된다.
여기서 주의해야할점 주서버(R/W) 와 보조서버(ReadOnly) 간의 데이터 동기화 시점인데,
실제적으로 주서버에 반영된 데이터의를 보조서버로 업데이트되는 모드에 따라, 알아두어야할 사항있다
아래는 실제 경험한 사례인데(비동기 커밋 모드로 추정됨)
특정 테이블에 R/W 커넥션 객체를 이용해 Insert 를 한후 , 바로즉시 , ReadOnly 객체를 통해 위에 테이블의 데이터를 가져오거나,
방금 등록된 데이터의 키로 select 하려고 조회를 하는데 코드가 작성된경우 , 데이터가 없는 경우가 발생했다.
이는, 내부적으로 주서버 에서 → 보조서버로 데이터 동기화 반영하는 시점보다, 사용자가 먼저 접근했기때문인데
이럴경우는 Read/Write 커넥션 객체를 통해, 주서버에서 쓰기와 읽기를 모두 해결하는것을 추천한다
물론 MSSQL 의 주서버-보조서버의 동기화 모드에 따라, 다를수 있다는점 인지하기 바라고
현업의 상황에 맞게 DBA 와 충분히 상의 하여야할 것이다.
아래는 MSSQL 의 AlwasyOn 가용성그룹에서 주서버 보조서버의 데이터 동기화 모드에 따른 설명이다
1. 동기 커밋 모드 (Synchronous Commit Mode)
동기 커밋 모드에서는 트랜잭션이 주 서버와 보조 서버에 모두 기록될 때까지 커밋이 완료되지 않습니다. 이 모드에서는 데이터가 주 서버와 보조 서버 간에 실시간으로 동기화됩니다.
- 동작 과정:
- 주 서버에서 트랜잭션이 시작됩니다.
- 트랜잭션 로그가 주 서버에서 기록됩니다.
- 주 서버는 보조 서버에 로그 기록을 보냅니다.
- 보조 서버는 로그를 수신하고 해당 트랜잭션을 재생하여 데이터 파일에 기록합니다.
- 보조 서버가 주 서버에 로그 기록 완료를 확인합니다.
- 주 서버는 클라이언트에 트랜잭션 커밋 완료를 확인합니다.
이 모드는 데이터 일관성을 높이지만, 네트워크 대기 시간 및 보조 서버의 성능에 따라 트랜잭션 성능에 영향을 미칠 수 있습니다.
2. 비동기 커밋 모드 (Asynchronous Commit Mode)
비동기 커밋 모드에서는 주 서버에서 트랜잭션이 커밋되면 보조 서버에 즉시 로그를 보내지만, 보조 서버의 확인을 기다리지 않습니다. 이 모드는 성능을 향상시키지만 데이터 일관성이 보장되지 않을 수 있습니다.
- 동작 과정:
- 주 서버에서 트랜잭션이 시작됩니다.
- 트랜잭션 로그가 주 서버에서 기록됩니다.
- 주 서버는 보조 서버에 로그 기록을 보냅니다.
- 주 서버는 보조 서버의 확인을 기다리지 않고 클라이언트에 트랜잭션 커밋 완료를 확인합니다.
- 보조 서버는 수신한 로그를 재생하여 데이터 파일에 기록합니다.
이 모드는 네트워크 대기 시간에 관계없이 트랜잭션 성능이 우수하지만, 장애가 발생할 경우 주 서버와 보조 서버 간의 데이터 불일치가 발생할 수 있습니다.