다음을 통해 공유


Azure Database for MySQL - 유연한 서버의 최적 성능을 위한 모범 사례

Azure Database for MySQL 유연한 서버로 작업하는 동안 최상의 성능을 얻는 방법을 알아봅니다. 플랫폼에 새로운 기능이 추가되면 이 섹션의 권장 사항이 계속 개선됩니다.

물리적 근접성

응용 프로그램과 데이터베이스를 동일한 지역에 배포해야 합니다. 성능 벤치마킹 실행을 시작하기 전에 빠른 검사로 간단한 SELECT 1 쿼리를 사용하여 클라이언트와 데이터베이스 간의 네트워크 대기 시간을 확인합니다.

웹 애플리케이션 및 관련 데이터베이스와 같은 리소스가 다른 지역에서 실행되는 경우 해당 리소스 간의 통신 대기 시간이 증가할 수 있습니다. 별도의 지역에 있는 애플리케이션과 데이터베이스가 있는 경우의 또 다른 부작용은 아웃바운드 데이터 전송 비용과 관련됩니다.

비용 최적화 배포에서 애플리케이션의 성능과 안정성을 향상시키려면 웹 애플리케이션 서비스 및 Azure Database for MySQL 유연한 서버 리소스가 동일한 지역 및 가용성 영역에 있는 것이 좋습니다. 이 공동 배치는 대기 시간이 중요한 애플리케이션에 가장 적합하며 리소스가 긴밀하게 연결되므로 최상의 처리량도 제공합니다.

가속된 네트워킹

Azure 가상 머신, Azure Kubernetes 또는 App Services를 사용하는 경우 애플리케이션 서버에 가속화된 네트워킹을 사용합니다. 가속화된 네트워킹을 사용하면 VM에 대한 SR-IOV(단일 루트 I/O 가상화)를 구현할 수 있어 네트워킹 성능이 크게 향상됩니다. 이 고성능 경로는 데이터 경로에서 호스트를 우회함으로써 대기 시간, 지터 및 CPU 사용률을 줄이므로 지원되는 VM 유형에서 가장 까다로운 네트워크 워크로드에 사용합니다.

연결 효율

새 연결 설정 작업은 항상 비용과 시간이 많이 걸립니다. 응용 프로그램은 데이터베이스 연결을 요청할 때 새 유휴 데이터베이스 연결을 만드는 대신 기존 유휴 데이터베이스 연결의 할당을 우선적으로 적용합니다. 다음은 좋은 연결 방법에 대한 몇 가지 옵션입니다.

  • ProxySQL: 기본 제공 연결 풀링이 있으며 애플리케이션 코드를 변경하여 요청 시 필요에 따라 워크로드 부하를 읽기 복제본 여러 개로 분산하는 ProxySQL을 사용합니다.

  • Heimdall Data Proxy: 또는 공급업체 중립적 독점 프록시 솔루션인 Heimdall Data Proxy를 사용할 수도 있습니다. 복제 지연 검색을 사용하여 쿼리 캐싱 및 읽기/쓰기 분할을 지원합니다. Heimdall 프록시를 사용하여 MySQL 성능을 가속화하는 방법을 참조할 수도 있습니다.

  • 영구적 또는 장기간 연결: 애플리케이션에 짧은 트랜잭션이나 5-10밀리초 미만의 실행 시간을 갖는 쿼리가 포함된 경우, 단기간 연결을 영구적 연결로 바꿉니다. 단기간 연결을 영구 연결로 대체하려면 코드를 약간 변경해야 하지만 많은 일반적인 응용 프로그램 시나리오에서 성능 향상에 큰 영향을 줍니다. 트랜잭션이 완료되면 시간 제한을 설정하거나 연결을 닫아야 합니다.

  • 복제본: 복제본을 사용하는 경우 ProxySQL을 사용하여 주 서버와 읽기 가능한 보조 복제본 서버 간의 부하를 분산합니다. ProxySQL을 설정하는 방법을 알아봅니다.

연결 풀링

연결 풀링은 데이터베이스 연결 만들기와 할당을 관리하고 연결 급증으로부터 데이터베이스를 보호하는 메커니즘입니다. 애플리케이션이 비교적 짧은 시간에 많은 연결을 열고 연결 수명이 짧은 경우 연결 풀링을 사용하는 것이 좋습니다. 예를 들어 이러한 형식의 연결은 초당 수백 개 또는 수천 개 이상 발생할 수 있으며 이러한 연결을 설정하고 닫는 데 걸리는 시간은 총 연결 수명 보다 중요합니다.

