1만 QPS 이상을 처리하는 DB의 무중단 교체 및 고가용성 환경 구축

HIVE 서비스는 그 특성상 항시 대량의 트래픽을 처리하고 있으므로 그에 따른 시스템 부하를 낮추기 위해 캐시 서버를 운영하고 있습니다. 그런데 캐시 서버 군의 장애가 발생하면서 DB 서버의 성능상 한계를 발견하게 되었습니다. 어플리케이션 서버의 요청을 캐시 서버가 응답하지 못하므로 그 만큼의 트래픽이 DB 서버로 유입되었습니다. 어플리케이션 서버는 요청에 대한 응답을 받지 못해 타임아웃이 발생하였습니다. 이 시점에 DB 시스템의 CPU 사용률이 100%로 증가하나 쿼리에 대한 응답 지연이 발생하지는 않은 것을 보면 OS에서 네트워크 패킷을 처리할 수 있는 수용량의 한계에 도달한 것으로 예상됩니다. 하지만 이에 대한 사례 또는 기술자료는 찾지 못했습니다. 

 

 DB 시스템의 패킷 수신량

그림 1. DB 시스템의 패킷 수신량

 

위와 같은 상황에서는 서비스 영향을 최소화하기 위하여 쿼리를 분산시킬 수 있는 구조가 필요하다는 판단을 하였습니다. 

 

목차

  • 기존 서버 구성
  • 신규 서버 구성
  • 작업 준비
  • 서버 교체 작업

 

기존 서버 구성

SQL Server의 일반적인 미러링 구성과 같이 주 서버 1대와 미러 서버 1대를 운영하고 있었습니다. 각 서버의 사양은 다음과 같습니다. 

 

  • CPU : Intel(R) Xeon(R) CPU E5-4657L 2.4GHz 12 Core, CPU 4개
  • 메모리 : 256 GB
  • 디스크 구성 : 
    • 볼륨 1 : SSD × 2 (RAID 1)
    • 볼륨 2 : SSD × 6 (RAID 10)
    • 볼륨 3 : SAS × 12 (RAID 10)
    • 볼륨 4 : SAS × 6 (RAID 10)
    • 볼륨 5 : SAS × 6 (RAID 10)
  • 소프트웨어 : 
    • Windows Server 2008 R2 Enterprise
    • SQL Server 2008 R2 (SP2) Enterprise Edition – 10.50.4033.0
  • 쿼리 처리량
    • 초당 배치 요청 : 최대 46,000, 평균 11,000

 

DB 시스템의 초당 쿼리 처리 건수

그림 2. DB 시스템의 초당 쿼리 처리 건수

 

 

신규 서버 구성

 

기존 장비는 도입 후 5년이 경과하여 교체 시기가 되었습니다. 향후 유저 증가를 대비하기 위해 기존 장비 보다 하드웨어 리소스를 안정적으로 사용하면서 더 많은 쿼리를 처리할 수 있는 장비를 선정하기 위해 벤치마크테스트를 진행했습니다. 그 결과 선정된 장비의 사양은 다음과 같습니다. 

 

  • CPU : Intel(R) Xeon(R) Gold 6154 CPU 3.00GHz 18 Core, CPU 4개
  • 메모리 : 512 GB
  • 디스크 구성
    • 볼륨 1 : SSD × 2 (RAID 1)
    • 볼륨 2 : SSD × 2 (RAID 1)
    • 볼륨 3 : SSD × 16 (RAID 10)
    • 볼륨 4 : SSD × 2 (RAID 1)
    • 볼륨 5 : SSD × 2 (RAID 0)

 

Always On 가용성 그룹 기능은 SQL Server 2012 버전에서 도입된 고가용성 솔루션입니다. 가용성 그룹은 장애 조치(Failover) 환경을 지원하고 읽기/쓰기 주 데이터베이스 집합과 1~8개의 해당 보조 데이터베이스 집합을 지원하며 보조 데이터베이스에 대해 읽기 전용 액세스를 설정할 수 있습니다.

 

복제본의 가용성 및 장애 조치 모드

그림 3. 복제본의 가용성 및 장애 조치 모드

 

주 서버와 보조 서버 간의 동기화 방식은 동기와 비동기 방식을 지원합니다. 

  • 동기 : 주 서버에서 보조 서버까지 로그가 전달된 상태에서 커밋
  • 비동기 : 주 서버에 보조 서버까지 로그가 전달되지 않더라도 커밋

 

