내보내기(0) 인쇄
모두 확장

Azure 클라우드 서비스에서 대규모 서비스를 디자인하는 방법에 대한 모범 사례

업데이트 날짜: 2014년 1월

저자: Mark Simms 및 Michael Thomassy

참여자: Jason Roth 및 Ralph Squillace

검토자: Brad Calder, Dennis Mulder, Mark Ozur, Nina Sarawgi, Marc Mercuri, Conor Cunningham, Peter Carlin, Stuart Ozer, Lara Rubbelke 및 Nicholas Dritsas

클라우드 컴퓨팅은 분산 컴퓨팅입니다. 분산 컴퓨팅은 어떤 플랫폼을 선택하든 신중한 계획과 배포가 필요합니다. 이 문서의 목적은 실제 고객 시나리오를 기반으로 Azure 및 SQL 데이터베이스에서 PaaS(Platform-as-a-Service) 접근 방식을 활용하여 확장 가능한 응용 프로그램을 빌드하는 상세한 지침을 제공하는 것입니다. 이러한 응용 프로그램은 웹 및 작업자 역할을 사용하여 Azure 클라우드 서비스로 빌드됩니다.

Important중요
참고: 이 문서에 설명된 모든 최상의 방법은 Azure에서 프로덕션 코드를 실행하는 고객과 긴밀한 협력을 통해 나온 결과물입니다. 이 문서에서는 v1.6 SDK 릴리스 기반 Azure 클라우드 서비스(PaaS) 플랫폼에 대해 설명합니다. Azure 웹 사이트 또는 Azure 가상 컴퓨터(IaaS) 등의 기능은 다루지 않습니다.

이 문서는 Azure 응용 프로그램, 주요 Azure 플랫폼 기능, 제한 및 기능을 구축하기 위한 기본 설계 개념과 핵심 Azure 서비스 작업에 대한 최상의 방법을 다루고 있습니다. 일관성이 약한 분산 데이터 저장소(일관성이 엄격한 또는 고밀도 다중 테넌트 데이터 모델의 반대 개념)에 사용할 수 있는 응용 프로그램에 초점을 맞추고 있습니다.

응용 프로그램 및 서비스를 Azure로 전환해야 하는 다음과 같은 여러 가지 매력적인 이유가 있습니다.

  • 자본 지출을 절감하거나 운영 지출에 통합합니다.

  • 수요와 용량을 보다 밀접하게 연결하여 비용을 절감하고 효율성을 개선합니다.

  • 인프라 장벽을 낮추거나 제거하여 민첩성 및 시장 출시 시간을 개선합니다.

  • 고객층을 모바일 장치와 같은 새로운 시장까지 확장합니다.

  • 지리적으로 분산된 데이터 센터에서 글로벌 고객을 지원할 수 있는 새로운 응용 프로그램을 구축하여 클라우드 컴퓨팅의 엄청난 혜택을 누릴 수 있습니다.

새 응용 프로그램을 개발하거나 기존 응용 프로그램의 일부 또는 전체를 Azure로 이식해야 하는 여러 가지 기술적 이유가 있습니다. 다양한 구현 방법이 존재하기 때문에 올바른 구현 접근 방식을 선택하려면 구체적인 응용 프로그램 패턴을 신중하게 평가해야 합니다. 일부 응용 프로그램은 Azure 클라우드 서비스(Platform-as-a-Service 또는 PaaS 접근 방식)에 적합한 반면 다른 응용 프로그램은 Azure 가상 컴퓨터와 같은 부분적 또는 완전한 IaaS(infrastructure-as-a-service)를 활용할 수 있습니다. 마지막으로, 특정 응용 프로그램 요구 사항은 두 가지 접근 방식을 모두 사용하는 것이 최고의 방법이 될 수 있습니다.

Azure 클라우드 서비스의 이점을 극대화하려면 응용 프로그램이 다음과 같은 세 가지 주요 특징 중 하나 이상을 갖고 있어야 합니다. 응용 프로그램이 이러한 특징을 모두 갖추어야 하는 것은 아닙니다. 다음 특징 중 하나만 잘 이용해도 뛰어난 투자 수익률을 얻을 수 있습니다. 그러나 이러한 특징이 전혀 없는 작업에는 Azure 클라우드 서비스가 잘 맞지 않습니다.

응용 프로그램을 평가해야 하는 중요한 특징은 다음과 같습니다.

  • 탄성 수요. Azure로 전환해야 하는 핵심 가치 제안 중 하나는 탄성 수요입니다. 탄성 수요란 응용 프로그램의 용량을 추가 또는 제거(확장 또는 축소)하여 동적 사용자 수요와 보다 밀접하게 연결하는 기능입니다. 사용자 수, 거래 건수 등이 정적이고 수요가 꾸준한 작업의 경우 Azure 클라우드 서비스의 이러한 이점을 극대화할 수 없습니다.

  • 분산된 사용자 및 장치. Azure에서 실행하면 전 세계에 배포된 응용 프로그램에 즉시 액세스할 수 있습니다. 단일 위치(예: 하나의 사무실)에서 실행하는 고정 사용자층을 갖고 있는 작업의 경우 클라우드 배포를 통해서도 최적의 투자 수익률을 얻을 수 없습니다.

  • 분할 작업. 클라우드 응용 프로그램은 규모를 확장하고 그에 따라 작은 청크에 더 많은 용량을 추가합니다. 응용 프로그램에서 확장(예: 대형 데이터베이스 및 데이터 웨어하우스) 또는 특수한 전용 작업(예: 통합된 대형 고속 저장소)에 의존하는 경우 응용 프로그램이 확장 서비스에서 실행되도록 분해(분할)하여 클라우드를 사용할 수 있도록 해야 합니다. 작업에 따라 이것이 매우 중요할 수 있습니다.

다시 한 번 강조하지만, 응용 프로그램을 평가할 때 Azure 클라우드 서비스로 전환하거나 구축하여 뛰어난 투자 수익률을 얻으려면 작업이 앞에서 설명한 Azure 클라우드 서비스 같은 platform-as-a-service 환경에서 장점을 보이는 세 가지 특징 중 하나 이상을 갖고 있어야 합니다. 세 가지 특징을 모두 갖춘 응용 프로그램은 더욱 뛰어난 투자 수익률을 얻을 수 있습니다.

Azure용 응용 프로그램 디자인은 내부 개발과 매우 비슷하면서도 기본 플랫폼 및 서비스의 작동 방식에 있어서 몇 가지 중요한 차이점이 있습니다. 클라우드에서 탄력적인 확장이 가능한 응용 프로그램을 제공하려면 이러한 차이점과 그에 따른 디자인 방법을 이해하는 것이 매우 중요합니다.

이번 단원에서는 Azure 클라우드 서비스 같은 PaaS(Platform-as-a-Service) 환경을 위해 광범위하게 분산된 대규모 확장 응용 프로그램을 구축하기 위한 5가지 핵심 디자인 개념을 간략하게 설명합니다. 세 가지 개념을 이해하면 단지 Azure 클라우드 서비스에서 작동하는 것에서 그치지 않고 Azure 클라우드 서비스를 최대한 활용하여 최고의 투자 수익률을 거둘 수 있는 응용 프로그램을 디자인하여 구축할 수 있습니다. 이 문서의 뒷부분에서 다루게 될 모든 디자인 고려 사항 및 선택 사항은 이러한 5가지 개념 중 하나와 다시 연결됩니다.

또한 이러한 고려 사항과 최고의 방법 중 상당수는 .NET 응용 프로그램의 관점에서 바라본 것이지만 기본 개념 및 접근 방식은 언어나 플랫폼과 별 관계가 없다는 점에 주목해야 합니다.

내부 응용 프로그램에서 Azure 클라우드 서비스로 전환할 때 발생하는 주요 변화는 응용 프로그램의 확장 방식과 관련되어 있습니다. 기존에는 대형 응용 프로그램을 구축할 때 수평 확장(상태 비저장 웹 서버 및 응용 프로그램 서버)과 수직 확장(대형 다중 코어/대용량 메모리 시스템 구입, 데이터베이스 서버, 대규모 데이터 센터 구축 등)을 혼합하여 사용했지만 클라우드에서는 현실적으로 수직 확장이 불가능합니다. 수평 확장을 명시적으로 디자인하는 방법을 통해서만 확장성이 뛰어난 응용 프로그램을 얻을 수 있습니다.

사내 응용 프로그램에는 수평 확장(웹 서버, 응용 프로그램 서버)에 사용할 수 있는 여러 요소가 있지만 수직 확장 서비스에 의존하는 응용 프로그램에서 이러한 요소를 식별하여 수평 확장 구현 요소로 변환(또는 매핑)하는 것이 문제입니다. 수직 확장 종속성의 대표적인 예는 관계형 데이터베이스(SQL Server/Azure SQL 데이터베이스)입니다.

기존의 관계형 디자인은 일관성과 트랜잭션 동작이 엄격한 전 세계적으로 일관적인 데이터 모델(단일 서버 수직 확장)에 집중했습니다. 기존에는 “모든 것을 상태 비저장”으로 만드는 방법으로 이 백업 저장소에 대한 확장 기능을 제공했기 때문에 상태 관리의 책임이 수직 확장 SQL 서버에 있었습니다.

그러나 SQL Server의 놀라운 확장성 때문에 진정으로 탄력적인 확장이 어려웠습니다. 즉, 수직 확장을 할 때마다 응답성이 매우 뛰어난 리소스 대신 마이그레이션 단계가 비싸고 수요를 훨씬 초과하는 용량을 가진 대형 서버를 구입해야 합니다. 뿐만 아니라 확장의 범위가 중급 하드웨어를 초과할 경우 비용이 기하급수적으로 늘어납니다.

수평으로 확장되는 Azure 클라우드 서비스의 구조를 보강하려면 응용 프로그램이 수평 확장 데이터 저장소에서 작동하도록 디자인해야 합니다. 즉, 데이터를 더 작은 청크(데이터 파티션 또는 수평 확장 유닛에 맞는)로 명시적으로 분할하고 분산 데이터 요소 간의 일관성을 관리해야 하는 설계적 어려움이 있습니다. 디자인의 단점을 대부분 방지하는 방법으로 분할하여 수직 확장을 달성할 수 있습니다.

잘 알려진 수직 확장 기술을 중심으로 데이터를 수평 확장하고 상태를 관리하는 것은 클라우드 디자인의 가장 큰 과제 중 하나입니다. 이러한 과제를 해결하고 Azure 클라우드 서비스 및 Azure SQL 데이터베이스의 탄력적인 확장 기능을 활용하여 영구 데이터를 관리할 수 있는 응용 프로그램을 디자인하는 것이 이 문서의 주된 내용입니다.

자체적인 데이터 센터를 운영할 경우 거의 무한한 제어권 및 선택권을 가질 수 있습니다. 에어컨, 전력 공급 장치, 바닥 면적 등의 물리적 시설부터 랙, 서버, 저장소, 네트워킹 등의 인프라를 아우르는 모든 것과 라우팅 토폴로지, 운영 체제 설치 등의 구성을 제어할 수 있습니다.

이 정도 수준의 제어권을 유지하려면 자본, 운영, 인력 및 시간 비용이 많이 듭니다. 수시로 변화하는 환경에서 모든 것을 관리하는 데 드는 비용이 바로 가상화의 핵심이며 클라우드 전환의 주요 관건입니다. 이러한 플랫폼은 제어권을 포기하는 대신 개발 및 관리 비용을 줄이고 민첩성을 향상시킵니다. 이러한 플랫폼을 사용할 때 따르는 제약 조건은 사용 가능한 구성 요소 및 서비스의 크기(용량, 처리량 등)가 제품의 고정된 집합으로 제한된다는 것입니다.

물건을 대량으로 운송할 경우 대부분 컨테이너 단위로 운송되는 것에 비유할 수 있습니다. 컨테이너는 다양한 운송 수단(선박, 기차 및 트럭)에 의해 운송되고 최대 16미터에 이르는 다양한 크기의 표준 컨테이너를 사용할 수 있습니다. 운송하려는 화물의 양이 가장 큰 트레일러의 용량을 초과할 경우 다음 중 한 가지 방법을 사용해야 합니다.

  • 트레일러를 여러 개 사용합니다. 이렇게 하려면 컨테이너 수에 맞춰 화물을 나누고(분할하고) 트레일러의 운송을 조정해야 합니다.

  • 특별한 운송 방법을 사용합니다. 부피가 너무 크거나 그 밖의 이유로 여러 표준 컨테이너에 나누어 적재할 수 없는 화물의 경우 바지선 같은 특별한 방법을 사용해야 합니다. 이러한 방법은 일반적으로 표준 화물 운송보다 훨씬 비쌉니다.

이 비유를 Azure 및 일반적인 클라우드 컴퓨팅에 그대로 적용해 보자면 모든 리소스에는 한계가 있습니다. 개별 역할 인스턴스, 저장소 계정, 클라우드 서비스는 물론이고 심지어 데이터 센터도 마찬가지입니다. Azure의 모든 가용 리소스에는 한계가 있습니다. 가장 큰 화물선의 경우 무려 10,000개가 넘는 컨테이너를 운송할 수 있는 것처럼 데이터 센터에서 사용할 수 있는 저장소의 양이 엄청나게 많기는 하지만 분명 한계가 있습니다.

이러한 제약 조건을 염두에 두고 부하를 여러 확장 단위, 즉 여러 가상 컴퓨터, 데이터베이스, 저장소 계정, 클라우드 서비스 또는 데이터 센터로 나누어 구성하는 접근 방식을 사용해야 합니다.

이 문서에서는 (a)정의된 부하 수준을 처리하고 (b)추가로 구성할 경우 더 많은 부하를 처리할 수 있는 리소스 그룹을 지칭하는 개념으로 확장 단위라는 용어를 사용합니다. 예를 들어 Azure 저장소 계정의 최대 크기는 100TB입니다. 100TB가 넘는 데이터를 저장해야 할 경우 저장소 계정을 여러 개(예: 저장소 확장 단위 2개 이상) 사용해야 합니다.

Azure의 각 핵심 서비스 또는 구성 요소의 용량에 대한 일반적인 디자인 지침은 추가 확장을 위한 서비스 구성 권장 방법과 함께 이 문서의 후반부에서 다루겠습니다.

유연성이 뛰어난 내부 응용 프로그램을 구축하려면 엄청난 시간, 에너지 및 지적 자본이 투입됩니다. 이러한 구축 작업은 일반적으로 응용 프로그램을 낮은 상태 구성 요소(응용 프로그램 서버, 네트워킹)와 높은 상태 구성 요소(데이터베이스, SAN)로 분류하여 각 구성 요소가 오류 모드에 유연하게 대처할 수 있도록 만드는 작업이 포함됩니다.

이러한 맥락에서 오류 모드는 (a)오류 상태의 시스템 및 (b)오류의 원인을 관찰하는 작업과 관련되어 있습니다. 예를 들어 암호 업데이트를 잘못 구성하여 액세스가 불가능한 데이터베이스는 오류 모드가 됩니다. 오류 상태는 연결 불가능(연결 거부, 자격 증명 거부)이고 오류 원인은 응용 프로그램 코드에 적절히 전달되지 않는 암호 업데이트입니다.

낮은 상태 구성 요소는 느슨하게 연결된 중복성을 통해 복구 기능을 제공하며 외부 시스템에 의해 관리되는 시스템과 "통합"됩니다. 예를 들어 부하 분산 장치 뒤에 웹 서버를 추가로 배치합니다. 각 서버는 서로 동일하며(따라서 용량을 새로 추가하는 것이 기본 웹 서버 이미지를 복제하는 문제가 됨) 부하 분산 장치에 의해 관리되는 전체 응용 프로그램과 통합됩니다.

높은 상태 구성 요소는 밀접하게 연결된 중복성을 통해 복구 기능을 제공하며 구성 요소 사이에서 "통합"되어 철저하게 관리됩니다. 예는 다음과 같습니다.

  • SQL Server. 중복 SQL Server 인스턴스를 활성/수동 클러스터의 일부로 추가하려면 호환되는(즉, 동일한) 하드웨어와 공유 저장소(예: SAN)를 신중하게 선택하여 여러 노드 간에 트랜잭션에 일관성이 있는 장애 조치(failover)를 제공해야 합니다.

  • 전력 공급 장치. 중복되는 전력 공급 장치를 제공하는 것은 매우 정교한 예입니다. 여러 시스템이 동시에 작동하여 로컬(한 서버에 전원 공급 장치가 여러 개 있고 온보드 하드웨어로 주 공급 장치와 보조 공급 장치 간에 전환하는) 및 센터(정전을 대비한 보조 발전기) 수준의 문제를 완화할 수 있어야 합니다.

밀접하게 연결된 접근 방식을 기반으로 하는 복구 솔루션은 전문 교육을 받은 인력, 특수 하드웨어, 신중한 구성 및 테스트가 필요하기 때문에 느슨하게 연결되어 "더 많은 복제 항목을 추가할 수 있는" 접근 방식에 비해 훨씬 많은 비용이 듭니다. 뿐만 아니라 솔루션을 바로 구축하기도 어렵고 그렇게 하려면 또 비용이 들어갑니다.

