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)

동기 커밋 모드에서는 트랜잭션이 주 서버와 보조 서버에 모두 기록될 때까지 커밋이 완료되지 않습니다. 이 모드에서는 데이터가 주 서버와 보조 서버 간에 실시간으로 동기화됩니다.

  • 동작 과정:
    1. 주 서버에서 트랜잭션이 시작됩니다.
    2. 트랜잭션 로그가 주 서버에서 기록됩니다.
    3. 주 서버는 보조 서버에 로그 기록을 보냅니다.
    4. 보조 서버는 로그를 수신하고 해당 트랜잭션을 재생하여 데이터 파일에 기록합니다.
    5. 보조 서버가 주 서버에 로그 기록 완료를 확인합니다.
    6. 주 서버는 클라이언트에 트랜잭션 커밋 완료를 확인합니다.

이 모드는 데이터 일관성을 높이지만, 네트워크 대기 시간 및 보조 서버의 성능에 따라 트랜잭션 성능에 영향을 미칠 수 있습니다.

2. 비동기 커밋 모드 (Asynchronous Commit Mode)

비동기 커밋 모드에서는 주 서버에서 트랜잭션이 커밋되면 보조 서버에 즉시 로그를 보내지만, 보조 서버의 확인을 기다리지 않습니다. 이 모드는 성능을 향상시키지만 데이터 일관성이 보장되지 않을 수 있습니다.

  • 동작 과정:
    1. 주 서버에서 트랜잭션이 시작됩니다.
    2. 트랜잭션 로그가 주 서버에서 기록됩니다.
    3. 주 서버는 보조 서버에 로그 기록을 보냅니다.
    4. 주 서버는 보조 서버의 확인을 기다리지 않고 클라이언트에 트랜잭션 커밋 완료를 확인합니다.
    5. 보조 서버는 수신한 로그를 재생하여 데이터 파일에 기록합니다.

이 모드는 네트워크 대기 시간에 관계없이 트랜잭션 성능이 우수하지만, 장애가 발생할 경우 주 서버와 보조 서버 간의 데이터 불일치가 발생할 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다