동기 방식의 경우 주 서버와 보조 서버의 동기화로 인한 네트워크 속도와 로그 쓰기 속도가 주 서버의 쿼리 속도에 포함되므로 주 서버의 쿼리 처리 속도를 높이기 위하여 비동기 방식을 선택했습니다. 

 

SQL Server의 버전에 따라 가용성 그룹 기능의 동작에 차이가 있습니다. 

  • SQL Server 2016 이상 : 읽기 전용 라우팅 사용 시 보조 서버 여러대로 라우팅 가능
  • SQL Server 2016 미만 : 읽기 전용 라우팅 사용 시 보조 서버 1대로만 라우팅 가능

 

읽기 전용 라우팅 사용 시 접속을 위한 트래픽은 주 서버에서 처리하지만 데이터에 대한 트래픽은 라우팅 이후에 보조 서버에 처리하므로 여러 서버로 읽기 라우팅이 가능한 버전을 우선 고려했습니다. 최신 버전인 SQL Server 2017은 국내에서 레퍼런스를 찾지 못하여 안정성을 고려하여 SQL Server 2016 Enterprise Edition – 13.0.5366.0 버전을 선택했습니다. 

 

SQL Server 2012 버전부터는 Windows Server 2012 이상의 버전을 요구합니다. 당사에서는 운영 경험이 있는 Windows 2012 R2 Standard 버전을 선택했습니다. 

 

작업 준비

 

가용성 그룹 구성 후 읽기 전용 라우팅에 소모되는 주 서버의 사용 리소스에 대해 검토하였습니다. 이를 위해 스레드를 여러 개 생성하여 커넥션 생성, 쿼리, 커넥션 해제 과정을 반복 실행하는 테스트를 수행했습니다. 그리고 SQL Server 프로파일러를  통해 주 서버의 커넥션 정보 유입, 보조 서버의 커넥션 정보와 질의 유입 내역을 조사했습니다. 주 서버와 보조 서버의 유입 패킷을 측정하였고 주 서버에서 처리하는 패킷 량은 테스트 패킷의 6~7% 수준이었습니다. 

 

HIVE 서비스의 중요한 역할을 담당하고 있는 DB 서버이므로 게임을 이용하는 유저에게 장비 교체 작업으로 인한 영향을 최소화 할 수 있는 작업 방법을 고려할 필요가 있었습니다. 모바일 게임은 한번 로그인이 되면 그 상태를 유지하는 것이 일반적이므로, 기존 유저는 자동 로그인 기능만 유지되어도 인증 후 게임을 이용하는데 영향이 없습니다. 

 

이 점에 착안하여 자동 로그인을 제외한 기능을 어플리케이션 서버에서 비활성화하여 DB 서버에 트랜젝션 로그가 발생하지 않도록 하고 예상치 못한 쿼리가 유입되어 트랜잭션 로그가 발생하는 것을 방지하기 위하여 DB 서버를 읽기 전용으로 변경하기로 했습니다. 각 DB 계정의 권한을 변경하는 방식도 가능하지만, HIVE 서비스가 스테이트리스(stateless) 형태인 것을 고려하면 순간적인 어플리케이션 서버의 접속 오류가 유저에게는 치명적이지 않으므로 안정적인 작업을 위하여 읽기 전용 DB로 변경하는 방식이 적합하다고 판단하였습니다. 이 상태에서 신규 서버의 가용성 그룹 구성과 데이터 동기화를 완료한 뒤에 어플리케이션 서버가 접속하는 DB 서버의 IP를 변경하는 방식으로 작업을 계획하였습니다.

 

가용성 그룹 구성과 장비 변경 작업에 대한 절차와 소요 시간 산정하였습니다. 이 작업 계획을 검증하기 위하여 실제 작업 환경에서 시뮬레이션 진행 후 그 결과를 반영하여 분 단위의 최종 작업 계획을 수립했습니다. 

 

서버 교체 작업

 