하드웨어 플랫폼의 복구 기능을 높이는 데 초점을 맞추는 이 접근 방식을 “티타늄 달걀 껍질”에 비유할 수 있습니다. 달걀의 내용물을 보호하기 위해 단단하지만 비용이 많이 드는 티타늄으로 껍질을 코팅하는 것이죠.

대규모 시스템을 실험한 결과에 따르면(자세한 내용은 http://www.mvdirona.com/jrh/TalksAndPapers/JamesRH_Lisa.pdf 참조) Azure 규모의 데이터 시스템처럼 크기가 충분한 시스템에서는 물리적인 구동부 때문에 시스템의 일부가 항상 고장 나는 것으로 나타났습니다. Azure 플랫폼은 노드 수준 오류 이벤트를 자동으로 복구하는 방법으로 이러한 한계를 극복하도록 디자인되었습니다. 이러한 디자인 의도는 모든 핵심 Azure 서비스에 적용되며 Azure 가용성 모델을 사용하는 응용 프로그램을 디자인하는 열쇠입니다.

Azure로 전환하면 복구에 대한 대화의 주제가 인프라 중복성 과제에서 서비스 중복성 과제로 변하게 됩니다. Azure에서는 내부 가용성 계획을 결정하는 핵심 서비스의 대다수가 “정상적으로 작동”합니다.

  • SQL 데이터베이스는 자동으로 트랜잭션이 일치하는 데이터 복제본을 여러 개 유지합니다. 데이터베이스에 대한 노드 수준 오류가 발생할 경우 자동으로 일치하는 보조 복사본으로 장애 조치(Failover)됩니다. 이렇듯 간단한 경험은 내부 복구 기능을 제공하는 데 드는 시간 및 비용과 극명하게 대조됩니다.

  • Azure 저장소는 자동으로 일치하는 데이터 복제본을 여러 개 유지합니다(자세한 내용은 http://sigops.org/sosp/sosp11/current/2011-Cascais/11-calder-online.pdf 참조). 저장소 볼륨에 대한 노드 수준 오류가 발생할 경우 자동으로 일치하는 보조 복사본으로 장애 조치(Failover)됩니다. SQL 데이터베이스와 마찬가지로, 완벽하게 관리되는 이러한 경험은 내부 클러스터 또는 SAN의 저장소 복구 직접 관리 방식과 극명하게 대조됩니다.

하지만 이번 단원의 제목은 복구가 아니라 가용성입니다. 복구는 SLA 범위 내에서 사용자에게 지속적으로 가치를 제공하는 전체 이야기의 한 부분일 뿐입니다. 서비스의 모든 인프라 구성 요소가 정상이지만 예상되는 사용자 수를 처리할 수 없다면 해당 서비스는 사용이 불가능할 뿐만 아니라 가치를 제공할 수도 없습니다.

모바일 또는 소셜 중심 작업(예: 모바일 장치 응용 프로그램이 있는 공용 웹 응용 프로그램)은 고정 대상 그룹을 대상으로 하는 작업보다 훨씬 동적인 경향이 있으며 수많은 이벤트와 최대 부하를 처리하려면 보다 정교한 접근 방식이 필요합니다. 본 문서 전체에서 다음을 중심으로 Azure 응용 프로그램에 가용성을 디자인할 때 염두에 두어야 하는 핵심 개념에 대해 다룰 것입니다.

  • Azure의 각 서비스 또는 구성 요소는 특정 SLA(서비스 수준 계약)를 제공합니다. 이 SLA는 응용 프로그램을 실행하는 데 필요한 가용성 통계와 직접적인 상관관계가 없을 수도 있습니다. 시스템 구성 요소, 가용성 SLA, 상호 작용 방식을 이해해야만 사용자에게 제공할 수 있는 전체적인 가용성을 이해할 수 있습니다.

    • 단일 인스턴스 역할처럼 SLA를 저하시키는 단일 실패 지점을 피해야 합니다.

    • 여러 구성 요소를 작성하거나 여러 구성 요소로 대체하여 특정 서비스가 오프라인이 되거나 제공할 수 없게 되었을 때의 영향을 완화합니다.

  • Azure의 각 서비스 또는 구성 요소에 일시적 또는 장기적 이벤트가 발생할 수 있습니다. 응용 프로그램이 오류를 정상적으로 처리할 수 있는 방법으로 응용 프로그램을 작성해야 합니다.

    • 일시적 오류의 경우 적절한 재시도 메커니즘을 제공하여 작업을 다시 연결하거나 다시 제출합니다.

    • 그 외의 오류 이벤트의 경우 오류 이벤트에 대한 풍부한 계측 기능(작업에 오류 보고)을 제공하고 사용자에게 적절한 오류 메시지를 표시합니다.

    • 가능하다면 다른 서비스 또는 워크플로로 대체합니다. 예를 들어 데이터를 SQL 데이터베이스에 삽입하라는 요청이 잘못된 스키마 같은 비일시적인 이유로 인해 실패할 경우 데이터를 BLOB 저장소에 직렬화된 형식으로 기록합니다. 이렇게 하면 데이터가 영구적으로 캡처되어 스키마 문제가 해결되면 데이터베이스에 제출됩니다.

  • 모든 서비스는 명시적으로든(제한 정책 또는 최대 부하 점근선을 통해) 암시적으로든(시스템 리소스 제한에 도달) 최대 용량이 있습니다.

    • 리소스 제한에 도달하면 응용 프로그램의 성능이 저하되기는 하지만 정상적으로 작동하도록 디자인하여 사용자에게 미치는 영향을 완화합니다.

    • 적절한 백오프/재시도 논리를 구현하여 서비스에 대한 "호위(convoy)" 효과를 피합니다. 적절한 백오프 메커니즘이 없으면 피크 이벤트가 발생한 후 다운스트림 서비스가 처리되지 않습니다. 응용 프로그램이 계속해서 서비스에 더 많은 부하를 밀어넣어 제한 정책 또는 리소스 부족 현상을 트리거하기 때문입니다.

  • 빠른 버스트 이벤트가 발생할 수 있는 서비스는 최대 설계 부하를 초과하는 부하를 정상적으로 처리할 수 있어야 하며 일반적으로 기능을 축소하는 방법이 사용됩니다.

    • 기온이 매우 낮을 경우 인체가 팔과 다리로 흐르는 혈액 흐름을 제한하는 것처럼 부하가 과도할 경우 중요도가 낮은 서비스를 제한하도록 서비스를 디자인해야 합니다.

    • 여기서 중요한 것은 응용 프로그램에서 제공하는 모든 서비스의 업무 중요도가 동일하지는 않기 때문에 SLA를 차등적으로 적용할 수 있다는 점입니다.

이러한 고급 개념은 각 서비스 또는 구성 요소의 가용성 목표와 가용성 설계 방법에 대한 권장 사항과 함께 핵심 Azure 서비스를 설명하는 각 단원에서 보다 자세히 적용할 예정입니다. 데이터 센터는 전력 공급 장치(예는 여기를 참조)부터 시스템 오류(예는 여기 참조)에 이르는 대규모 응용 프로그램의 단일 지점에서 오류가 발생하며 인프라 및 응용 프로그램 문제가 데이터 센터의 성능을 떨어트린다는 점을 기억해야 합니다. 비교적 드물기는 하지만 최고 수준의 가동 시간을 요구하는 응용 프로그램은 여러 중복 데이터 센터에서 배포해야 합니다.

응용 프로그램을 여러 데이터 센터에서 배포하려면 다음과 같은 다양한 인프라 및 응용 프로그램 기능이 필요합니다.

  • 지역, 사용자 분할 또는 기타 선호도 논리에 따라 서비스 사용자를 적절한 데이터 센터에 라우팅할 수 있는 응용 프로그램 논리.

  • 적절한 수준의 대기 시간 및 일관성으로 데이터 센터 간에 응용 프로그램 상태를 동기화 및 복제.

  • 데이터 센터 간의 종속성이 최소화되는(즉, 데이터 센터 A의 오류가 데이터 센터 B의 오류를 트리거하지 않는) 응용 프로그램 자동 배포.

가용성과 마찬가지로, 데이터 센터가 손실된 경우 재해 복구 솔루션을 제공하려면 엄청난 시간, 에너지 및 비용이 필요합니다. 이 단원에서는 시스템에 오류가 발생하고 데이터가 손실된(시스템 또는 사용자에 의한) 경우에도 비즈니스 연속성을 제공하기 위한 접근 방법과 고려 사항을 집중적으로 다룰 것입니다. "재해 복구"라는 용어는 데이터베이스 커뮤니티의 구현 방식에 대한 함축적 의미를 포함하기 때문입니다.

비즈니스 연속성을 제공하는 방법은 다음과 같은 범주로 분류할 수 있습니다.

  • 심각한 인프라 오류가 발생하는 경우에 중요한 비즈니스 시스템(영구 상태에 대한 응용 프로그램 작업)에 대한 액세스 및 가용성 유지

  • 심각한 인프라 오류가 발생하는 경우에 중요한 비즈니스 데이터(영구 상태)에 대한 액세스 및 가용성 유지

  • 운영자가 오류를 범하거나 실수로 삭제, 수정 또는 손상시키는 경우에 중요한 비즈니스 데이터(영구 상태)에 대한 액세스 및 가용성 유지

처음 두 요소는 전통적으로 지리적 재해 복구(geo-DR)의 맥락에서 해결되며 세 번째 요소는 데이터 백업 및 데이터 복원의 영역입니다.

Azure는 중요한 비즈니스 시스템의 가용성에 대한 상황을 크게 변화시켜 지리적으로 분산된 핵심 응용 프로그램을 전 세계의 데이터 센터에 신속하게 배포할 수 있습니다. 실제로 지리적으로 분산된 응용 프로그램을 제공하는 과정은 단일 클라우드 서비스를 제공하는 과정과 거의 차이가 없습니다.

영구 상태에 대한 액세스를 관리해야 하는 주요 과제는 여전히 남아 있습니다. 모든 데이터 센터에서 Azure 저장소 및 SQL 데이터베이스 같은 영구 상태 서비스에 액세스할 경우 긴 대기 시간 및/또는 가변적인 대기 시간으로 인해 일반적으로 최선이 아닌 결과가 발생하므로 데이터 센터에 오류 발생 시 비즈니스 연속성 요구 사항을 만족할 수 없습니다.

복구 기능과 마찬가지로, 여러 Azure 서비스에서 자동 지리적 복제를 제공하거나 로드맵에 포함하고 있습니다. 예를 들어 구체적으로 구성하지 않는 한 Azure 저장소(BLOB, 큐 또는 테이블)에 대한 모든 쓰기 작업은 다른 데이터 센터(각 데이터 센터는 동일한 지역 내에 특정 "미러" 대상을 갖고 있음)에 자동으로 복제됩니다. 이렇게 하면 Azure를 기반으로 기존의 재해 복구 솔루션을 제공하기 위해 필요한 시간과 작업이 대폭 감소합니다. 영구 상태를 관리하는 핵심 Azure 서비스의 지리적 복제 기능에 대한 개요는 이 단원의 후반부에서 설명하겠습니다.

사용자 또는 운영자의 잘못으로 인한 오류가 발생해도 비즈니스 연속성을 유지하려면 응용 프로그램 디자인에서 고려할 추가적인 고려 사항이 몇 가지 더 있습니다. Azure 저장소는 저장소 분석 기능(나중에 설명)을 통해 제한된 감사 기능을 제공하기는 하지만 지정 시간 복원 기능은 제공하지 않습니다. 우발적인 삭제나 수정이 발생했을 때 복구 기능이 필요한 서비스는 BLOB를 다른 저장소 계정에 주기적으로 복사하는 등 응용 프로그램 중심의 접근 방식을 살펴보아야 합니다.

SQL 데이터베이스는 DB 복사 및 bacpac 파일을 통한 가져오기/내보내기를 포함하여 데이터 스냅숏 기록을 유지 관리하는 기본 기능을 제공합니다. 이러한 옵션은 이 문서의 후반부에서 자세히 살펴보겠습니다.

Azure 플랫폼이 제공하는 탄력적인 확장 기능을 사용하면 최대 부하를 고려하여 추가 용량을 과도하게 확보하는 일 없이 공급 곡선을 수요 곡선과 근접하게 일치시킬 수 있습니다.

탄력적인 확장 기능을 사용하면 다음 요소에 의해 매출 원가가 결정됩니다.

  • 솔루션에 사용되는 확장 단위의 수(확장을 구성하는 가상 컴퓨터, 저장소 계정 등)

  • 이러한 확장 단위에 의해 수행되는 작업의 효율성

주어진 용량으로 수행할 수 있는 작업의 양을 응용 프로그램의 밀도라고 합니다. 밀도가 높은 서비스 및 프레임워크는 주어진 리소스로 더 많은 작업을 수행할 수 있습니다. 즉, 밀도를 개선하면 배포된 용량(및 비용)을 줄이거나 동일한 용량으로 더 많은 부하를 흡수할 수 있습니다. 밀도는 다음과 같은 두 가지 주요 요인에 의해 결정됩니다.

  • 확장 단위 내에서 작업이 얼마나 효율적으로 수행되는가. 이것은 스레드 경합 및 잠금을 관리하고, 알고리즘을 최적화하고, SQL 쿼리를 조정하는 전통적인 형태의 성능 최적화입니다.

  • 전체 확장 단위에서 작업이 얼마나 효율적으로 조정되는가. 수많은 소형 단위로 구성되는 시스템에서는 이러한 소형 단위를 효율적으로 연결하는 기능이 효율성을 높이기 위한 핵심입니다. 여기에는 SOAP 메시징 스택(예: WCF), ORM(예: Entity Framework), TDS 호출(SQL 클라이언트 호출), 개체 직렬화(예: 데이터 계약 또는 JSON) 등 구성 요소에 걸쳐 통신하는 프레임워크 및 도구가 관련되어 있습니다.

확장 가능하고 효율적인 Azure 서비스를 제공하려면 단일 컴퓨터(또는 데이터베이스)에 사용되는 기존의 최적화 기술 외에도 분산 통신 및 작업 최적화가 매우 중요합니다. 이러한 주요 최적화는 뒷부분에서 자세히 다루겠습니다.

  • 덩어리가 크고 수다스럽지 않게. 모든 분산 작업(즉, 결과적으로 네트워크 호출로 이어지는)에는 패킷 프레이밍, 직렬화, 처리 등을 위한 오버헤드가 어느 정도 존재합니다. 오버헤드의 양을 최소화하려면 다수의 "수다스러운 작업" 대신 소수의 "대규모 작업"을 일괄 처리하는 것이 좋습니다. 자잘한 작업을 일괄 처리할 경우 대기 시간이 늘어나고 잠재적인 데이터 손실 위험에 노출된다는 점을 기억해야 합니다. 적절한 일괄 처리 동작의 예는 다음과 같습니다.

    • SQL. 여러 작업을 단일 일괄 처리로 실행합니다.

    • REST 및 SOAP 서비스(예: WCF). 수다스러운 RPC 스타일보다는 메시지 중심 작업 인터페이스를 활용하고 가능하다면 REST 기반 방식을 고려합니다.

    • Azure 저장소(BLOB, 테이블, 큐). 여러 업데이트를 개별적으로 게시하지 말고 일괄 처리에 게시합니다.

  • 직렬화의 영향. 컴퓨터 간에 데이터를 이동하고 영구 저장소를 입출력하려면 일반적으로 데이터를 연결 형식으로 직렬화해야 합니다. 이 작업의 효율성, 즉 걸리는 시간과 사용되는 공간은 대규모 시스템의 전체적인 응용 프로그램 성능에 즉각적인 영향을 미칩니다.

    • 매우 효율적인 직렬화 프레임워크를 활용합니다.

    • JSON을 사용하여 장치 또는 상호 운용되는(사람이 읽을 수 있는) 응용 프로그램과 통신합니다.

    • 두 끝점을 모두 제어하는 경우 서비스 간 통신에 protobuf 또는 Avro 같이 매우 효율적인 이진 직렬화를 사용합니다.

  • 효율적인 프레임워크를 사용합니다. 정교한 대규모 기능 집합을 갖춘 개발용 프레임워크가 많이 있습니다. 이러한 프레임워크의 단점은 사용하지 않는 기능의 성능 비용까지 지불해야 하는 경우가 종종 있다는 것입니다.

    • 서비스 및 클라이언트 API를 제네릭 인터페이스 뒤에 격리하여 대체 또는 병렬 평가(정적 팩터리를 통해 또는 컨트롤 컨테이너의 순서를 변경하여)가 가능하게 합니다. 예를 들어 특정 구현(예: Azure Caching)이 아니라 제네릭 인터페이스에 대한 작업을 통해 플러그형 캐싱 계층을 제공합니다.

이전 단원에서는 Azure에서 제공하는 클라우드 패브릭을 활용하는 응용 프로그램을 구축하기 위한 핵심 디자인 개념 및 관점을 소개했습니다. 이 단원에서는 기능, 확장 경계 및 가용성 패턴을 보여 주는 주요 서비스와 기능을 살펴보겠습니다.

모든 Azure 서비스 또는 인프라 구성 요소는 가용성 SLA가 설정된 유한한 용량을 제공하기 때문에 확장 목표 및 최종 사용자 SLA에 맞는 적절한 디자인을 선택할 수 있도록 이러한 제한과 동작을 이해하는 것이 중요합니다. 각각의 핵심 Azure 서비스는 기능, 기능의 의도, 확장성 및 가용성이라는 네 가지 핵심 축을 중심으로 표시할 수 있습니다.

Azure 구독은 관리, 청구 및 서비스 할당량의 기본 단위입니다. 각 Azure 구독마다 기본 할당량이 있으며 지원 부서에 문의하여 할당량을 추가할 수 있습니다. 이것은 의도하지 않게 리소스를 과다하게 사용하는 것을 방지하기 위한 조치입니다.

각 구독에는 Microsoft 계정(이전 명칭은 Live ID)을 통해 인증되는 한 명의 계정 소유자와 여러 명의 공동 관리자가 있으며 계정 소유자는 관리 포털을 통해 구독의 모든 리소스를 완전하게 제어할 수 있습니다. 계정 소유자는 저장소 계정을 만들고, 클라우드 서비스를 배포하고, 구성을 변경하고, 공동 관리자를 추가 또는 제거할 수 있습니다.

Azure 관리 API(REST 기반 웹 서비스)는 관리 포털에서 사용하는 Azure 서비스를 만들고, 구성하고, 배포할 수 있는 자동화 인터페이스를 제공합니다. 이러한 API에 대한 액세스는 관리 인증서를 사용하여 제한됩니다.

 

서비스 기본 제한

클라우드 서비스

20

저장소 계정

20

코어

20

SQL 데이터베이스 논리 서버

5

Tip
최신 Azure 구독 및 서비스 제한은 Azure 구독 및 서비스 제한, 할당량 및 제약 조건을 참조하십시오.

Azure 클라우드 서비스(이전 명칭은 호스팅된 서비스)는 배포 및 확장의 기본 단위입니다. 각 클라우드 서비스는 두 가지 배포(프로덕션 및 준비)로 구성되며 각 배포마다 일련의 역할이 있습니다. 클라우드 서비스는 프로덕션 배포를 위한 공용 DNS 항목(servicename.cloudapp.net의 형태)과 배포 준비 DNS 항목(someguid.cloudapp.net의 형태)을 갖고 있습니다.

각 배포는 하나 이상의 역할(웹 역할 또는 작업자 역할)을 포함하며, 각 역할은 하나 이상의 인스턴스(비 영구적 가상 컴퓨터)를 포함합니다. 각 인스턴스는 해당 역할에 대한 소프트웨어 패키지의 동일하고, 변경할 수 없고, 비 영구적인 스냅숏을 포함합니다. 즉, 주어진 역할의 모든 인스턴스에 동일한 빌드가 배포됩니다. 이러한 인스턴스는 Windows Server의 Azure 특수 버전(보안을 강화하기 위해 기본적으로 여러 서비스가 해제되어 있고 Azure 네트워킹 및 서비스 패브릭에서 잘 작동하도록 구성됨)을 실행하며 기본적으로 Azure 패브릭에 의해 자동으로 패치됩니다. 라이브 패치는 아래에 설명된 롤링 업그레이드 스키마를 통해 처리됩니다.

서비스를 만들 때 대상 지역을 직접 선택하여 또는 선호도 그룹을 통해 모든 Azure 데이터 센터에 클라우드 서비스를 배포할 수 있습니다. 선호도 그룹은 응용 프로그램의 모든 구성 요소를 동일한 데이터 센터에 배포하는 작업을 간소화할 때 사용할 수 있는 배포 대상의 간접 참조입니다.

웹 역할은 응용 프로그램 코드를 호스팅하는 IIS 인스턴스를 통해 미리 구성됩니다. 작업자 역할에서 호스팅된 응용 프로그램 코드는 미리 구성된 장기 실행 응용 프로그램 호스트에서 실행됩니다. 각 클라우드 서비스는 최대 25개의 역할을 가질 수 있습니다. 역할 기본 구성은 .NET 코드를 실행하는 것이지만 Java, Python, Ruby, node.js 등의 Windows Server와 호환되는 모든 코드를 실행하도록 역할을 구성할 수도 있습니다. 이 문서에서 언급하는 모든 플랫폼 기능은 어떤 플랫폼에서도 사용할 수 있지만 REST 기반 API을 대상으로 하는 클라이언트 프록시를 추가로 개발해야 할 수 있습니다.

클라우드 서비스 내에서 모든 인스턴스는 10.x 블록 내에 있는 개인 IP 주소에 할당됩니다. 모든 아웃바운드 연결은 네트워크 주소 변환을 통해 단일 가상 IP 주소 또는 VIP(클라우드 서비스 배포의 VIP)에서 오는 것처럼 보입니다. 모든 인바운드 연결은 구성된 끝점을 통과해야 합니다. 이러한 끝점은 내부 역할 및 포트에 대한 부하가 분산된 액세스를 제공합니다. 예를 들어 클라우드 서비스 배포에 대한 인바운드 HTTP/HTTPS(포트 80 및 443) 연결은 기본적으로 주 웹 역할의 사용 가능한 모든 인스턴스에 대해 부하가 분산됩니다.

교차 서비스 대기 시간(즉, 부하 분산 장치를 통해 한 클라우드 서비스의 NAT를 순회하여 다른 NAT로 들어가는)은 내부 대기 시간보다 훨씬 가변적입니다. 확장할 때 일괄 처리 또는 "규모가 큰” 교차 서비스 연결을 사용하도록 권장하는 이유 중 하나이기도 합니다.

또한 Azure 패브릭은 클라우드 서비스 배포의 모든 인스턴스에 사용할 수 있는 구성 서비스를 제공합니다. 예상되는 구성 키의 정적 집합은 서비스 정의에서 배포 주기의 일부로 제공되며 구성 값의 초기 집합은 Azure에 게시될 때 서비스와 함께 배포됩니다. 이 구성 값 집합은 서비스 배포의 모든 인스턴스에 대한 런타임 조회로 사용할 수 있으며 REST 인터페이스, Azure 포털 또는 PowerShell 스크립트를 통해 수정할 수 있습니다.

런타임 구성이 변경되면 모든 인스턴스는 응용 프로그램 코드에서 구성 변경 알림을 후크하고 구성 업데이트를 내부적으로 처리하도록 선택할 수 있습니다. 응용 프로그램 코드가 구성 변경 이벤트를 캡처하도록 작성되지 않을 경우 역할의 모든 인스턴스가 구성을 업데이트하기 위해 롤링 재부팅을 수행하게 됩니다.

각 인스턴스의 상태는 영구적이지 않습니다. 기본 Azure 이미지(특수한 Windows Server 가상 컴퓨터)를 기반으로 하는 모든 구성은 시작 시 성능 카운터를 만들고, IIS 설정을 조정하고, 종속 소프트웨어를 설치하도록 구성해야 합니다. 이러한 구성 스크립트는 일반적으로 클라우드 서비스 구성에서 정의하는 시작 작업으로 실행됩니다.

클라우드 서비스 내부에서는 Azure 패브릭이 RoleEnvironment를 통해 구성, 내부 IP 주소, 서비스 구성 등에 대한 정보를 제공합니다. Azure 인스턴스에서 실행되는 모든 프로세스는 RoleEnvironment 정보에 액세스하여 구성을 검색하고 네트워크 토폴로지를 발견할 수 있습니다. Azure 관리 API를 사용하여 외부에서 이 정보에 액세스할 수도 있습니다.

Azure 패브릭은 구성 요소 오류, 재구성 및 업그레이드/패치를 관리하는 두 가지 핵심 개념을 노출합니다. 그것은 바로 업그레이드 도메인과 오류 도메인입니다.

업그레이드 도메인은 Azure 서비스 내의 논리적 그룹화입니다. 기본적으로 각 서비스마다 5개의 업그레이드 도메인이 있으며 이 값은 클라우드 서비스 정의에서 수정할 수 있습니다. 모든 서비스 변경 또는 업그레이드는 한 번에 하나의 업그레이드 도메인에만 영향을 미칩니다. 이러한 변경의 예로 운영 체제 패치, 가상 컴퓨터 크기 변경, 실행 중인 서비스에 역할 또는 역할 인스턴스 추가, 끝점 구성 변경 등이 포함됩니다.

이렇게 하면 실행 중인 클라우드 서비스의 가용성을 유지하면서 실시간으로 다시 구성할 수 있습니다. 인스턴스가 하나뿐인 역할의 경우 Azure 패브릭이 업그레이드 작업을 수행하는 동안 가용성을 제공할 수 없습니다. 이것이 바로 단일 인스턴스 역할을 실행하면 Azure SLA를 만족하지 못하는 이유입니다.

오류 도메인은 기본 하드웨어에 따른 논리적 그룹화입니다. 반드시 특정 하드웨어 구성에 직접 매핑되는 것은 아니지만 논리적 그룹화를 Azure 패브릭이 단일 오류 지점(단일 기본 서버, 랙 등)을 나타내는 리소스에서 자동으로 인스턴스를 분리하는 방식으로 생각할 수 있습니다. 서비스 SLA를 만족하려면 Azure가 두 개 이상의 오류 도메인에 인스턴스를 배포해야 합니다. 단일 인스턴스 역할 배포가 Azure SLA를 만족하지 않는 또 다른 이유입니다.

요약하자면

  • Azure의 배포 및 확장 기본 단위는 역할 집합으로 구성된 클라우드 서비스입니다. 각 역할은 동일한 역할 인스턴스 집합을 포함하여, 각각은 특수하게 구성된 Windows Server 클라우드 버전을 실행합니다.

  • 물리적 토폴로지(역할 및 인스턴스)와 응용 프로그램 코드 외에도 클라우드 서비스는 서비스 차원 구성을 정의합니다. 이 구성은 런타임에 업데이트할 수 있습니다.

  • 각 역할 인스턴스는 비 영구적이므로 재부팅, 패치, 오류 이벤트가 발생할 경우 변경 사항, 파일 등이 반드시 유지되는 것은 아닙니다.

  • 각 클라우드 서비스는 인바운드 및 아웃바운드 트래픽 모두에 대해 단일 가상 IP를 노출합니다. 클라우드 서비스는 내부 역할 및 포트에 (라운드 로빈) 부하가 분산된 매핑을 제공하는 끝점을 노출합니다.

  • Azure는 업그레이드 도메인을 사용하여 인스턴스 그룹을 논리적으로 분리하고, 가용성을 유지하면서 롤링 업그레이드 또는 수정이 가능합니다.

  • Azure는 오류 도메인을 사용하여 단일 오류 지점(예: 같은 기본 물리적 컴퓨터에서 모든 인스턴스 실행)에서 인스턴스를 물리적으로 그룹화합니다.

  • 여러 구독을 활용하여 개발, 테스트, 준비 및 프로덕션 환경을 격리합니다.

각 역할에는 하나 이상의 인스턴스 집합이 포함되어 있습니다. 이러한 각각의 인스턴스는 특수 버전의 Windows Server를 실행하는 가상 컴퓨터입니다. 현재 인스턴스(가상 컴퓨터)는 초소형에서 특대형까지 총 5개의 크기가 제공됩니다. 이러한 크기에 따라 정해진 CPU, 메모리, 저장소 및 대역폭이 할당됩니다.

 

가상 컴퓨터 크기 CPU 코어 수 메모리 웹 및 작업자 역할의 로컬 저장소 리소스에 사용할 디스크 공간 VM 역할의 로컬 저장소 리소스에 사용할 디스크 공간 할당된 대역폭(Mbps)

초소형

공유됨

768 MB

19,480 MB

(6,144MB는 시스템 파일용으로 예약됨)

20 GB

5

작음

1

1.75 GB

229,400 MB

(6,144MB는 시스템 파일용으로 예약됨)

165 GB

100

중형

2

3.5 GB

500,760 MB

(6,144MB는 시스템 파일용으로 예약됨)

340 GB

200

대형

4

7 GB

1,023,000 MB

(6,144MB는 시스템 파일용으로 예약됨)

850 GB

400

특대형

8

14 GB

2,087,960 MB

(6,144MB는 시스템 파일용으로 예약됨)

1,890 GB

800

Tip
최신 Azure 구독 및 서비스 제한은 Azure 구독 및 서비스 제한, 할당량 및 제약 조건을 참조하십시오.

서로 다른 오류 및 업그레이드 도메인에 두 개 이상의 인스턴스를 배포할 경우 Azure는 클라우드 서비스에 다음과 같은 SLA를 제공합니다.

  • 외부 끝점이 있는 인터넷 역할에 대한 외부 연결 성공률 99.95%

  • 역할 인스턴스 문제를 2분 이내에 99.9% 감지하여 수정 작업 시작

역할 인스턴스 크기 및 수는 실행 중인 응용 프로그램에서 동적으로 변경될 수 있으며 역할 인스턴스 크기가 변경될 경우 롤링 재배포가 트리거됩니다. Azure 응용 프로그램을 구축하기 위한 수평 확장 방식을 고려할 때 크기가 큰 인스턴스를 선택하는 것이 반드시 좋다고 할 수는 없습니다. 이것은 비용(사용하지 않는 기능에 지불하는)과 성능(CPU 바인딩된 작업인지 아니면 I/O 바인딩된 작업인지에 따라 결정되는) 모두에 적용됩니다. 인스턴스 수 및 인스턴스 크기를 선택하는 방법은 이 문서의 최선의 구현 방법 단원에서 보다 자세히 살펴보겠습니다.

Azure 저장소는 Azure의 기준이 되는 영구 데이터 서비스로써 BLOB(파일), 큐 및 테이블 저장소(가치의 핵심)를 제공합니다. 저장소 계정은 확장 및 가용성의 기본 단위로써 다음과 같은 기능을 제공합니다. 스토리지 서비스와의 모든 통신은 HTTP를 통한 REST 인터페이스를 기반으로 합니다.

Tip
최신 Azure 구독 및 서비스 제한은 Azure 구독 및 서비스 제한, 할당량 및 제약 조건을 참조하십시오.

Azure 저장소 가용성 SLA는 형식이 올바르게 지정된 데이터 추가, 업데이트, 읽기 및 삭제 요청이 99.9% 이상 성공적으로 처리되며 저장소 계정이 인터넷 게이트웨이에 연결될 것을 보장합니다.

이러한 제한은 개별 저장소 계정을 사용할 때마다 공유됩니다. 예를 들어 초당 작업 수와 전체적인 대역폭은 테이블, BLOB 및 큐 간에 공유됩니다. 응용 프로그램이 초당 총 작업 수를 초과하는 경우 서비스에서 HTTP 503 서버 사용 중이라는 코드를 반환합니다. 작업은 각 저장소 요소(테이블, 큐 또는 BLOB)에 따라 결정되며 아래의 하위 단원에 설명되어 있습니다.

앞에서 배송 컨테이너에 비유한 방법으로 설명하자면 각 저장소 계정은 일정량의 용량을 제공하는 컨테이너입니다. 단일 계정(배송 컨테이너)의 제한을 초과할 경우 같은 응용 프로그램에서 여러 계정을 활용해야 합니다.

Azure 저장소는 기본적으로 가용성 및 복구 기능을 제공합니다. Azure 저장소에 대한 모든 쓰기 또는 업데이트 작업은 서로 다른 업그레이드 및 오류 도메인에 위치한 3개의 저장소 노드에서 투명하고 일관적으로 복제됩니다. Azure 저장소에 대한 액세스는 액세스 키 형태의 단일 요소 인증을 사용하여 제어됩니다. 각 저장소 계정마다 기본 키와 보조 키가 있어서 기본 키가 회전되더라도 지속적인 가용성이 보장됩니다. Azure 저장소의 데이터는 포털을 사용하여 해당 기능을 해제하지 않는 한 “미러” 데이터 센터에 자동으로 지역 간 복제됩니다. 지역 간 복제는 불투명하며 주 데이터 센터에 오류가 발생할 경우 DNS 리디렉션을 활용하여 클라이언트를 보조 위치에 장애 조치(Failover)합니다.

Azure 저장소는 자동화된 복제본을 통해 데이터 복구 기능을 제공하기는 하지만 응용 프로그램 코드(또는 개발자/사용자)가 실수로 또는 의도하지 않게 데이터를 삭제하거나 업데이트하여 데이터가 손상되는 것을 막아 주지는 못합니다. 응용 프로그램 오류 또는 사용자의 실수가 발생하더라도 데이터의 정확성을 유지하려면 감사 로그와 함께 데이터를 보조 저장소 위치에 복사하는 등의 고급 기술이 필요합니다. BLOB 저장소는 Blob 내용의 시간 스냅숏에 읽기 전용 지점을 만들 수 있는 스냅숏 기능을 제공하며 이렇게 생성된 읽기 전용 지점은 BLOB의 데이터 정확성의 기준으로 사용할 수 있습니다.

Azure 저장소는 저장소 분석 기능을 통해 테이블, 큐 및 BLOB의 개별 저장소 호출에 대한 사용량 데이터를 수집하여 노출하는 원격 분석을 제공합니다. 수집 정책(모든 데이터 수집, 테이블에 대한 데이터만 수집 등) 및 보존 정책(데이터를 보관하는 기간)을 사용하여 각 저장소 계정마다 저장소 분석 기능을 설정해야 합니다.

Azure의 BLOB 저장소는 구조화되지 않은 대용량 데이터를 저장할 수 있는 가용성과 경제성이 뛰어난 파일 관리 서비스를 제공합니다. 이 서비스는 아래와 같은 두 가지 유형의 BLOB를 제공합니다.

  • 블록 BLOB. 블록 BLOB는 대용량 데이터 BLOB를 효율적으로 관리하기 위해 디자인되었습니다. 각 블록 BLOB는 최대 50,000개의 블록으로 구성되고 각 블록의 최대 크기는 4MB이므로 전체 블록의 최대 크기는 200GB입니다. 블록 BLOB는 네트워크를 통해 대용량 파일을 효율적으로 동시에 이동할 수 있도록 병렬 업로드를 지원합니다. 개별 블록을 삽입, 대체 또는 삭제할 수 있지만 바로 편집할 수는 없습니다.

  • 페이지 BLOB. 페이지 BLOB는 임의 읽기/쓰기 작업(예: VHD에 액세스)을 효율적으로 제공하기 위해 디자인되었습니다. 각 페이지 BLOB의 최대 크기는 1TB이고 512바이트 페이지로 구성됩니다. 즉시 덮어쓰기 작업을 통해 개별 페이지 또는 페이지 그룹을 추가 또는 업데이트할 수 있습니다.

아래 표는 BLOB 저장소에 대한 디자인 제한입니다. 이 모든 작업이 전체 저장소 계정 제한에 적용된다는 점을 기억해야 합니다.

 

BLOB 범주 제한

최대 BLOB 크기(블록)

200GB(블록 50000개)

최대 블록 크기

4 MB

최대 BLOB 크기(페이지)

1TB

페이지 크기

512바이트

최대 대역폭/BLOB

480Mbps

단일 BLOB의 크기 또는 대역폭 제한을 초과할 경우 응용 프로그램이 여러 동시 또는 순차 BLOB 파일에 쓸 수 있습니다. 응용 프로그램이 단일 저장소 계정의 제한을 초과할 경우 저장소 계정을 여러 개 활용하여 용량을 추가하십시오.

Azure 큐는 게시자와 구독자를 연결하는 중간(브로커) 메시징 서비스를 제공합니다. 큐는 여러 동시 게시자와 구독자를 지원하지만 기본적으로 게시자/구독자 또는 항목 기반 라우팅 같이 순서가 높은 메시징 기본 형식을 노출하지 않습니다. 큐는 일반적으로 메시지, 문서, 작업 등의 작업 항목을 작업 역할 인스턴스 집합에(또는 여러 호스팅된 서비스 간에) 배포하는 데 사용됩니다.

응용 프로그램에서 큐 메시지를 검색하여 삭제하지 않을 경우 7일 후에 자동으로 삭제됩니다. 큐를 통해 게시자 정보와 소비자 정보를 분리할 수 있으며 양쪽 모두 저장소 계정 키와 큐 이름을 갖고 있는 한 서로 통신할 수 있습니다.

 

큐 범주 제한

큐의 최대 메시지

해당 없음(최대 저장소 계정 제한)

메시지의 최대 수명

1주일(자동 삭제)

최대 메시지 크기

64 kB

최대 처리량

초당 500개 메시지

큐의 목적은 원시 데이터가 아닌 제어 메시지를 전달하는 것입니다. 메시지가 너무 커서 큐에 맞지 않는 경우 메시지를 리팩터링하여 데이터와 명령을 분리합니다. 데이터를 BLOB 저장소에 저장하고 데이터 및 의도(BLOB 저장소의 데이터로 무엇을 할 것인가)에 대한 참조(URI)를 큐 메시지에 저장합니다.

단일 큐 내에서 처리량을 높이려면 여러 메시지를 단일 메시지에서 일괄 처리한 다음 업데이트 메시지 명령을 활용하여 메시지 작업의 캡슐화 진행 상황을 추적합니다. 또 다른 방법은 BLOB에 여러 메시지를 배치하고 큐 메시지에 BLOB에 대한 포인터를 넣는 것입니다.

응용 프로그램이 단일 큐에서 공급하는 처리량보다 더 많은 처리량을 필요로 할 경우 여러 개의 동시 큐를 활용합니다. 이러한 맥락에서 응용 프로그램에 적절한 분할 및 라우팅 논리를 구현해야 합니다.

Azure 테이블 저장소는 열 형식(2 차원) 데이터를 저장할 수 있는 영구적이고, 확장성이 뛰어나고, 일관성 있는 저장 기능을 제공 합니다. 테이블 저장소는 아래 다이어그램에서 볼 수 있듯이 데이터를 저장하고 액세스하기 위한 { partition key, row key } -> { data[] } 의미 체계를 제공합니다. 각 테이블은 파티션에 의해 분할되며 분할된 테이블은 엔터티를 포함합니다. 각 엔터티는 고유의 (플랫) 스키마 또는 속성 목록(열)을 갖습니다.

각 파티션은 초당 최대 500개의 작업을 지원하므로 결과적으로 각 테이블은 저장소 계정에서 사용 가능한 최대 작업 수를 지원합니다. 각 엔터티는 실제 데이터뿐만 아니라 열 형식 메타데이터(모든 엔터티는 서로 다른 스키마를 가질 수 있기 때문에)를 포함하기 때문에 특히 대규모 방식의 경우 열 이름을 길게 하지 않는 것이 좋습니다.

 

테이블 범주 제한

초당 파티션별 최대 작업 수

500

최대 엔터티 크기(열 이름 + 데이터)

1 MB

최대 열 크기(바이트 배열 또는 문자열)

64 kB

최대 행 수

해당 없음(최대 저장소 계정 제한)

지원되는 데이터 형식

바이트 배열, 부울, 날짜/시간, Double, GUID, Int32, Int64, String

개별 엔터티(행이라고 생각해도 됨)의 최대 크기는 1MB이고 개별 열의 최대 크기는 64kB로 제한됩니다. 지원되는 데이터 형식은 위의 표에 나열되어 있습니다. 지원되지 않는 형식(예: DateTimeOffset)의 경우 응용 프로그램 코드에 직렬화 프록시가 필요합니다(예: 표준 문자열 형식으로 된 DateTimeOffset 저장).

테이블 저장소는 파티션 및 엔터티, 파티션 검색 또는 엔터티 검색과 연결된 키를 사용하여 저장된 데이터에 대한 액세스를 제공합니다. 테이블 저장소는 필터 프로젝션을 지원합니다. 필터 식을 쿼리의 일부로 테이블 저장소에 밀어넣어 테이블 저장소에서 실행할 수 있습니다. 테이블 저장소는 보조 인덱스를 제공하지 않기 때문에 파티션 키 또는 엔터티 키를 기반으로 하지 않는 모든 조회는 테이블 및/또는 파티션을 검색해야 합니다. 다수의 엔터티가 포함된 파티션의 경우 이것이 성능에 막대한 영향을 미칩니다.

5초 이상 걸리는 모든 쿼리 처리는 응용 프로그램에서 쿼리 결과를 계속해서 받을 수 있는 연속 토큰을 반환합니다. 1,000개가 넘는 엔터티를 검색하는 쿼리는 페이징 모델을 활용하여 1,000 엔터티 청크로 데이터를 다시 가져와야 합니다(테이블 저장소 API에서 기본적으로 지원).

현재 테이블 저장소에 대해 지원되는 유일한 쿼리 식은 필터링 및 선택(특정 속성을 선택)입니다. 테이블 저장소는 서버 쪽 집계 또는 그룹화 의미 체계를 제공하지 않습니다. 풍부한 집계 또는 분석 기능이 필요한 응용 프로그램을 구축하려고 할 때 데이터를 집계된 형식으로 저장하거나 Azure SQL 데이터베이스 같은 관계형 엔진을 사용하는 것이 더 나은 선택인 경우가 종종 있습니다. 일부 응용 프로그램은 테이블 저장소에서 보조 SQL 데이터베이스로 데이터를 집계한 후 쿼리 및 보고서에 이용하는 혼합 방식을 사용합니다.

테이블 저장소를 효율적이고 효과적으로 사용하려면 적절한 파티션 함수를 선택하는 것이 중요합니다. 파티션 함수는 크게 두 종류가 있습니다.

  • 시간. Azure 진단 성능 카운터(이 문서의 원격 분석 단원에서 다룬 사용량) 같은 시계열 데이터를 저장하는 데 주로 사용되는 시간 기반 파티션 함수는 현재 시간을 특정 기간(현재 시간, 분 등)을 나타내는 값으로 변환합니다.

    테이블 저장소에 대한 필터 절에서 >=, <= 등을 지원하므로 이렇게 하면 특정 파티션을 효율적으로 조회 및 검색할 수 있지만 선택한 기간이 너무 짧아서 스파이크 이벤트가 발생할 경우 쉽게 제한되는 경향이 있습니다. 예를 들어 선택한 파티션 함수가 현재 분이고 스파이크 이벤트가 발생할 경우 동시에 너무 많은 클라이언트가 같은 파티션에 쓰기를 시도할 수 있습니다. 이는 삽입 처리량뿐만 아니라 쿼리 처리량에도 영향을 줍니다.

  • 데이터. 데이터 중심 파티션 함수는 저장할 또는 검색할 데이터 속성 하나 이상을 기반으로 파티션 값을 계산합니다. 적절한 데이터 중심 파티션 함수를 선택하려면 쿼리 패턴, 파티션 키의 밀도(파티션에서 끝나는 엔터티의 수), 예측 불가능한 성장(대규모 테이블의 균형을 다시 조정할 때 문제가 될 수 있음) 등의 여러 가지 요소를 고려해야 합니다. 일반적인 패턴은 다음과 같습니다.

    • 단일 필드. 파티션 키는 원본 데이터(예: 주문 정보의 고객 ID)의 단일 필드입니다.

    • 다중 필드. 파티션 또는 행 키는 원본 데이터의 여러 필드가 합성된(일반적으로 연결된) 복합체입니다. 파티션 키를 선택할 때 일괄 처리 작업의 모든 엔터티가 같은 파티션에 있어야 합니다. 즉, 파티션 키가 같아야 합니다.

    • 계산 필드. 파티션 키는 하나 이상의 필드에서 결정적 함수를 기반으로 계산됩니다. 사용자 프로필을 여러 파티션에 배포하는 경우가 대표적인 예입니다. 상대적으로 균일한 분포에 대해 설계된 해시 함수를 사용하여 사용자 ID를 해시한 후 원하는 파티션 수에 따라 모듈로를 가져옵니다.

모든 특수 응용 프로그램은 다중 파티션을 사용해야 합니다. 총 엔터티 수가 적은(예: 2개) 테이블이라고 해도 응용 프로그램에서 초당 수천 건의 요청을 생성할 경우 이를 처리하기 위해 다중 파티션이 필요합니다.

  • 단일 테이블/단일 파티션. 파티션 키 값이 고정된 가장 간단한 옵션으로, 데이터 및 요청 처리량 요구 사항이 제한된(< 500 엔터티/초) 소규모 작업에 적합합니다.

  • 단일 테이블/다중 파티션. 대부분의 배포에 사용되는 일반적인 옵션으로, 대상 쿼리 패턴과 일치하는 파티션 키를 신중하게 선택해야 합니다.

  • 다중 저장소 계정/다중 파티션. 초당 작업 수가 5000개를 초과할 것으로 예상되는 경우 여러 저장소 계정에 걸쳐 분산된 테이블을 사용해야 합니다.

데이터 균형 조정(다시 분할)을 선택할 경우 새 파티션 키로 모든 엔터티를 읽고 복사한 후 기존 데이터를 삭제해야 하는 작업까지 포함되어 비용이 많이 들 수도 있습니다. 파티션의 최소 크기 제한은 없으며 단일 엔터티(행)로 파티션을 구성할 수도 있습니다.

응용 프로그램이 단일 테이블에서 공급하는 처리량보다 더 많은 처리량을 필요로 할 경우(파티션을 신중하게 선택한 후) 다른 저장소 계정에서 여러 개의 동시 테이블을 활용합니다. 이러한 맥락에서 적절한 저장소 계정을 선택할 수 있도록 응용 프로그램에 적절한 라우팅 논리를 구현해야 합니다.

Azure CDN(콘텐츠 배달 네트워크)은 BLOB 또는 응용 프로그램 출력의 정적 콘텐츠를 전 세계적으로 분산된 캐싱 네트워크에서 캐시할 수 있는 효율적인 방법을 제공합니다. 이렇게 하면 응용 프로그램의 정적 콘텐츠 배달 부담을 완화하고 전체적인 최종 사용자 경험을 개선할 수 있습니다.

콘텐츠 배달 네트워크 가용성 SLA는 매월 캐시된 개체를 가용성 99.9%로 배달할 것을 보장합니다.

CDN을 사용하려면 구독에 대해 기능을 활성화해야 합니다. 그런 다음 공개적으로 사용 가능한 익명 액세스 컨테이너의 BLOB 콘텐츠와 익명 응용 프로그램 출력 콘텐츠(예: http://www.myapp.com/cdn/somepage.aspx)를 캐시할 수 있습니다.

일반적으로 대규모 응용 프로그램의 경우 자주 사용되는 정적 콘텐츠(이미지, css 등)는 적절한 캐시 만료 정책이 적용되는 CDN을 통해 제공해야 합니다.

1백만 권의 전자책이 있는 온라인 서점을 예로 들어 보겠습니다. CDN에 있는 모든 책의 콘텐츠(이미지 등)를 포함하려면 비용이 매우 많이 듭니다. 대부분의 콘텐츠는 자주 이용하지도 않을 뿐더러 지속적으로 만료되기 때문입니다. 그에 반해 베스트셀러 50 같은 인기 콘텐츠만 포함한다면 가격 대비 적절한 캐싱 믹스를 제공할 수 있습니다.

대규모 서비스를 성공적으로 제공하기 위한 핵심 요소 중 하나는 응용 프로그램의 작업, 성능 및 최종 사용자 경험을 파악할 수 있는 원격 분석입니다. Azure 응용 프로그램의 원격 분석 방식은 플랫폼의 수평 확장/분산되는 특성과 원격 분석을 수집, 분석 및 사용하기 위한 플랫폼 서비스를 모두 고려해야 합니다.

Azure의 원격 분석을 수집하고 이해하기 위한 기본이 되는 기술 구성 요소는 WAD(Azure 진단)입니다. WAD는 개별 인스턴스에서 데이터를 수집하여 중앙의 컬렉션 지점(저장소 계정)으로 전달하는 에이전트와 데이터를 저장하고 액세스하기 위한 표준 구조 및 규칙 집합으로 구성됩니다. 에이전트는 배포된 프로젝트 코드 내에 포함된 구성 파일인 코드(.NET) 또는 BLOB 저장소에 배포된 중앙 집중식 구성 파일을 포함하여 다양한 구성 방식을 지원합니다. 구성은 마지막 인스턴스에서 부분적으로 동적이므로 업데이트된 진단 파일을 BLOB 저장소에 밀어넣은 다음 대상 에이전트로 끌어내릴 수 있습니다.

WAD 구성은 다양한 데이터 원본을 제공합니다. 각각의 데이터 원본은 주기적으로 수집되어 ETW(Windows용 이벤트 추적) 세션을 통해 일괄 처리된 후 대상 저장소 계정에 게시됩니다. 에이전트는 일시적인 연결 문제, 재시도 등을 처리합니다. 사용 가능한 데이터 원본은 다음과 같습니다.

  • 성능 카운터. 로컬 ETW 세션으로 캡처되어 주기적으로 테이블 저장소에 게시되는 성능 카운터 값의 하위 집합입니다(CPU, 메모리 등).

  • Windows 이벤트 로그. 로컬 ETW 세션으로 캡처되어 주기적으로 테이블 저장소에 게시되는 Windows 이벤트 기록입니다(응용 프로그램, 시스템 등).

  • Azure 로그. 응용 프로그램 코드에 의해(System.Diagnostics.Trace를 통해) 게시되고 DiagnosticMonitorTraceListener 추적 수신기에 의해 캡처되는 응용 프로그램 로그(추적 메시지)입니다. 이러한 로그는 대상 저장소 계정의 WAD 성능 카운터 테이블에 게시됩니다.

  • IIS 7.0 로그. IIS에서 기록하는 요청에 대한 표준 IIS 로그 정보입니다(웹 역할만 해당). 로그는 로컬 파일에 수집되어 주기적으로 BLOB 저장소에 게시됩니다.

  • IIS 실패한 요청 로그. 실패한 요청에 대한 IIS의 정보이며 로컬 파일에 수집되어 주기적으로 BLOB 저장소에 게시됩니다.

  • 크래시 덤프. 시스템이 충돌할 경우 운영 체제의 상태에 대한 로그를 캡처하여 BLOB 저장소에 게시합니다.

  • 데이터 원본. WAD는 추가 로컬 디렉터리(예: 로컬 저장소의 로그 디렉터리)를 모니터링하여 데이터를 BLOB 저장소의 사용자 지정 컨테이너에 주기적으로 복사할 수 있습니다.

각 데이터 원본은 수집할 데이터의 하위 집합(예: 성능 카운터 목록)과 수집/게시 간격으로 구성됩니다. 또한 런타임 구성을 변경하거나 에이전트의 데이터를 대상 저장소 계정에 즉시 개시하도록 강제할 수 있는 다양한 PowerShell 스크립트가 있습니다.

Important중요
원격 분석 결과를 별도의 저장소 계정에 기록해야 합니다. 원격 분석 및 응용 프로그램 데이터를 같은 저장소 계정에 기록할 경우 심각한 경합 문제가 발생합니다.

Azure SQL 데이터베이스는 DaaS(database-as-a-service)를 제공하므로 응용 프로그램이 신속하게 프로비전하고, 데이터를 삽입하고, 관계형 데이터베이스를 쿼리할 수 있습니다. 익숙한 SQL Server의 기능 중 상당 부분을 그대로 제공하는 한편 하드웨어, 구성, 패치 및 복구의 부담을 줄였습니다.

note참고
SQL 데이터베이스는 SQL Server와 1대1로 대응되는 기능을 제공하지는 않으며 클라우드 응용 프로그램의 고유한 요구 사항(탄력적인 확장, 유지 비용을 절감하기 위한 DaaS(database-as-a-service) 등)을 만족하는 것이 목적입니다. 자세한 내용은 http://blogs.msdn.com/b/windowsazure/archive/2012/06/26/data-series-sql-server-in-windows-azure-virtual-machine-vs-sql-database.aspx를 참조하십시오.

서비스는 다중 테넌트 공유 환경에서 실행되며 여러 사용자 및 구독의 데이터베이스는 상용 하드웨어에 구축된 인프라(수직 확장이 아닌 수평 확장)에서 실행됩니다.

데이터베이스는 논리 서버 내부에서 프로비전됩니다. 각 논리 서버는 기본적으로 최대 150개의 데이터베이스를 포함할 수 있습니다(master 데이터베이스 포함). 기본적으로 각 구독은 5개의 논리 서버를 프로비전할 수 있으며, 지원 부서에 문의하여 이러한 할당량과 논리 서버당 최대 데이터베이스 수를 늘릴 수 있는 기능이 제공됩니다.

각 논리 서버마다 고유하게 생성된 공용 DNS 이름([servername].database.windows.net 형식)이 할당되고 구독의 모든 논리 서버는 동일한 공용 IP 주소를 공유합니다. 논리 서버 및 데이터베이스는 표준 SQL 포트(TCP/1433)를 통해 액세스할 수 있으며 REST 기반 관리 API를 사용할 경우 포트 TCP/833을 통해 액세스할 수 있습니다.

기본적으로 논리 서버 및 논리 서버에 포함된 모든 데이터베이스에 대한 액세스 권한은 IP 기반 방화벽 규칙에 의해 Azure 관리 포털로 제한됩니다(논리 서버 또는 개별 데이터베이스에 대해 규칙 설정 가능). Azure 응용 프로그램에 대한 액세스를 허용하고 Azure 외부에서 응용 프로그램에 직접 연결할 수 있도록(예: SQL Server Management Studio에 연결) 설정하려면 방화벽 규칙을 구성해야 합니다. 이러한 규칙은 관리 서비스 API 호출을 사용하여 Azure 관리 포털을 통해 구성할 수 있습니다.

SQL 데이터베이스는 SQL Server의 주요 기능을 대부분 지원하지만 다음과 같은 몇 가지 중요한 예외가 있습니다.

  • 모든 테이블은 CLUSTERED INDEX를 포함해야 합니다. CLUSTERED INDEX가 정의되기 전에는 SQL 데이터베이스의 테이블에 데이터를 INSERT할 수 없습니다.

  • CLR(공용 언어 런타임) 지원, 데이터베이스 미러링, Service Broker, 데이터 압축 또는 테이블 분할 기능이 내장되어 있지 않습니다.

  • XML 인덱스는 없지만 XML 데이터 형식은 지원됩니다.

  • TDE(투명한 데이터 암호화) 또는 데이터 감사를 지원하지 않습니다.

  • 전체 텍스트 검색을 지원하지 않습니다.

생성되는 각 데이터베이스는 최대 크기가 제한됩니다. 현재 제공되는 용량은 1GB, 5GB, 10GB, 20GB, 30GB, 40GB, 50GB, 100GB 및 150GB(현재 최대 크기)가 있습니다. 데이터베이스가 최대 크기 제한에 도달하면 더 이상의 INSERT 또는 UPDATE 명령을 거부합니다(데이터를 쿼리하고 삭제하는 명령은 가능). ALTER DATABASE 명령을 실행하여 데이터베이스 크기를 변경(확장 또는 축소)할 수도 있습니다.

데이터베이스는 일일 평균 사용 크기에 따라 요금이 청구되며, 급격한 성장이 예상되거나 성장 속도를 예측할 수 없는 응용 프로그램은 처음부터 데이터베이스 최대 크기를 150GB로 선택하는 것도 나쁘지 않습니다. 데이터베이스를 150GB 이상으로 확장하려면 아래 단원에 자세히 설명된 수평 확장 방식을 활용해야 합니다.

SQL 데이터베이스는 노드 수준 오류를 복구할 수 있는 복구 기능을 기본적으로 제공합니다. 데이터베이스에 대한 모든 쓰기 작업은 쿼럼 커밋 기술을 사용하여 두 개 이상의 배경 노드에 자동으로 복제됩니다(주 데이터베이스와 하나 이상의 보조 데이터베이스에서 작업이 트랜잭션 로그에 기록된 것을 확인한 후 트랜잭션이 정상적으로 처리된 것으로 간주하고 반환해야 함). 노드 오류가 발생할 경우 데이터베이스가 자동으로 보조 복제본 중 하나로 장애 조치(failover)합니다. 이로 인해 클라이언트 응용 프로그램에 대한 일시적 연결 오류가 발생할 수 있으며 바로 이러한 이유로 모든 SQL 데이터베이스 클라이언트에 일시적 연결 오류를 처리할 수 있는 기능을 구현해야 합니다. 일시적 연결 오류 처리에 대한 자세한 내용은 아래를 참조하십시오.

월별 가용성 SLA는 5분 간격으로 30초 이내에 SQL 데이터베이스에 연결할 수 있는 기능에 정의된 대로 99.9%의 가동 시간을 제공합니다. 이전 단원에서 설명한 장애 조치(failover) 이벤트는 대부분 30초 이내에 발생하므로 응용 프로그램이 일시적 연결 오류를 처리할 수 있도록 해야 합니다.

SQL 데이터베이스는 DMV(동적 관리 뷰)를 통해 상태 및 성능에 대한 정보를 제공합니다. 이러한 DMV는 쿼리 성능, 데이터베이스 및 테이블 크기 등 시스템의 주요 측면에 대한 정보를 포함하고 있습니다. 응용 프로그램은 주요 DMV의 정보를 주기적으로 수집하여 분석한 후 보다 광범위한 원격 분석 및 고급 정보 프레임워크와 통합하는 역할을 담당합니다.

SQL 데이터베이스에 사용할 수 있는 여러 가지 비즈니스 연속성(백업, 복원) 옵션이 있습니다. 데이터베이스 복사 기능 또는 DAC 가져오기/내보내기 서비스를 통해 데이터베이스를 복사할 수 있습니다. 데이터베이스 복사는 트랜잭션에 일관성이 있는 결과를 제공하는 반면 가져오기/내보내기 서비스를 통한 bacpac는 그렇지 않습니다. 두 옵션 모두 데이터 센터 내에서 큐 기반 서비스로 실행되며 현재는 완료 시간 SLA를 제공하지 않습니다.

데이터베이스 복사 및 가져오기/내보내기 서비스는 원본 데이터베이스에 상당한 부하를 주기 때문에 리소스 경합 또는 제한 이벤트가 트리거될 수 있습니다(아래의 공유 리소스 및 제한 단원 참조). 이러한 방법 중 어떤 것도 SQL Server와 동일한 수준의 증분 백업을 제공하지는 않지만 지정 시간 복원 기능을 설정할 수 있는 새로운 기능이 현재 미리 보기로 제공되고 있습니다. 지정 시간 복원 기능을 사용하면 사용자가 데이터베이스를 2주 이내의 특정 시점으로 복원할 수 있습니다.

현재 유일하게 지원되는 인증 기술은 SQL 인증, 데이터베이스에 등록된 사용자를 기반으로 한 단일 요소 사용자 이름/암호 로그인입니다. Active Directory 또는 2단계 인증 기능은 아직 제공되지 않습니다. ADO.NET, ODBC 등으로 제공되는 내장된 암호화 지원을 사용하여 SQL 데이터베이스에 대한 연결을 암호화할 것을 권장합니다. 데이터베이스 수준 사용 권한은 SQL Server와 동일합니다. Azure SQL 데이터베이스 보안 설정에 대한 자세한 내용은 Azure SQL 데이터베이스에서 데이터베이스 및 로그인 관리를 참조하십시오.

SQL 데이터베이스는 쿼리 성능 및 데이터베이스 상태를 관찰할 수 있는 풍부한 동적 관리 뷰를 제공합니다. 그러나 이 데이터를 수집하여 분석하는 자동화된 인프라는 제공되지 않으며 이와 비슷한 기능을 가진 직접 연결된 프로파일러, OS 수준 성능 카운터 등의 도구도 제공되지 않습니다. 데이터 수집 및 분석 방식은 이 문서의 원격 분석 단원에 설명되어 있습니다.

위에서 설명한 대로 SQL 데이터베이스는 공유 인프라에서 실행되는 다중 테넌트 서비스입니다. 다른 테넌트의 데이터베이스는 상용 하드웨어를 기반으로 구축되는 기본 실제 노드를 공유 합니다. 시스템의 다른 사용자는 동일한 기본 인프라의 주요 리소스(작업자 스레드, 트랜잭션 로그, I/O 등)를 사용할 수 있습니다. 리소스 사용량은 데이터베이스를 설정된 리소스 경계 내에서 유지하도록 제어됩니다. 이러한 제한에 도달하면 테넌트 또는 실제 노드 수준에서 SQL 데이터베이스가 사용량을 제한하거나 연결을 끊는 방법으로 응답합니다. 이러한 제한은 아래 표에 나열되어 있습니다.

 

리소스 트랜잭션당 최대 값/세션 실제 노드당 최대 값 소프트 제한 한도 하드 제한 한도

작업자 스레드

해당 없음

512

305

410

데이터베이스 크기

데이터베이스당 최대 150GB

해당 없음

없음

100%. 제한에 도달한 후에는 삽입 또는 업데이트가 허용되지 않음

트랜잭션 로그 증가

트랜잭션당 2GB

500 GB

해당 없음

해당 없음

트랜잭션 로그 길이

총 로그 공간의 20%(100GB)

500 GB

해당 없음

해당 없음

잠금 카운트

트랜잭션당 1백만

해당 없음

해당 없음

해당 없음

시스템 작업 차단

20초

해당 없음

해당 없음

해당 없음

임시 DB 공간

5 GB

해당 없음

해당 없음

5 GB

메모리

해당 없음

해당 없음

해당 없음

20 초 이상 16MB

최대 동시 요청

데이터베이스당 400개

해당 없음

해당 없음

해당 없음

트랜잭션 한계에 도달 하면 시스템에서는 트랜잭션을 취소하는 방식으로 응답합니다. 데이터베이스가 소프트 제한에 도달하면 트랜잭션 및 연결 속도가 느려지거나 중단됩니다. 하드 제한 한도에 도달하면 기본 실제 노드의 모든 데이터베이스 및 사용자에게 영향을 미쳐 기존 작업이 종료되고 리소스가 제한 임계값 아래로 떨어질 때까지 새로운 작업 또는 연결이 제한됩니다.

이러한 제한 한도 중 일부는 응용 프로그램의 디자인 및 성능을 정확하게 제한하기가 어려울 수 있습니다. 예를 들어 트랜잭션 로그 증가를 트랜잭션당 최대 2GB로 제한할 경우 인덱스를 구축하면 2GB가 넘는 트랜잭션 로그가 생성되는 대규모 테이블에는 인덱스를 구축할 수 없습니다. 이러한 작업을 수행하는 기술은 이 문서의 최선의 구현 방법 단원에서 설명하겠습니다.

이러한 제한 조건 및 일시적 오류를 처리하려면 클라이언트 코드를 신중하게 디자인하여 구현해야 합니다. 이러한 문제를 해결하려면 데이터베이스 계층을 수평 확장하여 여러 데이터베이스를 동시에 활용해야 합니다. 수평 확장은 다음 단원에서 다루겠습니다.

SQL 클라이언트 응용 프로그램 코드는 다음과 같아야 합니다.

  • 제한과 관련된 SQL 오류 코드를 인식하고 적절한 백오프 논리를 제공하는 재시도 코드 구현. 응용 프로그램에 특정 형태의 백오프 논리가 없으면 데이터베이스에 대해 최대 부하를 계속 밀어넣어 데이터베이스를 연속 제한 상태로 잠글 수 있습니다.

  • 임시 연결, 제한 및 하드 오류를 구분하는 재시도 코드를 사용하여 제한 오류 기록(구문, 누락된 저장 프로시저 등). 이렇게 하면 응용 프로그램 가용성 문제를 추적하고 해결하는 데 도움이 됩니다.

  • 회로 차단기 패턴 구현. 적절히 선택한 재시도 정책이 만료된 경우(응용 프로그램의 재시도 빈도와 대기 시간 및 시스템 응답을 균형 있게 조정) 코드 경로를 호출하여 일시적이지 않은 오류를 처리합니다(즉, 차단기 작동). 그러면 응용 프로그램 코드가 다음을 수행할 수 있습니다.

    • 다른 서비스 또는 방법으로 대체. 응용 프로그램이 SQL 데이터베이스에 새로운 데이터를 삽입하지 못한 경우(데이터를 즉시 사용하지 않아도 된다면) 데이터를 대신 DataTable(또는 다른 XML/JSON 형식)로 직렬화하고 BLOB 저장소의 파일에 기록해야 합니다. 그러면 응용 프로그램이 사용자(또는 API 호출)에 대해 성공 코드를 반환하고 나중에 데이터베이스에 데이터를 삽입할 수 있습니다.

    • 데이터 또는 워크플로가 선택 사항인 경우(최종 사용자 환경에 영향을 주지 않음) null 값을 반환하여 자동 실패

    • 유용한/적절한 대체 메커니즘이 없는 경우 오류 코드를 반환하여 빠른 오류.

SQL 데이터베이스는 상대적으로 작은 확장 단위(데이터베이스)를 간편하게 대규모로 제공할 수 있습니다. SQL 데이터베이스를 활용하는 Azure에 확장성이 높은 응용 프로그램을 구현하려면 다양한 요구 사항을 충족하는 여러 데이터베이스의 리소스로 이루어진 수평 확장 방법을 사용해야 합니다. 기존에 응용 프로그램은 유연성이 뛰어난 단일 수평 확장 데이터베이스 서버의 "티타늄 달걀 껍질"에 목표를 두었지만 응용 프로그램이 수평 확장 데이터베이스 서비스를 효율적으로 활용하게 만들려면 신중하게 설계해야 합니다.

SQL 데이터베이스는 다른 핵심 Azure 서비스와 마찬가지로 수평 확장 및 구성이 추가 확장(데이터베이스 크기, 처리량) 및 리소스(작업자 스레드 등)를 위한 해결책입니다. SQL 데이터베이스 분할(즉, 수평 확장)을 구현하는 핵심적인 방법에는 두 가지가 있습니다. 이러한 방법은 응용 프로그램 내에서 상호 배타적이지 않습니다.

  • 행 분할. 수평 분할 방식에서는 원본 테이블 또는 데이터 집합이 개별 데이터베이스로 분리됩니다. 예를 들어 다양한 고객 집합에 서비스를 제공하는 다중 테넌트 응용 프로그램의 경우 고객별로 데이터베이스를 만들 수 있습니다. 대규모의 단일 테넌트 응용 프로그램의 경우 고객 테이블이 주문 테이블과 다른 데이터베이스에 상주할 수 있습니다. 분할 키는 일반적으로 테넌트 식별자(예: 고객 ID)입니다. 아래 다이어그램에서 데이터 집합은 전자 메일의 해시를 파티션 값으로 사용하여 3개의 데이터베이스로 수평 분할되었습니다(즉, 파티션 키는 전자 메일이고 파티션 함수는 키의 해시를 사용하여 대상 데이터베이스로 매핑됨).

  • 수직 분할. 수직 분할 방식에서는 스키마 분할에 따라 데이터 집합이 여러 물리적 테이블 또는 데이터베이스에 분산됩니다. 예를 들어 고객 데이터 및 주문 데이터가 여러 물리적 데이터베이스에 분산될 수 있습니다. 아래 다이어그램에서는 데이터 집합이 두 개의 데이터베이스로 수직 분할되었습니다. 핵심 사용자 정보(이름, 전자 메일)는 DB1에 저장되고, 사용자 프로필 정보(예: 아바타 사진의 URI)는 DB2에 저장됩니다.

많은 응용 프로그램은 수평 및 수직 분할이 혼합된 방식(혼합 분할)을 사용하고 추가 저장소 서비스를 통합합니다. 예를 들어 위의 예에서는 사용자의 아바타 사진이 ID로 데이터베이스에 저장되고, 응용 프로그램이 전체 URL로 확장됩니다. 그런 다음 이러한 URL이 BLOB에 저장된 이미지에 매핑됩니다.

수평 확장된 관계형 데이터 저장소로 작업할 경우 가용성 계산 방식이 매우 다릅니다. 분할된 데이터베이스가 많은 시스템은 일부 개별 데이터 세그먼트가 오프라인 상태일 확률이 높고, 전체 응용 프로그램을 사용할 수 없을 확률은 매우 낮습니다. 응용 프로그램은 백 엔드 데이터 저장소의 부분적인 가용성을 고려해야 합니다. 수평 확장된 데이터 모델에서 데이터 가용성은 더 이상 전부 아니면 전무 상태가 아닙니다.

데이터를 다시 분할하는 작업은 사용 모델 또는 데이터 분포가 시간의 경과에 따라 변하는 경우에 특히 어려울 수 있습니다. 역할 기반의 분할 키를 사용하려면 고정된 수(분할 값의 해시 모듈로 사용) 또는 분할 값의 분포 중 어디에 기반을 두건 관계없이 분할된 개별 데이터베이스 간에 데이터를 균형 있게 조정해야 합니다. 범위 기반 파티션 구성표는 이진 분할 또는 병합을 사용하여 균형 조정 작업을 간소화하는 경우가 많습니다.

예를 들어 고정 범위 분할 방법(예: 성의 첫 글자)은 처음에는 균형 잡힌 분포가 될 수 있지만 새로운 사용자가 나타날 때마다 사용자의 성이 추가되면서 알파벳이 고르게 분포되거나 분포되지 않을 수 있어 빠른 시간 안에 심한 불균형을 초래하게 될 수 있습니다. 시간 경과에 따른 분할 메커니즘의 조정 필요 여부와 데이터 균형 조정 비용을 염두에 두어야 합니다.

조회 기반의 파티션 구성 표는 모든 데이터 테넌트 또는 파티션에 대한 고성능 조회 메커니즘이 필요하기 때문에 세분화된 균형 조정보다 구현하기가 더 어렵지만 단일 테넌트가 개별적으로 새 파티션에 맞게 균형 조정될 수 있으므로 다루기가 더 쉽습니다. 또한 데이터를 복사할 필요 없이 시스템에 추가 용량(새 데이터베이스 등)을 추가할 수 있습니다.

분할 방법을 혼합하든 관계없이 분할된 관계형 데이터베이스의 수평 확장 방식으로 전환할 경우 특정 제한 사항이 적용되어 다른 데이터 관리 및 쿼리 방식이 필요합니다.

  • 기존의 “양호한” SQL 데이터 저장소 및 쿼리 디자인이 고도로 정규화된 데이터 모델을 활용하여 저장 및 일관성에 맞게 최적화되었습니다. 이러한 방식은 상호 참조 및 테이블 간 조인을 활용하여 전역적으로 일관적인 데이터 공간을 가정합니다. 데이터가 물리적으로 분산된 노드에 분산되어 있으므로 조인 및 상호 참조는 하나의 분할된 데이터베이스 내에서만 허용됩니다. SQL 데이터베이스는 여러 데이터베이스에 분산된 쿼리를 지원하지 않습니다. 클라이언트 계층에서 데이터 병합이 처리되어야 하며 분할된 데이터베이스 간에 데이터 역정규화 및 복제가 처리되어야 합니다.

  • 참조 데이터 및 메타데이터는 일반적으로 참조 테이블에 중앙 집중화됩니다. 수평 확장 방법에서는 이러한 참조 테이블 및 일반적인 분할 키로 분리할 수 없는 데이터를 분할된 데이터베이스 간에 복제하고 일관성을 유지해야 합니다.

  • 분할된 데이터베이스 간에 확장 가능하며 적절한 성능의 분산 트랜잭션을 제공할 수 있는 실용적인 방법은 없습니다. 데이터 및 스키마 업데이트는 분할된 데이터베이스 간에 트랜잭션 방식으로 일관되지 않습니다. 응용 프로그램 코드는 분할된 데이터베이스 간에 어느 정도의 느슨한 일관성을 가정하고 고려합니다.

  • 응용 프로그램 코드는 분할 메커니즘(수평, 수직, 분할 유형)을 이해해야 적절한 분할된 데이터베이스에 연결할 수 있습니다.

  • Entity Framework와 같은 일반 ORM은 기본적으로 수평 확장 데이터 모델을 인식하지 못합니다. 대규모 ORM을 광범위하게 사용하는 응용 프로그램은 수평 분할과 호환되도록 상당 부분을 다시 설계해야 할 수 있습니다. 수직으로 분할된 방법에서 테넌트(고객 집합)를 단일 데이터베이스로 격리하는 디자인은 일반적으로 데이터 액세스 계층에서 다시 디자인해야 할 부분이 적습니다. 순수 수직 분할 모델의 단점은 각각의 개별 분할이 단일 데이터베이스 용량의 제한을 받는다는 점입니다.

  • 여러 분할된 데이터베이스를 건드려야 하는(읽거나 씀) 쿼리는 대상 분할된 데이터베이스에 대해 개별 쿼리가 실행되고 결과 집합이 클라이언트 데이터 액세스 계층에 집계되는 분산/수집 패턴을 사용하여 구현되어야 합니다.

SQL 데이터베이스를 사용한 수평 확장은 데이터를 여러 SQL에 수동으로 분할하여 수행합니다. 이러한 수평 확장 방법은 규모에 따라 선형에 가까운 비용 증가를 달성할 수 있는 기회를 제공합니다. 필요에 따라 탄력적인 성장이나 용량 증가와 함께 비용이 증가할 수 있습니다. 일부 응용 프로그램은 상당 부분을 다시 디자인해야 이러한 수평 확장 모델을 지원할 수 있습니다.

  • 분할된 데이터베이스를 대량으로 업데이트할 경우에 특히 스키마 업데이트가 트랜잭션 방식으로 일관되지 않을 수 있습니다. 응용 프로그램은 계획된 가동 중지 기간을 허용하거나 여러 동시 작업 버전의 배포된 스키마를 고려해야 합니다.

  • 비즈니스 연속성 프로세스(백업/복원 등)는 여러 데이터 조각을 고려해야 합니다.

이러한 문제를 해결하기 위한 디자인 권장 사항 및 최선의 구현 방법은 이 문서의 최선의 구현 방법 섹션에 나와 있습니다.

이 문서의 나머지 부분에서는 실제 환경 및 제공하는 교육에 따라 Azure 및 SQL 데이터베이스를 사용하여 확장성이 높은 응용 프로그램을 제공하기 위한 최선의 구현 방법을 주로 설명합니다. 각각의 최선의 구현 방법에서는 대상 최적화 및 구성 요소, 구현 방법, 내재된 장단점에 대해 설명합니다. 다른 모든 최선의 구현 방법과 마찬가지로 이러한 권장 사항은 적용되는 상황에 따라 크게 달라집니다. 이전 섹션에서 설명한 플랫폼 기능에 따라 각각의 최선의 구현 방법을 평가하여 가장 적합한 방법을 찾으십시오.

note참고
이러한 경험은 일반적인 OLTP(온라인 트랜잭션 처리) 패턴을 따르지 않는 여러 고객 계약에서 도출되었습니다. 이러한 최선의 구현 방법 중에는 강력한, 또는 엄격한 데이터 일관성이 요구되는 응용 프로그램에 바로 적용할 수 없는 최선의 구현 방법도 있다는 것을 알아두십시오. 자신의 응용 프로그램 및 환경의 정확한 비즈니스 요구 사항은 자신만이 압니다.

각각의 최선의 구현 방법은 하나 이상의 최적화 측면과 관련이 있습니다.

  • 처리량. 시스템을 통해 작업(트랜잭션, 서비스 호출 등) 수를 늘리고 경합을 줄이는 방법.

  • 대기 시간. 집계 및 개별 작업 모두에서 대기 시간을 줄이는 방법.

  • 밀도. 직접 컨텍스트(예: SQL 데이터베이스에 대한 응용 프로그램 코드) 및 집계 컨텍스트(규모 확장을 위해 여러 저장소 계정 활용) 모두에서 서비스를 구성할 때 경합 지점을 줄이는 방법.

  • 관리 효율성. 진단, 원격 측정 및 고급 정보 - 대규모로 배포된 서비스의 상태 및 성능을 파악하는 방법.

  • 가용성. 실패 지점 및 모드의 영향을 줄여 전반적인 응용 프로그램 가용성을 높이는 방법(로드가 있는 상황의 가용성은 처리량/대기 시간/밀도에서 다룸).

Azure의 기본 척도 단위인 호스팅된 서비스의 신중한 디자인 및 배포는 확장성과 가용성이 높은 서비스를 제공하는 데 매우 중요합니다.

  • 호스팅된 서비스 내에서 여러 인스턴스 및 업그레이드 도메인은 호스팅된 서비스를 배포, 구성 및 업그레이드해야 하는 시기에 큰 영향을 줄 수 있습니다. 이러한 이점을 얻는 데 따른 복잡성 증가와 성능 및 확장성 이점을 균형 있게 조정하십시오. 확장성 및 유연성이 개선되면 일반적으로 솔루션의 개발 및 관리 비용이 증가합니다.

  • 단일 인스턴스 역할은 피하십시오. 이러한 구성은 Azure SLA의 요구 사항에 부합하지 않습니다. 노드 실패 또는 업그레이드 시 단일 인스턴스 역할은 오프라인 상태가 됩니다. 이들의 용도를 우선 순위가 낮은 "유지 관리" 작업으로 제한하십시오.

  • 모든 데이터 센터는 한정된(그러나 대규모의) 용량을 보유하고 있고 드문 경우지만 단일 실패 지점이 될 수 있습니다. 최고 수준의 확장성 및 가용성이 필요한 서비스는 여러 개의 호스팅되는 서비스를 지원하는 다중 데이터 센터 토폴로지를 구현해야 합니다. 그러나

  • 최고 수준의 가용성이 필요하지 않은 경우에는(위의 항목 참조) 응용 프로그램 및 종속 서비스를 단일 데이터 센터 내에 완전히 포함하십시오. 솔루션에서 여러 데이터 센터를 사용해야 하는 경우 다음 지침을 따르십시오.

    • 의도적인 사이트 간 동기화 외부에서 실시간 작업에 대한 데이터 센터 간 네트워크 호출을 피하십시오. 데이터 센터 간 장거리 대기 시간이 매우 가변적일 수 있고 예기치 않은 또는 원하지 않는 응용 프로그램의 성능 특성을 생성할 수 있습니다.

    • 다른 데이터 센터의 서비스에 액세스하는 필수 기능은 최소한으로만 유지하십시오. 일반적으로 이러한 활동은 비즈니스 연속성 및 데이터 복제와 관련이 있습니다.

대규모 분산 응용 프로그램의 경우 상태 저장 응용 프로그램 데이터에 대한 액세스가 중요합니다. 전반적인 응용 프로그램 처리량 및 대기 시간은 일반적으로 필요한 데이터 및 컨텍스트를 검색, 공유 및 업데이트하는 속도의 제한을 받습니다. Azure Caching 및 memcached와 같은 분산 캐시 서비스는 이러한 요구 사항에 따라 진화했습니다. 응용 프로그램은 분산 캐시 플랫폼을 활용해야 합니다. 다음 지침을 살펴 보십시오.

  • 호스팅된 서비스 내에서 분산 캐싱 플랫폼을 작업자 역할로 활용합니다. 캐시의 클라이언트에 대한 이러한 근접성은 부하 분산 장치 순회에 따른 대기 시간 및 처리량 장벽을 줄여 줍니다. Azure 캐시의 역할 내 캐시는 클라우드 서비스 내의 작업자 역할에 캐싱을 호스팅합니다.

  • SQL 데이터베이스 또는 다른 영구 저장소에서 지원되는 일반적인 응용 프로그램 데이터 및 개체(예: 사용자 프로필 및 세션 상태)에 read-through 또는 캐시 배제 방법으로 액세스하기 위한 기본 리포지토리로 분산 캐싱 플랫폼을 사용하십시오.

  • 캐시 개체에는 분산 캐시에서 활성화되는 기간에 영향을 주는 TTL(Time to Live)이 있습니다. 응용 프로그램은 캐시된 개체에 대해 TTL(Time to Live)을 명시적으로 설정하거나 캐시 컨테이너의 기본 TTL(Time to Live)을 구성합니다. 데이터의 가용성(캐시 적중)과 메모리 압력 및 소진 간에 균형 잡힌 TTL(Time to Live)을 선택합니다.

  • 캐시는 키->바이트[] 의미 체계를 보여 줍니다. 캐시에 일관되지 않은 데이터를 만드는 쓰기 겹치기의 가능성에 대해 알고 있어야 합니다. 분산 캐시는 일반적으로 저장된 데이터의 구조를 모르기 때문에 저장된 데이터를 자동 업데이트하는 API를 제공하지 않습니다.

    • 동시 쓰기에 엄격한 일관성이 요구되는 응용 프로그램의 경우 엔터티 업데이트에 대한 잠금 메커니즘을 제공하는 분산 캐싱 플랫폼을 사용하십시오. Azure 캐싱의 경우 GetAndLock/ PutAndUnlock을 통해 이를 구현할 수 있습니다. 참고: 이렇게 하면 처리량이 저하될 수 있습니다.

  • 캐시 성능은 응용 프로그램 계층에서 개체를 직렬화하고 역직렬화하는 데 필요한 시간에 따라 달라집니다. 이 프로세스를 최적화하려면 상대적으로 대칭적이고(데이터 인코딩/디코딩에 필요한 시간이 동일한), 매우 효율적인 protobuf와 같은 이진 직렬 변환기를 활용하십시오.

    • 사용자 지정 직렬화를 성공적으로 사용하려면 캐시에 직렬화할 DTO(데이터 전송 개체)를 디자인하고, 직렬화를 위한 적절한 주석을 사용하고, 순환 종속성을 피하고, 단위 테스트를 활용하여 효율적인 직렬화를 추적하십시오.

기본적으로 부하 분산 장치를 통한 인바운드 연결을 비롯한 서비스 계층 간 연결에는 연결 고정이 제한된 라운드 로빈 할당 체계가 적용됩니다. 다음 다이어그램에서는 계층과 외부 서비스 간의 일반적인 연결 메시를 보여 줍니다(왼쪽이 일반적인 웹 계층 전용 응용 프로그램). 이러한 메시는 HTTP와 같은 경량 연결 프로토콜에서 큰 성능 문제를 유발하지 않지만 특정 연결은 연결/초기화 비용이 많이 들거나 제한되는 리소스입니다. 예를 들어 SQL 데이터베이스 연결이 이 범주에 속합니다. 이러한 외부 서비스 및 구성 요소의 사용을 최적화하려면 특정 인스턴스에 대한 리소스 호출의 선호도를 설정하는 것이 좋습니다.

위의 다이어그램에서 오른쪽의 토폴로지에는 동일한 호스팅 서비스 내에 별도의 웹 및 작업자 계층(역할)이 있습니다. 이 토폴로지에는 또한 특정 응용 프로그램 인스턴스의 호출을 특정 데이터베이스에 고정하기 위해 웹 및 응용 프로그램 계층 간 선호도가 구현되어 있습니다. 예를 들어 데이터베이스 1(DB1)에서 데이터를 요청하려면 웹 인스턴스가 응용 프로그램 인스턴스 1 또는 2를 통해 데이터를 요청해야 합니다. Azure 부하 분산 장치는 현재 라운드 로빈 방법만 구현하기 때문에 응용 프로그램에 선호도를 설정하려면 신중하게 설계하고 구현해야 합니다.

  • 별도의 웹 및 응용 프로그램 계층을 사용하여 웹 및 응용 프로그램 계층 간에 파티션 또는 리소스 인식 선호도를 제공하여 응용 프로그램을 설계합니다.

  • 서비스 내 호출을 대상 응용 프로그램 인스턴스에 투명하게 라우팅하는 라우팅 논리를 구현합니다. 외부 또는 다운스트림 리소스(예: SQL 데이터베이스)에서 사용되는 분할 메커니즘에 대한 지식을 활용하십시오.

이러한 다중 계층 아키텍처를 실용적으로 구현하려면 웹 및 응용 프로그램 계층 간에 효율적인 경량 프로토콜을 사용하는 매우 효율적인 서비스 통신이 필요합니다.

Azure 응용 프로그램의 개발 기술은 Windows 서버의 개발 기술과 근본적으로 다르지 않습니다. 그러나 탄력적인 패브릭은 컴퓨팅 리소스를 가장 효과적으로 사용하는 효율적인 코드를 적용해야 할 필요성과 그 이점을 강조합니다.

  • 모든 서비스, 네트워크 호출 및 종속 리소스가 잠재적으로 불안정하고, 일시적인 오류 모드 및 지속적인 오류 모드에 취약하다고 가정해 보겠습니다(예: SQL 데이터베이스의 재시도 논리를 구현하는 방법은 이 항목의 뒷부분에 나옴).

    • 모든 서비스 호출(SQL 데이터베이스, 저장소 등)에 적절한 재시도 정책을 구현하여 일시적인 오류 상태 및 연결 중단을 처리하십시오.

    • 재시도 논리에 백오프 정책을 구현하여 "호위(convoy)" 효과(서비스에 대한 재시도가 누적되어 중단이 계속됨)를 피하십시오.

    • 오류 메시지 및 실패 이벤트를 컨텍스트 정보(대상 서비스, 사용자/계정 컨텍스트, 활동 등)와 함께 기록하는 데 사용되는 풍부한 클라이언트 쪽 원격 분석을 구현하십시오.

  • 작업을 예약하는 스레드를 직접 만들지 마십시오. 대신 .NET Task Parallel Library와 같은 예약 및 동시 작업 프레임워크를 활용하십시오. 스레드는 상대적으로 무거운 개체이며, 만들고 삭제하는 과정이 중요합니다. 공유 스레드 풀에서 작동하는 스케줄러는 보다 효율적으로 작업을 예약하고 실행할 수 있습니다. 이러한 아키텍처는 또한 연속 및 오류 처리를 설명하는 개략적인 의미 체계를 제공합니다.

  • 직렬화네트워크 전송을 위해 DTO(데이터 전송 개체)를 최적화하십시오. Azure 응용 프로그램의 고도로 분산된 특성을 고려할 때 시스템의 개별 구성 요소가 얼마나 효율적으로 네트워크를 통해 통신할 수 있는지에 따라 확장성이 달라집니다. 통신 또는 저장을 위해 네트워크를 통해 전달된 모든 데이터는 네트워크를 통해 전송되는 메타데이터의 양을 최소화하는 적절한 힌트(예: "통신 중"과 같은 짧은 필드 이름)를 사용하여 JSON 텍스트 직렬화 또는 보다 효율적인 이진 형식을 구현해야 합니다.

    • 상호 운용이 중요한 경우 상호 운용 및 대역 내 메타데이터에 JSON과 같은 효율적인 텍스트 형식을 사용하십시오.

    • 양쪽 모두를 제어하는 서비스 간 통신과 같이 높은 처리량이 중요한 경우 bson 또는 protobuf와 같이 매우 효율적인 압축된 이진 형식을 사용하는 것이 좋습니다.

      • 작은 개체의 데이터를 자주 전송하지 마십시오. 서비스 간에 통신이 자주 발생하면 오버헤드 작업에서 상당한 시스템 리소스가 낭비되고 가변적인 대기 응답에 취약해집니다.

      • 개체 직렬화 및 역직렬화 테스트는 자동화된 테스트 프레임워크의 핵심 구성 요소가 되어야 합니다. 기능 테스트는 데이터 클래스가 직렬화가 가능하고 순환 종속성이 없는지 확인합니다. 성능 테스트는 필요한 대기 시간과 인코딩 크기를 확인합니다.

  • 필요한 경우 구성 요소와 서비스 간 통신을 위한 경량 프레임워크를 활용하십시오. .NET 스택에서 기존의 여러 기술은 Azure의 분산되는 특성에 적합하지 않을 수 있는 풍부한 기능 집합을 제공합니다. 의도와 실행 간에 높은 수준의 추상화를 제공하는 구성 요소는 성능 비용이 많이 발생하는 경우가 많습니다.

    • 프로토콜 상호 운용 또는 고급 프로토콜 지원이 필요하지 않은 경우 WCF 대신 ASP.NET Web API를 사용하여 웹 서비스를 구현하는 방법을 조사해 보십시오.

    • Entity Framework의 풍부한 기능이 필요하지 않을 경우 Dapper와 같은 마이크로 ORM을 사용하여 SQL 클라이언트 계층을 구현하는 방법을 조사해 보십시오.

  • IIS에서 아웃바운드 데이터에 대한 HTTP 압축을 활성화하여 데이터 센터 외부로 전송되는 데이터의 양을 줄이십시오.

  • 계층 간 연결 선호도를 설정하여 연결 빈도와 컨텍스트 전환을 줄이십시오.

  • 응용 프로그램의 로드를 줄이려면 BLOB 저장소를 사용하여 더 큰 정적 콘텐츠를 서비스하십시오(> 100kB).

  • 응용 프로그램의 로드를 줄이려면 BLOB 저장소를 통한 CDN(콘텐츠 배달 네트워크)을 사용하여 이미지 또는 CSS와 같은 정적 콘텐츠를 서비스하십시오.

  • 세션 데이터에는 SQL 데이터베이스를 사용하지 마십시오. 대신 분산된 캐시 또는 쿠키를 사용하십시오.

Azure 저장소는 Azure 응용 프로그램의 견고한 데이터 백본입니다. 대규모 응용 프로그램은 기본적으로 매우 안정적이고 확장성이 높은 환경을 제공할 뿐만 아니라 적절한 설계 및 사용 지침이 필요합니다.

  • 여러 저장소 계정을 활용하면 크기(> 100TB)가 증가하거나 처리량(초당 작업 수 > 5,000개)이 증가하여 확장성이 높아집니다. 작업을 저장소 계정으로 라우팅하는 적절한 파티션 함수를 사용하여 여러 저장소 계정을 사용하도록 응용 프로그램 코드를 구성할 수 있는지 확인하십시오. 코드 변경이 아닌 구성 변경으로써 저장소 계정을 더 추가하는 기능을 설계하십시오.

  • 테이블 저장소의 파티션 함수를 신중하게 선택하여 삽입 및 쿼리 성능 측면에서 원하는 규모를 지원하십시오. 원격 분석 데이터와 관련하여 일시적이지 않은 데이터의 행 데이터에 기반을 둔 복합 키를 사용하는 시간 기반 분할 방식을 고려해 보십시오. 최적의 성능을 얻으려면 파티션을 적절한 범위로 유지하십시오. 파티션이 너무 작으면 쿼리를 포함한 일괄 처리 작업을 수행하는 기능이 제한되는 반면 파티션이 너무 크면 쿼리 비용이 많이 들고 대량 동시 삽입 시 병목 현상이 발생할 수 있습니다.

    • 파티션 함수의 선택도 쿼리 성능에 근본적인 영향을 줄 수 있습니다. 테이블 저장소는 {파티션 키, 행 키}를 사용할 경우 효율적인 조회를 제공하고, {파티션 키, 행 일치 필터} 및 {파티션 키 일치 필터, 행 키 일치 필터}의 처리 효율은 다소 떨어집니다. 쿼리는 글로벌 테이블 검사가 필요합니다({행 키 일치 필터}).

    • 파티션은 단일 엔터티만큼 작게 만들 수 있습니다. 이렇게 하면 쇼핑 카트 관리와 같은 순수 조회 워크로드에 대해 고도로 최적화된 성능이 제공됩니다.

  • 가능한 경우 저장소에 대한 작업을 일괄 처리하십시오. 테이블 쓰기는 일반적으로 .NET 클라이언트 API에서 SaveChanges 메서드를 사용하여 일괄 처리해야 합니다. SaveChanges 메서드를 사용하여 단일 일괄 처리로 테이블에 일련의 행을 삽입한 다음 변경 사항을 커밋합니다. PutBlockList 메서드를 사용하여 BLOB 저장소에 대한 업데이트도 단일 일괄 처리로 커밋해야 합니다. 테이블 저장소 API와 마찬가지로 개별 블록이 아닌 블록 범위에 대해 PutBlockList를 호출하십시오.

  • 메타데이터(속성 이름)는 대역 내에 저장되므로 테이블 속성에 대해 짧은 열 이름을 선택하십시오. 열 이름도 최대 행 크기 1MB에 포함됩니다. 지나치게 긴 속성 이름은 시스템 리소스의 낭비입니다.

Azure 살펴보기 섹션에서 알아본 것처럼 SQL 데이터베이스는 서비스 기능으로 턴키 관계형 데이터베이스를 제공하여 수평 확장 방식으로 데이터 저장소를 확장할 수 있게 해줍니다. 대규모 응용 프로그램에서 SQL 데이터베이스를 성공적으로 사용하려면 몇 가지 신중한 설계 및 구현 옵션이 필요합니다. 주요 디자인 요점 및 최선의 구현 방식이 이 섹션에 나와 있습니다.

대부분의 응용 프로그램에는 라우팅, 분할 및 테넌트 정보와 같은 세부 정보를 저장하기 위한 메타데이터 테이블이 필요합니다. 이러한 메타데이터를 단일 데이터베이스에 저장할 경우 단일 실패 지점과 확장성 병목 현상이 발생합니다. 중앙 메타데이터 저장소는 다음의 조합을 통해 수평 확장해야 합니다.

  • 적극적인 캐싱. 구성 데이터베이스의 정보는 분산 캐시(예: memcached 또는 Azure Caching)에 적극적으로 캐시되어야 합니다.

    • 응용 프로그램을 시작할 때 여러 작업자 스레드의 캐시를 적극적으로 미리 로드하려고 하면 일반적으로 과도한 로드 및 데이터베이스 제한이 발생할 수 있으므로 유의하십시오. 응용 프로그램에 미리 로드된 캐시가 필요할 경우 구성 가능한 로드 속도를 사용하여 전용 작업자 역할(또는 예약된 작업)에 데이터 로드 책임을 위임하십시오.

    • 캐시에 특정 데이터 세그먼트가 있는지 여부에 따라 응용 프로그램의 성능이나 안정성이 달라질 경우 캐시가 미리 채워질 때까지 응용 프로그램이 수신 요청을 거부해야 합니다. 데이터가 채워질 때까지 응용 프로그램은 적절한 오류 메시지 또는 코드를 반환해야 합니다.

  • 확장. 데이터를 수직으로(테이블로) 또는 수평으로(테이블을 여러 조각으로 분할) 분할하여 로드를 여러 데이터베이스에 분산하십시오.

분할된 SQL 데이터베이스의 전반적인 확장성은 개별 데이터베이스(분할된 데이터베이스)의 규모와 이러한 분할된 데이터베이스를 얼마나 효율적으로, 그리고 효과적으로 결합하여 크기를 늘릴 수 있는지에 따라 달라집니다.

  • 트랜잭션 로그 제한에 따라 인덱스 다시 작성과 같은 대규모의 트랜잭션이 제한되므로 개별 테이블은 약 10GB를 초과하지 않아야 합니다. 정확한 한도는 대상 테이블 인덱스의 크기에 따라 달라지므로 데이터베이스에 따라 10GB보다 클 수도 있고 작을 수도 있습니다. 대규모 개별 테이블의 경우 테이블을 더 작은 개별 테이블로 분할하고 분할된 보기를 사용하여 단일 오버레이를 제공하십시오.

    • 개별 테이블의 크기를 작게 유지하면 단계적 업그레이드 시 스키마 변경이나 인덱스 다시 작성이 미치는 영향이 감소합니다. 여러 개의 작은 테이블에 대한 변경은 차단 작업으로 인한 가동 중지 시간 및 대기 시간을 최소화할 수 있습니다.

    • 이같이 분할하면 관리 방법이 복잡해집니다. 인덱스 다시 구성과 같은 작업의 경우 모든 구성 요소 테이블에 대해 반복적으로 수행해야 합니다.

  • 개별 데이터베이스(분할된 데이터베이스)는 적당히 작게 유지하십시오. 50GB가 넘는 데이터베이스에 대해 DB 복사 또는 내보내기와 같은 연속 작업을 수행할 경우 완료되는 데 몇 시간이 걸릴 수 있습니다. 24시간 이상 실행되는 작업은 취소됩니다.

연속 서비스 제공 시 분산된 데이터베이스 업데이트나 스키마 수정 사항을 잘 관리해야 원활한 업그레이드 경로를 확보할 수 있습니다. 프로덕션 데이터 저장소에서 스키마 및 메타데이터 작업을 제어하는 방법에 대한 기존의 모든 최선의 구현 방법이 그 어느 때보다 중요해졌습니다. 예를 들어 100개로 분할된 데이터베이스에서 실수로 삭제한 저장 프로시저를 디버깅하고 문제를 해결하는 작업은 훨씬 더 복잡합니다.

스키마 업데이트 및 데이터 수정 사항은 분할된 데이터베이스 간에 트랜잭션 방식으로 일관되지 않으므로 응용 프로그램 업데이트는 전환 기간 동안 기존의 스키마와 새로운 스키마 모두와 호환되어야 합니다. 이러한 요구 사항은 일반적으로 응용 프로그램의 각 릴리스가 최소한 현재 버전 및 이전 버전의 스키마와 호환되어야 한다는 것을 의미합니다.

데이터베이스의 확장 컬렉션으로 전환하면 연결 관리와 관련된 문제가 발생합니다. 각 SQL 데이터베이스 연결은 클라이언트 API(ADO.NET, ODBC, PHP 등)의 연결 풀링을 많이 사용하므로 상대적으로 비용이 많이 드는 리소스입니다. 각 응용 프로그램 인스턴스가 중앙 SQL Server에 대한 여러 연결을 유지하는 대신 각 응용 프로그램 인스턴스가 여러 데이터베이스 서버에 대한 연결을 잠재적으로 유지해야 합니다.

연결은 비용이 많이 들고 잠재적으로 부족한 리소스이므로 응용 프로그램은 적시에 풀링된 연결을 반환하여 연결을 올바르게 관리해야 합니다. 응용 프로그램 코드는 자동 연결 삭제를 사용해야 합니다. .NET에서는 다음과 같이 SqlConnection의 모든 사용을 using 문 내에 래핑하는 것이 좋습니다.

using (var conn = new SqlConnection(connStr))
{
    // SQL client calls here
}

앞서 설명한 것처럼 SQL 데이터베이스에 연결 시 일시적인 연결 오류가 발생할 수 있습니다. 이러한 일시적인 오류를 방지하려면 모든 연결과 명령에서 재시도 논리를 사용해야 합니다(자세한 내용은 아래 내용 참조).

SQL 데이터베이스는 TCP 연결만(명명된 파이프 지원 안 함) 지원하므로 응용 프로그램 코드와 SQL 데이터베이스 간 연결을 암호화하는 것이 좋습니다. 명명된 파이프 사용 시도와 같은 의도하지 않은 연결 시도를 방지하려면 응용 프로그램이 SQL 연결 문자열의 형식을 다음과 같이 지정해야 합니다.

Server=tcp:{servername}.database.windows.net,1433;Database={database};User ID={userid}@{database};Password={password};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;

대규모 응용 프로그램 배포의 경우 SQL 데이터베이스 클러스터에서 호스팅 서비스 배포와 SQL 데이터베이스 논리 서버 간에 잠재 연결의 기본 개수가 기하 급수적으로 증가할 수 있습니다(각각 단일 외부 IP 주소를 가짐). 예를 들어 인스턴스가 100개이고, 데이터베이스가 50개인 호스팅 서비스는 ADO.NET에서 기본 연결 수가 100개입니다.

MaxConnections=DatabaseCount*Instance Count*MaxConnectionPoolSize

호스팅 서비스의 네트워킹 토폴로지를 참조하십시오. 연결의 양쪽(호스팅 서비스 및 SQL 데이터베이스 논리 서버)은 Azure 부하 분산 장치 뒤에 있습니다. . 각 Azure 부하 분산 장치는 모든 IPv4 주소 두 개 사이의 연결에 대해 64k의 상한값을 적용합니다. 이러한 네트워크 토폴로지와 사용 가능한 연결의 기본 수의 조합은 대규모 응용 프로그램에서 심각한 네트워크 오류를 초래합니다.

  • 대규모 응용 프로그램을 여러 호스팅 서비스에 나누어 배포하십시오.

  • 동일한 구독에 여러 논리 서버를 배포할 뿐만 아니라 데이터베이스를 여러 구독에 나누어 배포하여 고유한 IP 주소를 더 많이 획득하십시오.

  • 다중 계층 응용 프로그램을 구현하여 대상 응용 프로그램 인스턴스에 대한 아웃 바운드 작업의 선호도를 설정하십시오(호스팅 서비스에 대한 이전 섹션 참조).

  • 연결 풀은 고유한 연결 문자열별로 유지 관리되고 각각의 고유한 데이터베이스 서버, 데이터베이스 및 로그인 조합과 일치한다는 사실을 기억하십시오. SQL 클라이언트 연결 풀링을 사용하여 SQL 연결 풀의 최대 크기를 명시적으로 제한하십시오. SQL 클라이언트 라이브러리는 필요에 따라 연결을 다시 사용합니다. 작은 연결 풀을 사용할 경우 응용 프로그램이 연결할 수 있을 때까지 기다리는 시간이 늘어날 수 있습니다.

다음 목록에는 필요한 활성 연결 수를 줄이기 위한 권장 사항이 나와 있습니다.

분산된 데이터 모델로 전환하려면 데이터베이스 스키마의 디자인을 변경하고 특정 쿼리 유형을 변경해야 할 수 있습니다. 여러 데이터베이스에 분산된 트랜잭션을 사용해야 하는 응용 프로그램에는 잠재적으로 잘못된 데이터 모델 또는 구현이 있을 수 있습니다(예: 전역 일관성 적용 시도). 이러한 디자인은 리팩터링해야 합니다.

가용성 및 확장성 제약 조건으로 인해 응용 프로그램의 중요한 측면에는 중앙 시퀀스 생성 기능을 사용하지 말아야 합니다. 대부분의 응용 프로그램은 필요에 따라 시퀀스를 증분시키는 중앙 추적 메커니즘을 사용하여 전역적으로 고유한 식별자를 제공합니다. 이 아키텍처는 시스템의 모든 구성 요소가 상호 작용해야 하는 전역 경합 지점 및 병목 현상을 만듭니다. 이러한 병목 현상은 특히 잠재적으로 연결이 끊긴 모바일 응용 프로그램에 문제가 됩니다.

대신에 응용 프로그램은 분산 시스템에서 GUID와 같은 전역적으로 고유한 식별자를 생성할 수 있는 기능을 활용해야 합니다. 기본적으로 GUID는 순차적이지 않으므로 큰 테이블에서 CLUSTERED INDEX로 사용될 경우 조각화를 유발할 수 있습니다. 대규모 데이터 모델에서 GUID의 조각화 효과를 줄이려면 데이터베이스를 분할하여 개별 조각을 상대적으로 작게 유지하십시오. 이렇게 하면 SQL 데이터베이스가 복제 장애 조치 시 데이터베이스 조각 모음을 자동으로 수행할 수 있습니다.

클라이언트 응용 프로그램 코드는 분산된 데이터 모델 제공의 여러 측면을 고려해야 합니다.

  • 파티션 키. 파티션 키는 모든 데이터 클래스 또는 모델에 포함되어 있어야 하며 파티션 키 검색을 허용하는 특성으로 데코레이팅되어 있을 수 있습니다.

  • 원격 분석. 데이터 액세스 계층은 대상, 파티션, 컨텍스트, 대기 시간 및 오류 코드 또는 재시도를 비롯한 모든 SQL 호출에 대한 정보를 자동으로 기록해야 합니다.

  • 분산 쿼리. 분할된 데이터베이스 간 쿼리를 수행하는 경우 라우팅, 파티션 선택 및 부분 성공 개념(일부 개별 분할된 데이터베이스는 데이터를 반환했지만 다른 데이터베이스는 그렇지 못한 경우)을 비롯한 몇 가지 새로운 문제가 발생합니다. 데이터 액세스 계층은 비동기(병렬) 분산 수집 방식으로 분산 쿼리를 수행하여 복합 결과를 반환하기 위한 대리자를 제공해야 합니다. 분산 쿼리는 또한 기본 리소스 제한도 고려해야 합니다.

    • 최대 병렬 처리 수준(과도한 스레드 및 연결 압력 방지)

    • 최대 쿼리 시간(장기 실행 쿼리 또는 속도가 느린 분할된 데이터베이스에서 전반적인 대기 시간 감소).

또한 지속적인 관리 작업을 수행해야 합니다.

  • 참조 테이블. 전역적으로 일관적인 쿼리 공간이 없을 경우 쿼리에서 조인의 참조 데이터를 각 개별 분할된 데이터베이스에 복사해야 합니다. 데이터를 유지 관리하고 개별 분할된 데이터베이스의 참조 테이블에 복제하는 것은 적당히 일관적인 로컬 참조 데이터를 제공하는 데 필요합니다.

  • 파티션 균형 조정. 개별 파티션은 너무 많은 리소스를 소비하고 검사점이 되거나 충분하지 않은 활용도를 제공하고 리소스를 낭비할 경우 균형이 흐트러질 수 있습니다. 이러한 경우 파티션의 균형을 조정하여 리소스를 다시 할당해야 합니다. 균형 조정 메커니즘은 분할 전략 및 구현에 따라 크게 달라집니다. 대부분의 시나리오에서는 일반적으로 다음과 같이 균형 조정이 이루어집니다.

    • 분할/병합 메커니즘(범위 기반 파티션의 경우) 또는 엔터티 수준의 복사 및 다시 매핑(조회 기반 파티션의 경우)을 통해 분할된 데이터베이스에 있는 데이터를 하나 이상의 새로운 분할된 데이터베이스로 복사.

    • 분할된 데이터베이스 맵을 새로운 분할된 데이터베이스를 가리키도록 업데이트한 다음 전환 시 기존의 분할된 데이터베이스에 기록된 데이터 보상.

  • 데이터 잘라내기. 응용 프로그램이 커지고 데이터를 수집함에 따라 사용하지 않는 오래된 데이터를 정기적으로 잘라내어 주 시스템의 가용 헤드룸 및 용량을 높이는 것이 좋습니다. 잘라낸(삭제한) 데이터는 SQL 데이터베이스에서 동기적으로 삭제되지 않지만 백그라운드 프로세스에 의해 삭제 및 정리된 것으로 플래그가 지정됩니다. 데이터에 삭제되었다는 플래그를 지정하는 일반적인 방법은 특정 행을 활성, 비활성 상태로 표시하거나 삭제된 것으로 플래그를 지정할 수 있는 플래그 열입니다. 이렇게 하면 사용자가 데이터가 아직 필요하다고 알린 경우 일정 기간 동안 데이터 쿼리를 차단하여 데이터를 프로덕션으로 간편하게 다시 이동할 수 있습니다.

    데이터 삭제는 효율적인 쿼리 작업을 위해 인덱스 다시 작성이 필요할 수 있는 조각화를 트리거할 수도 있습니다. 오래된 데이터는 다음과 같은 위치에 보관할 수 있습니다.

    • 온라인 저장소(보조 SQL 데이터베이스). 이렇게 하면 주 시스템의 헤드룸이 증가하지만 비용이 감소되지는 않습니다.

    • BLOB 저장소의 bcp 또는 bacpac 파일과 같은 오프라인 저장소. 이렇게 하면 주 시스템의 헤드룸이 증가하고 비용이 감소합니다.

    • 비트 보관함. 데이터를 주 시스템에서 영구적으로 삭제하도록 선택하여 헤드룸을 늘릴 수 있습니다.

SQL 데이터베이스에서 흔히 일어나는 몇 가지 일 때문에 복제본 장애 조치(failover)와 같은 일시적인 연결 오류가 트리거될 수 있습니다. 응용 프로그램은 적절한 코드를 구현하여 일시적인 오류를 처리하고 리소스 소진 및 제한에 올바르게 대처해야 합니다.

  • 재시도를 통해 일시적인 연결 오류 처리. 데이터 액세스 코드는 정책 기반의 재시도 메커니즘을 사용하여 일시적인 연결 오류를 보상해야 합니다. 재시도 메커니즘은 일시적인 연결 오류를 탐지하고, 대상 SQL 데이터베이스에 다시 연결하고, 명령을 다시 실행해야 합니다.

  • 재시도 및 백오프 논리로 제한 처리. 데이터 액세스 코드는 정책 기반 재시도 및 백오프 메커니즘을 활용하여 제한 상태를 처리해야 합니다. 재시도 메커니즘은 제한 및 점진적인 백오프 시도를 탐지하여 명령을 다시 실행해야 합니다(제한 상태를 유지할 수 있는 호위(convoy) 효과 방지).

    • 데이터 액세스 코드는 또한 BLOB 저장소와 같은 대체 데이터 저장소로 백오프하는 기능을 구현해야 합니다. 이러한 대체 저장소는 활동, 데이터 및 상태를 캡처하여 장기적인 제한 또는 가용성 이벤트 발생 시 데이터 손실을 방지합니다.

.NET 응용 프로그램은 CloudFx(Cloud Application Framework) 또는 Enterprise Library Transient Fault Handler와 같이 SQL 데이터베이스를 인식하는 재시도 및 백오프 논리 프레임워크를 사용할 수 있습니다. 이러한 프레임워크는 SqlConnection 및 SqlCommand와 같은 일반적인 데이터 액세스 클래스를 위한 래퍼와 직접 호출할 수 있는 정책을 제공합니다.

var retryPolicy = RetryPolicy.Create<SqlAzureTransientErrorDetectionStrategy>(
    retryCount: 3, 
    initialInterval: TimeSpan.FromSeconds(5),
    increment: TimeSpan.FromSeconds(2));
                
using (var conn = new ReliableSqlConnection(connStr))
{
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {

    }
    conn.Close();
}

위의 코드 조각은 SQL 데이터베이스에 대한 작업을 수행할 때 CloudFx ReliableSqlConnection 클래스를 사용하여 일시적인 연결 오류를 처리하는 방법을 보여 줍니다.

잠재적으로 복잡한 오류 모드가 있는 SQL 데이터베이스와 같은 서비스에 API 호출을 기록할 때는 특별한 주의가 필요합니다. 컨텍스트 및 성능 정보의 핵심 부분을 파악하십시오. 예를 들어 모든 SQL 데이터베이스 세션에는 지원 문의 시 근본적인 문제를 바로 격리하는 데 도움이 되는 세션 식별자가 있습니다. 모든 호출, 명령 및 쿼리를 SQL 데이터베이스 로그에 기록하는 것이 좋습니다.

  • 서버데이터베이스 이름. 데이터베이스가 수백 개 있는 경우 문제를 추적하고 기록하는 데 있어서 대상 서버가 매우 중요합니다.

  • 필요에 따라 SQL 저장 프로시저 또는 명령 텍스트. 중요한 정보를 로그 파일에 유출하지 않도록 주의하십시오. 일반적으로 명령 텍스트는 기록하지 마십시오.

  • 호출의 종단 간 대기 시간. 스톱워치 또는 다른 간단한 타이머를 사용하여 타이밍 위임자에 호출을 래핑하십시오.

  • 호출의 결과 코드(성공 또는 실패) 및 재시도 횟수와 오류 원인(연결 중단, 제한 등).

  • CONTEXT_INFO() 속성을 통해 액세스할 수 있는 연결 세션 ID(또는 ReliableSqlConnection을 사용 중인 경우 SessionTracingId 속성). 그러나 이 명령은 서버에 대한 또 다른 라운드 트립을 트리거하므로 모든 클라이언트 호출에서 CONTEXT_INFO()의 세션 ID 속성을 검색하지 마십시오.

SQL 데이터베이스를 보다 효율적으로 사용하려면 가능한 경우 SQL 데이터베이스에 대한 쿼리 및 데이터 삽입을 일괄 처리하고 비동기적으로 실행해야 합니다. 이렇게 하면 응용 프로그램 효율성이 향상될 뿐만 아니라 SQL 데이터베이스의 전반적인 시스템 로드가 감소합니다(처리량 증가).

  • 삽입 일괄 처리. 새로운 사용자 등록과 같은 연속 데이터 삽입 작업의 경우 데이터를 일괄 처리하고 분할된 대상 데이터베이스에 맞게 조정해야 합니다. 이러한 일괄 처리는 대상 일괄 처리 크기 또는 기간과 같은 트리거에 따라 SQL 데이터베이스에 정기적으로(비동기적으로) 기록되어야 합니다. 배치 크기가 100개 행 미만인 경우 일반적으로 대량 복사 작업보다 테이블 반환 함수가 더 효율적입니다.

  • 수다스러운 인터페이스 방지. 데이터베이스가 쿼리 또는 일련의 작업을 수행하는 데 필요한 라운드 트립 수를 줄이십시오. 수다스러운 인터페이스는 오버헤드 수준이 높아 시스템의 로드가 증가하고 처리량 및 효율성이 감소합니다. 일반적으로 라운드 트립을 줄이는 저장 프로시저를 사용하여 관련 작업을 병합해 보십시오.

비즈니스 연속성에 대한 전반적인 접근 방식의 일부로 SQL 데이터베이스에 저장된 데이터를 정기적으로 BLOB 저장소로 내보내야 합니다. BLOB 저장소는 기본적으로 가용성 및 지역 간 복제를 지원합니다.

정기적으로 데이터베이스를 BLOB 저장소로 내보내는 예약된 작업을 구현하십시오. 전용 저장소 계정을 사용하십시오. 이 작업은 온-프레미스 데스크톱 또는 서버가 아니라 대상 데이터베이스와 동일한 데이터 센터에서 실행되어야 합니다.

최종 사용자 환경에 미치는 영향을 최소화하기 위해 내보내기 작업을 작업이 적은 시간으로 예약하십시오. 여러 데이터베이스를 내보낼 때는 병렬 내보내기의 수준을 제한하여 시스템 영향을 줄이십시오.

SQL 데이터베이스의 상태, 성능 및 헤드룸에 대한 고급 정보는 서비스 제공 전체에서 매우 중요한 구성 요소입니다. SQL 데이터베이스는 동적 관리 뷰를 통해 필요한 원시 정보를 제공하지만 현재 주요 메트릭을 캡처, 분석 및 보고하기 위한 턴키 인프라는 없습니다. SQL 데이터베이스에 이러한 기능을 제공하려면 다음과 같은 방법을 고려해 보십시오.

  • 시스템 로드, 사용된 리소스(작업자 스레드, 저장소 공간) 및 데이터와 관련된 주요 성능 데이터를 수집하여 공용 리포지토리에 저장하는 정기적인 작업 구현. 예를 들어 Azure 진단에 사용된 테이블을 고려해 보십시오. 이 작업은 응용 프로그램에 속하는 모든 데이터베이스의 데이터를 수집해야 합니다. 이러한 수집은 일반적으로 수평 확장 방식으로 수행됩니다(여러 데이터베이스에서 동시에 데이터 수집).

  • 이 정보를 집계하여 배포된 데이터베이스의 상태 및 용량에 대한 주요 성능 지표를 구축하는 정기적인 작업 구현.

Azure 진단은 응용 프로그램 및 인스턴스 수준의 원격 분석 수집을 위한 기준을 제공합니다. 그러나 Azure에서 실행되는 대규모 응용 프로그램에 대한 고급 정보를 제공하려면 데이터 흐름을 신중하게 구성하고 관리해야 합니다. 풍부한 Windows 진단 유틸리티를 활용할 수 있는 중앙 집중식 수직 확장 응용 프로그램과 달리 수평 확장 분산 시스템의 진단은 시스템이 가동되기 전에 구현해야 합니다. 나중에 생각해서는 안 됩니다.

오류 처리, 컨텍스트 추적 및 원격 분석 캡처는 오류 이벤트, 근본 원인 및 해결책을 이해하는 데 매우 중요합니다.

  • 라이브 사이트 데이터 및 원격 분석을 동일한 저장소 계정에 게시하지 마십시오. 진단 전용 저장소 계정을 사용하십시오.

  • 대규모 작업(고용량, 긴 대기 시간, 세부적인 데이터) 및 수다스러운 작업(저용량, 짧은 대기 시간, 높은 가치의 데이터)에 대해 별도의 채널을 만드십시오.

    • 수다스러운 정보에는 성능 카운터 및 추적과 같은 표준 Azure 진단 원본을 사용하십시오.

    • Enterprise Application Framework Library, log4net 또는 NLog와 같은 일반적인 로깅 라이브러리를 사용하여 로그 파일에 대한 대량 로깅을 구현하십시오. 진단 모니터 구성의 사용자 지정 데이터 원본을 사용하여 이러한 정보를 정기적으로 BLOB 저장소에 복사하십시오.

  • 모든 API 호출을 컨텍스트, 대상, 방법, 시간 정보(대기 시간) 및 결과(성공/실패/재시도)와 함께 외부 서비스에 기록하십시오. 대규모 로깅 채널을 사용하여 진단 시스템에 원격 분석 정보가 과도하게 많아지지 않도록 하십시오.

  • 테이블 저장소에 기록된 데이터(성능 카운터, 이벤트 로그, 추적 이벤트)는 60초 간격으로 임시 파티션에 기록됩니다. 너무 많은 데이터(너무 많은 지점의 원본, 너무 낮은 수집 간격)를 기록하려고 하면 이 파티션이 가득 찰 수 있습니다. 오류 스파이크로 인해 테이블 저장소에 대량의 삽입 시도가 트리거되지 않도록 하십시오. 이 경우 제한 이벤트가 트리거될 수 있습니다.

    • 주요 성능 카운터, 중요/오류 이벤트 또는 추적 기록을 비롯한 원본에서 수집할 높은 가치의 데이터를 선택하십시오.

    • 적절한 수집 간격(5분 – 15분)을 선택하여 전송 및 분석되어야 하는 데이터의 양을 줄이십시오.

  • 런타임에 인스턴스를 강제로 재설정하지 않고 로깅 구성을 수정할 수 있는지 확인하십시오. 또한 데이터베이스, 캐시 또는 다른 서비스와 같은 시스템의 특정 측면에 대해 로깅을 활성화할 수 있을 만큼 구성이 충분히 세부적인지 확인하십시오.

Azure 진단은 SQL 데이터베이스 또는 분산된 캐시 같은 종속 서비스에 대한 데이터 컬렉션을 제공하지 않습니다. 응용 프로그램 및 성능 특징에 대한 포괄적인 보기를 제공하려면 종속 서비스의 데이터를 수집하는 인프라를 추가하십시오.

  • 종속 서비스의 주요 성능 및 활용도 데이터를 수집하고 WAD 리포지토리에 성능 카운터 기록으로 게시하십시오.

    • Azure 저장소 - Azure 저장소 분석 사용

    • SQL 데이터베이스 - 동적 관리 뷰 사용

    • 분산된 캐시 - 성능 카운터 또는 상태 모니터링 API 사용

  • 원시 원격 분석 데이터를 정기적으로 분석하여 집계 및 롤업을 만드십시오(예약된 작업으로 실행).

표시:
© 2014 Microsoft