애플리케이션의 개발 프레임워크가 연결 풀링을 지원하지 않는 경우 대신 애플리케이션과 데이터베이스 서버 간에 ProxySQL 또는 Heimdall 프록시와 같은 연결 프록시를 사용합니다.

연결 크기 조정 처리

변동하는 수요가 충족되도록 웹 애플리케이션 크기를 조정하는 일반적인 방법은 애플리케이션 서버를 추가하고 제거하는 것입니다. 각 애플리케이션 서버는 데이터베이스에서 연결 풀을 사용할 수 있습니다. 이 방법을 사용하면 데이터베이스 서버의 총 연결 수가 애플리케이션 서버 수와 관련하여 증가합니다. 예를 들어 데이터베이스 서버에 애플리케이션 서버가 10개 있고 각각 데이터베이스 연결 100개에 구성된 경우 데이터베이스 연결 1000개를 제공합니다. 더 높은 사용자 작업으로 인해 또는 사용량이 많은 시간 동안 애플리케이션 워크로드가 확장되고 애플리케이션 서버 50개가 추가되면 데이터베이스 연결은 총 6,000개입니다. 일반적으로 이러한 연결의 대부분은 애플리케이션 서버에서 생성된 후에 유휴 상태가 됩니다. 유휴 연결은 리소스(메모리 및 CPU)를 계속 열어 두기 때문에 데이터베이스 확장성에 영향을 미칠 수 있습니다.

추가적인 잠재적 문제는 데이터베이스 서버에 대한 총 연결 수를 처리하는 것입니다. 이는 각각 자체 연결 세트를 만드는 데이터베이스 서버에 연결된 애플리케이션 서버 수에 의해 결정됩니다. 이러한 시나리오에서는 애플리케이션 서버에서 연결 풀을 조정하는 것이 좋습니다. 데이터베이스 서버 쪽에 연결이 bloat이 없도록 각 풀의 연결 수를 허용 가능한 최소값으로 줄이십시오. 애플리케이션 증가를 해결하도록 영구 솔루션이 아닌 애플리케이션 서버 크기 조정의 영향에 대응하는 단기적 해결 방안으로 고려합니다.

장기 솔루션으로 데이터베이스 서버와 애플리케이션 서버 간에 ProxySQL 또는 Heimdall 프록시와 같은 연결 프록시를 도입합니다. 이렇게 하면 프록시가 다음을 수행하므로 도움이 됩니다.

  • 연결 수를 고정하여 데이터베이스 서버에 대한 연결을 설정합니다.
  • 애플리케이션 연결을 수락하고 잠재적인 연결 폭증에 대한 버퍼 역할을 합니다.

프록시는 쿼리 캐싱, 연결 버퍼링, 쿼리 다시 쓰기/라우팅 및 부하 분산과 같은 다른 기능을 제공할 수 있습니다. 확장성을 향상하려면 프록시 인스턴스를 여러 개 사용하는 것이 좋습니다.

내결함성 및 빠른 복구를 위한 연결 처리

내결함성 및 빠른 복구를 위해 애플리케이션 및 환경을 디자인할 때 데이터베이스 환경에서 연결 중단 또는 하드웨어 오류가 발생할 수 있음을 고려합니다. 또한 인스턴스 크기 조정, 패치 및 수동 장애 조치(failover) 수행과 같은 운영 작업의 필요성도 기억해야 합니다.

예를 들어 데이터베이스 서버가 1분 이내에 장애 조치(failover)를 완료하지만 DNS TTL이 애플리케이션 쪽에서 너무 길음과 같은 문제로 인해 애플리케이션이 몇 분 동안 중단되는 시나리오를 고려해 보세요. 이러한 경우 간단히 TTL 값을 줄이면 복구가 더 빨라지거나 애플리케이션과 데이터베이스 서버 간에 연결 프록시를 통합하면 이러한 실패를 처리하는 데 도움이 될 수 있습니다.

파티션

프로덕션 워크로드에서 매우 큰 테이블을 사용하는 경우 분할은 데이터베이스 성능을 향상시키고 유지 관리를 용이하게 하는 좋은 방법입니다. 분할을 사용하면 큰 테이블을 보다 쉽게 관리할 수 있습니다. 이 방법을 사용하면 파티션을 추가 및 삭제하여 큰 테이블을 효과적으로 관리할 수 있습니다. 분할은 테이블당 또는 인덱스당 내부 잠금(예: InnoDB의 btr_search_latch 고려)과 같은 내부 구조 경합을 완화하여 엔진 크기를 조정하는 데 도움이 될 수 있습니다.