작업 내역

  • 00:00 ~ 00:07 기존 서버의 리소스 사용량 축소를 위해 SQL 에이전트 스케줄 조정과 미러링 해제
  • 00:10 ~ 01:08 기존 서버의 전체 백업
  • 01:08 ~ 02:30 통계 스케줄에 영향이 없도록 기존 서버의 전체 백업을 통계 서버로 복사
  • 02:30 ~ 03.29 기존 서버의 전체 백업을 주 서버에 복사
  • 03:29 ~ 06:16 주 서버에서 보조 서버에 전체 백업 파일 복사
  • 03:48 ~ 05:40 기존 서버의 2차 백업
  • 06:00 기존 서버의 트랜잭션 로그 백업 활성화
  • 06:16 ~ 06:53 신규 서버에 전체 백업 복구
  • 07:00 ~ 15:00 기존 서버의 트랜잭션 로그를 신규 서버에 복구
  • 15:00 ~ 15:14 HIVE 기능 제한 패치
    • 자동 로그인 접속 유지
    • 회원가입 또는 로그인 버튼 클릭 시 점검 안내 문구 노출
  • 15:14 ~ 15:17 기존 서버를 읽기 전용 DB로 변경
  • 15:17 ~ 15:22 기존 서버에 읽기 전용 변경 전까지의 트랜잭션 로그 복구
  • 15:22 ~ 15:23 신규 장비에 대해 가용성 그룹 구성
  • 15:23 ~ 15:41 특정 클라우드 내 어플리케이션 서버의 IP 관련 오류 발생에 따른 조치
  • 15:41 ~ 16:18 HIVE 서비스를 신규 서버의 IP로 변경 후 기능 제한 패치 롤백

 

실제 작업 시에는 특정 퍼블릭 클라우드 내 어플리케이션 서버에서 예상치 못한 오류가 발생하여 계획 대비 8분이 지연되었습니다. 하지만 예상과 같이 DB 교체 중에 게임 서버의 동시 접속자 수는 평시와 동일하게 유지되었습니다. 

 

작업 시간 동안 게임의 유럽 서버 동시 접속자 수

그림 4. 작업 시간 동안 게임의 유럽 서버 동시 접속자 수

 

작업 직후 동일 쿼리 처리량에 대한 서버 성능 비교

작업이 완료된 뒤에 기존 서버와 신규 서버의 성능을 비교하였습니다. 

 

기존 서버와 신규 서버 성능 비교

표 1. 기존 서버와 신규 서버 성능 비교

 

향후 운영 시 고려할 사항

 

기존 운영 경험에 따르면 DB 시스템은 서버의 하드웨어 장애 보다는 네트워크 지연이 발생 빈도가 높았습니다. 네트워크 지연으로 인한 페일오버의 발생을 방지하기 위해 페일오버를 자동으로 설정하지 않고, 모니터링을 통해 서버의 문제를 감지했을 때 수동으로 페일오버를 수행하기로 하였습니다. 

 

주 서버의 처리 성능을 극대화 시키기 위하여 보조 서버와의 네트워크 동기화 리소스를 최소화시키고자 비동기 방식으로 보조서버와 동기화를 구성했습니다. 따라서 읽기 전용 서버는 초 단위 지연 데이터를 조회해도 서비스에 영향이 없는 쿼리에만 사용해야 합니다. 다시 말하면 갱신된 데이터를 바로 조회할 경우에는 주 서버에 쿼리를 해야 합니다. 

 

DB 서버별 네트워크와 같은 외부 이슈로 인한 서비스 영향을 최소화하기 위하여 가용성 그룹 수신기를 사용하여 읽기 전용 라우팅을 통한 분산을 사용하였습니다. 가용성 그룹 수신기 사용 시에는 주 서버가 보조 서버로 라우팅 시키는 역할을 하는 구조이므로 읽기 분산을 위한 주 서버 리소스가 사용됩니다. 당사의 시스템 구조에서는 주 서버의 OS 레벨에서 네트워크 처리 한계에 도달할 경우 장애가 발생할 수 있는 구성이므로 모니터링을 통하여 네트워크 임계치가 초과되었을 경우 어플리케이션 서버에서 가용성 그룹 수신기를 사용하지 않고 직접 읽기 전용 서버로  접속하도록 수정하여 과도한 네트워크 트래픽으로 인한 장애를 방지해야 합니다. 

 

맺음말

 

시스템의 한계나 문제점이 발견되었을 경우에는 이를 개선하기 위해 새로운 솔루션의 도입이 필요할 때가 있습니다. 다양한 솔루션이 존재하지만 충분히 검토한 후 우리 시스템에 적합한 솔루션을 도입해야 한다고 생각합니다. 

 

물론 우리의 문제점을 보완하는 작업이 고객에게 불편함을 주지 않으면 좋겠지만 만약 불편함이 발생해야 한다면 최소화할 수 있는 방법을 고민해야겠습니다. 이를 위해 때로는 노가다성 작업이 필요할 수도 있겠습니다.