예를 들어 파티션 5개를 추가하면 작업이 많은 큰 테이블을 더 작고 효율적인 테이블 5개로 분할합니다. 이는 주로 기본 작업이 테이블의 기본 키 조회인 경우에 도움이 되므로 쿼리가 "파티션 정리"를 활용할 수 있습니다. 그러나 분할은 테이블 검색 측면에서도 도움이 될 수 있습니다.

분할에는 이점이 있지만 분할된 테이블의 외장 키에 대한 지원 부족, 쿼리 캐시 부족 등과 같은 몇 가지 제한 사항도 있습니다. 이러한 제한 사항의 전체 목록은 MySQL 참조 설명서에서 분할에 대한 제한 사항 및 제한 장을 참조하세요.

읽기 및 쓰기 분리

대부분의 애플리케이션은 주로 쓰기와 관련된 상호 작용의 일부만 사용하여 데이터베이스에서 읽습니다. 연결 풀에 계산한 주 데이터베이스의 활성 연결 수에는 읽기 트래픽이 포함됩니다. 가능한 한 많은 쿼리로 오프로드하여 복제본을 읽고 쓰기 가능한 주 인스턴스에 대한 액세스를 절약하면 주 데이터베이스에 대한 부하가 증가하지 않고 애플리케이션 서버에서 수행하는 전체 데이터베이스 작업 양이 증가합니다. 보고서와 같이 더 오래 실행되는 쿼리를 위해 읽기 복제본에 아직 액세스하지 않은 경우 즉시 보고 또는 분석을 읽기 복제본으로 이동하는 것이 좋습니다.

복제의 비동기 특성으로 인해 복제본이 주 복제본보다 약간 뒤처지므로 읽기 복제본을 더 광범위하게 사용하려면 더 신중한 고려가 필요할 수 있습니다. 사소한 코드 변경 사항으로 복제본의 읽기에서 제공될 수 있는 애플리케이션의 영역을 최대한 많이 찾습니다. 또한 캐싱과 관련하여 더 높은 수준에서 이 방법을 적용해야 합니다. Azure Cache for Redis와 같은 전용 캐싱 계층에서 읽기 전용 또는 느리게 변경되는 콘텐츠를 더 많이 제공합니다.

크기 조정 및 분할 작성

시간이 경과함에 따라 애플리케이션이 진화하고 새로운 기능이 추가됩니다. 편의상 또는 일반적인 관행에서 테이블은 주 데이터베이스에 추가됩니다. 데이터베이스에서 증가하는 트래픽 부하를 처리하려면 별도의 데이터베이스로 간편하게 이동할 수 있는 애플리케이션의 영역을 식별하고 데이터베이스를 가로 분할하거나 세로 분할하는 것이 좋습니다.

데이터베이스 가로 분할은 별도의 데이터베이스에 애플리케이션 스키마 복사본을 여러 개 만들고 고객 ID, 지리 또는 다른 일부 고객별 또는 테넌트 특성에 따라 고객과 모든 관련 데이터를 분리하는 방식으로 작동합니다. 이는 개별 고객이 작고 애플리케이션의 부하가 수백만 고객의 집계 사용량에서 비롯되는 SaaS 또는 B2C 애플리케이션에 매우 적합합니다. 그러나 고객이 크기가 다르고 개별 대형 고객이 특정 분할된 데이터베이스의 트래픽 부하를 지배할 수 있는 B2B 애플리케이션에서는 더 어렵습니다.

데이터베이스를 기능적으로 분할하여 부하를 세로 분할합니다. 별도의 애플리케이션 도메인(또는 마이크로 서비스)을 자체 데이터베이스로 이동합니다. 이렇게 하면 주 데이터베이스에서 별도의 서비스별 데이터베이스로 부하가 분산됩니다. 간단한 예제에는 로드가 많은 주문 테이블과 동일한 데이터베이스에 있을 필요가 없는 로깅 테이블이나 사이트 구성 정보가 포함됩니다. 더욱 복잡한 예제로는 주문 또는 처리 도메인을 제외한 고객과 계정 도메인 분리가 포함됩니다. 경우에 따라 전자 메일 또는 백그라운드 작업 큐를 자체 포함되도록 수정하고 고객 또는 주문 테이블에 다시 조인을 사용하지 않도록 애플리케이션을 변경해야 할 수 있습니다. Azure Database for MySQL 유연한 서버 읽기 복제본을 사용하여 기존 테이블 및 데이터를 새 주 데이터베이스로 이동하고 복제본을 승격하고 애플리케이션의 일부를 새로 만든 쓰기 가능한 데이터베이스로 가리키도록 할 수 있습니다. 새로 만든 데이터베이스에서는 원래 주 데이터베이스와 마찬가지로 연결 풀로 액세스를 제한하고 쿼리를 조정하며 자체 복제본으로 부하를 분산해야 합니다.

데이터 가져오기 구성

  • 데이터 가져오기 작업을 시작하기 전에 인스턴스를 더 높은 SKU 크기로 임시로 확장한 다음 가져오기가 성공할 경우 규모를 축소할 수 있습니다.
  • 온라인 또는 오프라인 마이그레이션을 위해 온-프레미스 MySQL을 Azure Database for MySQL로 마이그레이션하여 가동 중지 시간을 최소화하면서 데이터를 가져올 수 있습니다.

Azure Database for MySQL 유연한 서버 메모리 권장 사항

Azure Database for MySQL 유연한 서버 성능 모범 사례는 작업 집합이 거의 완전히 메모리에 상주할 수 있도록 충분한 RAM을 할당하는 것입니다.

  • Azure Database for MySQL 유연한 서버에 대한 메트릭을 사용하여 제한에 도달하는 데 사용되는 메모리 백분율을 확인합니다.
  • 서버가 한도에 도달하면 이를 확인할 수 있도록 이러한 숫자에 대한 경고를 설정합니다. 그러면 문제가 해결되도록 프롬프트 작업을 수행할 수 있습니다. 정의된 한도에 따라 데이터베이스 SKU를 더 높은 계산 크기나 더 나은 가격 책정 계층으로 확장하여 성능이 크게 향상되는지 확인합니다.
  • 크기 조정 작업 후 성능 숫자가 더 이상 크게 떨어지지 않을 때까지 확장합니다. DB 인스턴스의 메트릭을 모니터링하는 방법에 대한 자세한 내용은 Azure Database for MySQL 유연한 서버 DB 메트릭을 참조하세요.

InnoDB 버퍼 풀 사용 준비

Azure Database for MySQL 유연한 서버 인스턴스가 다시 시작되면 테이블이 쿼리될 때 스토리지에 있는 데이터 페이지가 로드되어 쿼리의 첫 번째 실행에 대한 대기 시간이 증가하고 성능이 저하됩니다. 대기 시간이 중요한 워크로드에는 허용되지 않을 수 있습니다.

InnoDB 버퍼 풀 준비를 활용하면 DML 또는 SELECT 작업이 해당 행에 액세스할 때까지 기다리는 대신 다시 시작 전 버퍼 풀에 있던 디스크 페이지를 다시 로드하여 준비 기간이 단축됩니다.

Azure Database for MySQL 유연한 서버 인스턴스를 다시 시작한 후 준비 기간을 줄일 수 있습니다. 이는 InnoDB 버퍼 풀 서버 매개 변수를 구성하여 성능 이점을 나타냅니다. InnoDB는 서버 종료 시 각 버퍼 풀에 대해 최근에 사용된 페이지의 백분율을 저장하고 서버 시작 시 이러한 페이지를 복원합니다.

또한 성능이 향상되면 서버의 시작 시간이 길어진다는 점을 이해해야 합니다. 이 매개 변수를 사용하도록 설정한 경우, 서버에 프로비전된 IOPS에 따라 서버 시작 및 다시 시작 시간이 늘어날 수 있습니다.

이 시간 동안 서버를 사용할 수 없으므로, 다시 시작 시간을 테스트하고 모니터하여 시작/다시 시작 성능이 적절한지 확인하는 것이 좋습니다. 프로비전된 IOPS가 1000 미만인 경우(즉, 프로비전된 스토리지가 335GB 미만인 경우)에는 이 매개 변수를 사용하지 않는 것이 좋습니다.

서버를 종료할 때 버퍼 풀의 상태를 저장하려면 서버 매개 변수 innodb_buffer_pool_dump_at_shutdownON으로 설정합니다. 이와 비슷하게 서버 시작 시 버퍼 풀 상태를 복원하도록 서버 매개 변수 innodb_buffer_pool_load_at_startupON으로 설정합니다. 서버 매개 변수 innodb_buffer_pool_dump_pct의 값을 낮추고 미세 조정하여 시작/다시 시작 시간에 대한 영향을 제어할 수 있습니다. 이 매개 변수는 기본적으로 25로 설정됩니다.

참고 항목

InnoDB 버퍼 풀 준비 매개 변수는 최대 16TB 스토리지를 포함하는 범용 스토리지 서버에서만 지원됩니다. 자세한 내용은 Azure Database for MySQL 유연한 서버 스토리지 옵션을 참조 하세요.