최대 부하에서 ASP.NET 성능을 향상시키는 4가지 방법

 

개요

ASP.NET은 웹 응용 프로그램 개발에 매우 ​​대중적으로 사용되고 있으며 이러한 응용 프로그램 중 상당수는 본질적으로 트래픽이 많고 수백만 명의 사용자에게 서비스를 제공합니다. 결과적으로 이러한 응용 프로그램은 비즈니스에 큰 영향을 미치므로 매우 중요합니다.

흥미롭게도 ASP.NET 응용 프로그램 아키텍처는 응용 프로그램 계층에서 확장성이 매우 뛰어납니다. 그리고 HTTP 프로토콜도 상태 비저장입니다. 이 두 가지 모두 각 HTTP 요청이 가장 적절한 웹 서버로 라우팅되는 부하 분산 웹 팜에서 ASP.NET 응용 프로그램을 실행할 수 있음을 의미합니다. 이를 통해 사용자 트래픽이 증가함에 따라 웹 팜에 더 많은 웹 서버를 쉽게 추가할 수 있습니다. 그리고 이를 통해 ASP.NET 응용 프로그램 계층을 매우 확장할 수 있습니다. 그러나 여기서 확장성이란 무엇을 의미합니까?

확장성은 본질적으로 최대 부하에서도 고성능을 제공하는 능력입니다. 따라서 ASP.NET 응용 프로그램 페이지 응답 시간이 10명의 사용자에서 매우 빠르고 100,000명의 사용자로 빠르게 유지된다면 ASP.NET 응용 프로그램은 확장 가능합니다. 그러나 사용자 수가 증가함에 따라 ASP.NET 응답 시간이 느려지면 응용 프로그램을 확장할 수 없습니다.

 

문제: 확장성 병목 현상

응용 프로그램 계층에서 매우 확장 가능한 아키텍처에도 불구하고 오늘날 ASP.NET 응용 프로그램은 주요 확장성 병목 현상에 직면해 있습니다. 이러한 병목 현상은 다음과 같은 네 가지 영역에서 발생합니다.

  1. 애플리케이션 데이터베이스
  2. ASP.NET 세션 상태 저장소
  3. ASP.NET View State
  4. 정적 출력을 위한 ASP.NET 페이지 실행

아래에서 각각에 대해 더 자세히 설명하겠습니다.

 

애플리케이션 데이터베이스

SQL Server 또는 Oracle과 같은 애플리케이션 데이터베이스는 트랜잭션 로드가 증가함에 따라 빠르게 확장성 병목 현상이 됩니다. 이것은 더 강력한 데이터베이스 서버를 구입하여 데이터베이스 계층을 확장할 수 있지만 데이터베이스 계층에 더 많은 서버를 추가하여 확장할 수 없기 때문에 발생합니다. 예를 들어, 애플리케이션 계층에서 10-20개의 서버를 보는 것은 매우 일반적이지만 데이터베이스 계층에서는 동일한 작업을 수행할 수 없습니다.

 

ASP.NET 세션 상태 저장소

또한 ASP.NET 세션 상태는 어딘가에 저장해야 합니다. 그리고 Microsoft에서 제공하는 즉시 사용 가능한 옵션은 InProc, StateServer 및 SqlServer입니다. 불행히도 세 가지 옵션 모두 중요한 성능 및 확장성 문제가 있습니다. InProc 및 StateServer는 고정 세션을 사용하고 세션이 생성된 동일한 서버에서 모든 HTTP 요청을 보내도록 합니다. 고정 세션을 피하기 위해 StateServer를 독립 실행형 서버로 구성하면 StateServer가 단일 실패 지점이 되고 그 성능도 주요 문제가 됩니다. 그리고 SqlServer는 ASP.NET 세션을 SQL Server 데이터베이스에 BLOB로 저장합니다. 그리고 이 접근 방식에는 심각한 성능 및 확장성 문제가 있습니다.

 

ASP.NET View State

ASP.NET View State HTTP 응답의 일부로 사용자의 브라우저에 전송되는 인코딩된 숨겨진 문자열(종종 100KB 크기)입니다. 브라우저는 아무 것도 하지 않고 HTTP Post-Back의 경우 웹 서버로 다시 반환합니다. 이것은 ASP.NET 페이지 응답을 늦추고 웹 서버 네트워크 카드에 더 많은 부담을 주며 많은 추가 대역폭을 소모합니다. 그리고 아시다시피 대역폭은 저렴하지 않습니다.

 

정적 출력을 위한 ASP.NET 페이지 실행

마지막으로 ASP.NET framework 페이지 출력이 이전 요청에서 변경되지 않는 경우에도 사용자 요청에 대해 ASP.NET 페이지를 실행합니다. 트랜잭션이 적은 환경에서는 괜찮을 수 있습니다. 그러나 이미 모든 리소스를 한계까지 확장하고 있는 높은 트랜잭션 환경에서 이러한 추가 실행은 비용이 많이 들고 확장성 병목 현상이 될 수 있습니다.

"모든 사슬의 힘은 가장 약한 고리만큼만 강하다"라는 속담처럼. 따라서 ASP.NET 응용 프로그램 환경의 어느 곳에서나 확장성 병목 현상이 있는 한 전체 응용 프로그램이 느려지고 중단되기까지 합니다.

그리고 아이러니하게도 이것은 최고 수준의 비즈니스 활동을 수행할 때 최대 부하에서 발생합니다. 따라서 속도 저하 또는 다운타임의 영향은 비즈니스에 훨씬 더 많은 비용을 초래합니다.

확장성 병목 현상에 직면한 ASP.NET
그림 1: 확장성 병목 현상에 직면한 ASP.NET
 

NoSQL Database 답이 아니다

NoSQL database 움직임은 관계형 데이터베이스의 확장성 문제의 결과로 시작되었습니다. NoSQL database 데이터를 여러 서버로 분할하고 애플리케이션 계층처럼 확장할 수 있습니다.

그러나, NoSQL database 관계형 데이터베이스를 포기하고 데이터를 NoSQL database. 그리고 이것은 여러 가지 이유 때문에 말보다 쉽지만 실제로는 많은 경우에 불가능합니다.

NoSQL databases는 관계형 데이터베이스와 동일한 데이터 관리 및 검색 기능을 갖고 있지 않으며 관계형 데이터베이스와 완전히 다른 방식으로 데이터를 저장하기를 원합니다. 또한 관계형 데이터베이스를 둘러싼 생태계는 대부분의 비즈니스에서 포기하기에는 너무 강력합니다.

그 결과, NoSQL databases는 구조화되지 않은 데이터를 처리할 때만 유용합니다. 그리고 대부분의 ASP.NET 응용 프로그램은 주로 구조화되고 관계형 데이터베이스에 적합한 비즈니스 데이터를 처리합니다. 결과적으로 이 데이터는 다음으로 이동할 수 없습니다. NoSQL database 용이하게.

그리고 결국 사용하시는 분들도 NoSQL database 구조화되지 않은 것으로 간주될 수 있는 전체 데이터의 작은 하위 집합에 대해 그렇게 합니다. 그리고, 그들은 사용 NoSQL database 기존 관계형 데이터베이스와 함께.

따라서 대부분의 경우 관계형 데이터베이스를 사용하면서 확장성 문제에 대한 다른 솔루션을 찾아야 합니다. 다행히도 매우 실행 가능한 솔루션이 있으며 이에 대해서는 아래에서 논의하겠습니다.

 

솔루션: 인메모리 분산 캐시

위에서 언급한 모든 문제에 대한 해결책은 다음과 같은 애플리케이션 배포에서 메모리 내 분산 캐시를 사용하는 것입니다. NCache. NCache 는 Teledyne LeCroy 오실로스코프 및 LSA-XNUMX 시리즈 임베디드 신호 분석기가 오픈 소스 분산 캐시 매우 빠르고 선형적으로 확장 가능한 .NET용입니다. 또한 배포되는 메모리 내 개체 저장소로 생각하십시오. 인메모리에 있으면 속도가 매우 빨라지고 분산되면 선형 확장이 가능합니다.

In-Memory Distributed Cache의 좋은 점은 다음과 같습니다. NCache 기존 관계형 데이터베이스 사용을 중지하도록 요청하지 않는다는 것입니다. 캐시는 모든 관계형 데이터베이스 확장성 병목 현상을 제거하므로 관계형 데이터베이스 위에 캐시를 사용할 수 있습니다.

NCache 선형 확장성 제공
그림 2 : NCache 선형 확장성 제공

인메모리 분산 캐시는 다음과 같습니다. NCache 관계형 데이터베이스보다 확장 가능합니까? 잘, NCache 캐시 서버의 클러스터를 형성하고 이러한 모든 서버의 CPU, 메모리 및 기타 리소스를 함께 풀링합니다.

그리고 NCache 캐시나 애플리케이션을 중지하지 않고 런타임에 캐시 서버를 추가할 수 있습니다. 또한 이를 통해 애플리케이션을 선형적으로 확장하고 극단적인 트랜잭션 로드를 처리할 수 있습니다. 이것은 관계형 데이터베이스로 할 수 없는 일입니다.

인메모리 분산 캐시와 같은 NCache 런타임에 캐시 클러스터(캐싱 계층)에 캐시 서버를 추가할 수 있어 선형적으로 확장됩니다. 그러나 다음과 같은 솔루션에서 어떤 유형의 성능 수치를 기대할 수 있습니까? NCache.

다음과 같습니다 NCache 성능 수치. 전체를 볼 수 있습니다 NCache 성능 벤치 마크 여기를 클릭해 문의해주세요.

성능 수치 NCache
그림 3: 성능 수치 NCache

보시다시피, 다음과 같은 메모리 내 분산 캐시 NCache 읽기 및 쓰기에 밀리초 미만의 성능을 제공하고 단순히 캐시 서버를 더 추가하여 트랜잭션 용량을 선형으로 확장할 수 있습니다.

이제 메모리 내 분산 캐시가 NCache 위에서 언급한 다양한 확장성 병목 현상을 해결합니다.

 

애플리케이션 데이터 캐싱

애플리케이션 데이터 캐싱을 사용하면 데이터베이스 병목 현상을 제거할 수 있습니다. 인메모리 분산 캐시와 같은 NCache 애플리케이션 데이터를 캐시하고 값비싼 데이터베이스 여행을 줄일 수 있습니다. 데이터베이스 트래픽의 70-90%를 메모리 내 분산 캐시로 전환할 수 있습니다. 이렇게 하면 데이터베이스에 대한 부담이 줄어들고 속도 저하 없이 더 빠르게 수행하고 더 큰 트랜잭션 로드를 처리할 수 있습니다.

Customer Load(string customerId)
{
 // Key format: Customer:PK:1000
 string key = "Customers:CustomerID:" + customerId;
 Customer cust = (Customer) _cache[key];
 if (cust == null)
 { // Item not in cache so load from db
LoadCustomerFromDb(cust);
// Add item to cache for future reference
_cache.Insert(key, cust);
 }
 return cust;
}

그림 4: 앱 데이터 캐싱에 메모리 내 분산 캐시 사용

애플리케이션 데이터 캐싱은 관계형 데이터베이스에서 얻은 모든 애플리케이션 데이터를 캐시하는 것을 의미합니다. 이것은 일반적으로 도메인 개체(엔티티라고도 함)의 형태입니다. 다음은 분산 캐시를 사용하는 방법에 대한 예입니다. NCache 애플리케이션 데이터 캐싱용.

 

ASP.NET 세션 상태 캐싱

인메모리 분산 캐시와 같은 NCache 또한 ASP.NET 세션 상태를 저장할 수 있는 좋은 장소입니다. 위에서 언급한 세 가지 옵션(InProc, StateServer 및 SqlServer)보다 훨씬 빠르고 확장성이 뛰어납니다. NCache 메모리에 있고 값이 ASP.NET 세션 상태인 "개체"인 키-값 인터페이스를 제공하기 때문에 더 빠릅니다. 그리고 분산 캐시이기 때문에 확장이 가능합니다.

그리고 NCache 또한 풍부한 캐싱 토폴로지를 통해 세션을 지능적으로 복제하므로 캐시 서버가 다운되더라도 세션 데이터 손실이 없습니다. 이 복제가 필요한 이유는 NCache 메모리 내 저장소를 제공하고 메모리가 저장소를 위반합니다.

NCache 또한 out-of-process로 저장되기 전에 필요한 ASP.NET 세션 상태 개체의 직렬화 속도를 높입니다. NCache 일반 .NET 직렬화보다 10배 빠른 Dynamic Compact 직렬화 기능을 사용하여 이를 수행합니다. 코드를 변경하지 않고도 이 기능을 사용할 수 있습니다.

당신은 연결할 수 있습니다 NCache 세션 상태 공급자 (SSP) 모듈을 아래와 같이 web.config 파일에서 일부 변경하여 ASP.NET 응용 프로그램에 추가합니다.

<system.web>
 ...
 <assemblies>
<add assembly="Alachisoft.NCache.SessionStoreProvider, Version=4.3.0.0,
 Culture=neutral, PublicKeyToken=CFF5926ED6A53769" />
 </assemblies>
 <sessionState cookieless="false" regenerateExpiredSessionId="true"
 mode="Custom" customProvider="NCacheSessionProvider"
timeout="20">
<providers>
 <add name="NCacheSessionProvider"
 type="Alachisoft.NCache.Web.SessionState.NSessionStoreProvider"
 useInProc="false" cacheName="myDistributedCache"
 enableLogs="false“ writeExceptionsToEventLog="false” />
</providers>
 </sessionState>
 ...
</system.web>

그림 5: 플러그인 NCache Web.Config에서 ASP.NET 세션 상태 공급자(SSP)로

 

ASP.NET View State 캐싱

나는 이미 방법을 설명했습니다 ASP.NET View State 웹 서버가 사용자의 브라우저로 보낸 인코딩된 문자열이며 HTTP 포스트백의 경우 웹 서버로 다시 반환합니다. 그러나 다음과 같은 InMemory 분산 캐시의 도움으로 NCache, 이것을 캐시할 수 있습니다 ASP.NET View State 서버에서 대신 작은 고유 ID만 보냅니다.

NCache 구현했습니다 ASP.NET View State 캐싱 모듈 사용자 지정 ASP.NET 페이지 어댑터 및 ASP.NET PageStatePersister를 통해. 이 방법, NCache HTTP 요청과 응답을 모두 가로챕니다. 응답시간에, NCache 인코딩된 문자열의 "값" 부분을 제거하고 캐시하고 대신 이 "값"에 고유 식별자(캐시 키)를 넣습니다.

그런 다음 다음 HTTP 요청이 오면 다시 가로채서 고유 식별자를 이전에 캐시에 넣은 실제 인코딩된 문자열로 바꿉니다. 이렇게 하면 ASP.NET 페이지는 다른 점을 인식하지 못하고 이전과 같이 보기 상태가 포함된 인코딩된 문자열을 사용합니다.

아래 예는 다음을 보여줍니다. ASP.NET View State 캐싱이 없는 인코딩된 문자열과 캐싱이 통합될 때 발생하는 일.

//ASP.NET View State without Caching
<input id="__VIEWSTATE"
 	type="hidden"
 	name="__VIEWSTATE"
 	value="/wEPDwUJNzg0MDMxMDA1D2QWAmYPZBYCZg9kFgQCAQ9kFgICBQ9kFgJmD2QWAgIBD
		xYCHhNQcm2aW91c0NvbnRyb2xNb2RlCymIAU1pY3Jvc29mdC5TaGFyZVBvaW50Lld
		lYkNvbnRyb2xzLlNQQ29udHJbE1vZDA1XzRlMjJfODM3Y19kOWQ1ZTc2YmY1M2IPD
		xYCHhNQcm2aW91c0NvbnRyb2xNb2RlCymIAU1pY3Jvc29mdC5TaGFyZVBvaW50Lld
		lYkNvbnRyb2xzLlNQQ29udHJbE1vZDA1XzRlMjJfODM3Y19kOWQ1ZTc2YmY1M2IPD
		... ==" />
			
//ASP.NET View State with Caching
<input id="__VIEWSTATE"
	type="hidden"
	name="__VIEWSTATE"
	value="vs:cf8c8d3927ad4c1a84da7f891bb89185" />

그림 6 : ASP.NET View State 캐싱이 있거나 없는 인코딩된 문자열

 

정적 페이지 출력을 위한 ASP.NET 출력 캐시

ASP.NET은 페이지 출력이 변경되지 않는 경우에도 과도한 페이지 실행 문제를 해결하기 위해 ASP.NET 출력 캐시 프레임워크를 제공합니다. 이 프레임워크를 사용하면 전체 페이지 또는 페이지의 일부의 출력을 캐시할 수 있으므로 다음에 이 페이지가 호출될 때 실행되지 않고 캐시된 출력이 표시됩니다. 이미 캐시된 출력을 표시하는 것이 전체 페이지를 다시 실행하는 것보다 훨씬 빠릅니다.

<caching>
   <outputCache defaultProvider ="NOutputCacheProvider">
     <providers>
       <add name="NOutputCacheProvider"
         type="Alachisoft.NCache.OutputCacheProvider.NOutputCacheProvider,
               Alachisoft.NCache.OutputCacheProvider, Version=x.x.x.x,
               Culture=neutral, PublicKeyToken=1448e8d1123e9096"
				  
               cacheName="myDistributedCache" exceptionsEnabled="false"
               writeExceptionsToEventLog="false" enableLogs="true” />"
     </providers>
   </outputCache>
</caching>

그림 7: ASP.NET 출력 캐시 공급자 설정 NCache Web.Config에서

NCache .NET 4.0 이상 버전용 ASP.NET 출력 캐시 공급자를 구현했습니다. 이렇게 하면 플러그인할 수 있습니다. NCache 프로그래밍 노력 없이 원활하게. 의 경우 NCache, 이 공급자는 여러 서버에 걸쳐 있는 메모리 내 분산 캐시용입니다. 따라서 ASP.NET 응용 프로그램이 부하 분산된 웹 팜에서 실행 중인 경우 서버 1에서 캐시된 페이지 출력을 웹 팜의 다른 모든 서버에서 즉시 사용할 수 있습니다. 아래는 연결하는 방법입니다 NCache ASP.NET 출력 캐시 공급자로.

 

분산 캐시 아키텍처

트래픽이 많은 ASP.NET 응용 프로그램은 특히 피크 시간에 다운될 여유가 없습니다. 이러한 유형의 애플리케이션에는 좋은 인메모리 분산 캐시가 다음과 같은 세 가지 중요한 아키텍처 목표를 가지고 있습니다. NCache 제공합니다. 그들은:

  1. 고 가용성
  2. 선형 확장성
  3. 데이터 복제 및 안정성

아래에서 각 영역에 대해 설명하겠습니다.

 

고 가용성

가장 중요한 건축 목표 중 하나는 NCache 고가용성과 캐시 탄력성을 달성하는 것입니다. 그리고 다음과 같은 아키텍처 기능을 통해 이를 수행합니다.

  1. 자가 치유 PXNUMXP 캐시 클러스터: NCache TCP/IP를 통해 캐시 서버 클러스터를 구축합니다. 이 클러스터에는 피어 - 투 - 피어 마스터/슬레이브 노드가 없고 다수결 클러스터링이 없음을 의미하는 아키텍처입니다. 대신, 각 노드는 동등한 피어입니다. 이를 통해 NCache 노드가 다운될 수 있고 클러스터가 자동으로 조정되고 계속 실행되고 애플리케이션에 중단이 없는 상황을 처리하기 위해.
  2. 동적 구성: 즉, 구성 파일에 하드코딩할 필요가 없습니다. 이 때문입니다 NCache 런타임에 캐시 클라이언트(응용 프로그램을 의미함)에 많은 구성 정보를 전파합니다. 따라서 런타임에 캐시 서버를 추가하면 클러스터 구성원이 자동으로 업데이트되고 클러스터는 이 변경 사항을 모든 캐시 클라이언트에 알립니다. 동일한 방식으로 처리되는 다른 구성 변경 사항이 많이 있습니다.
  3. 연결 장애 조치 지원: 이것은 캐시 서버가 다운될 때 캐시 클러스터와 캐시 클라이언트가 중단 없이 계속 작동할 수 있는 기능입니다. 캐시 클러스터의 경우 이러한 상황을 해결하는 자체 복구 품질에 대해 이미 논의했습니다. 캐시 클라이언트의 경우 이는 캐시 클라이언트가 클러스터의 다른 캐시 서버와 상호 작용하여 계속 작동함을 의미합니다.
 

선형 확장성을 통한 데이터 복제

인메모리 분산 캐시 이후 NCache 메모리를 저장소로 사용하므로 안정성을 보장하기 위해 데이터 복제를 제공해야 합니다. 그러나 동시에 선형 확장성을 타협할 수는 없습니다. 이것이 다음과 같은 분산 캐시를 사용하는 가장 중요한 이유이기 때문입니다. NCache.

다음은 몇 가지 있습니다 NCache 캐싱 토폴로지 이 두 가지 목표를 모두 달성하는 데 도움이 됩니다.

  1. 파티션된 캐시: NCache 캐시 서버의 수에 따라 캐시를 분할하고 각 캐시 서버에 하나의 파티션을 할당합니다. 또한 런타임에 캐시 서버를 추가하거나 제거할 때 파티션 수를 조정합니다. 더 많은 서버를 추가할 때 이 캐싱 토폴로지가 전체 저장소 크기와 CPU 처리 능력을 증가시키기 때문에 분할은 선형 확장성을 보장하는 주요 방법입니다.
  2. 분할된 복제본 캐시: 파티션을 나누는 것 외에도 NCache 또한 각 파티션에 대한 복제본을 제공합니다. 이러한 복제본은 파티션 자체와 다른 캐시 서버에 상주하여 캐시 서버가 파티션과 함께 다운되는 경우 복제본을 즉시 사용할 수 있도록 합니다. 이러한 방식으로 데이터 신뢰성이 제공됩니다. 각 파티션을 다른 캐시 서버에 한 번만 복제함으로써, NCache 선형 확장성을 손상시키지 않으면서 데이터 신뢰성을 달성합니다.
  3. 클라이언트 캐시(캐시 근처): 또 다른 매우 중요한 능력 NCache 클라이언트 캐시입니다. 이것은 캐시 클라이언트 시스템(즉, 웹 또는 앱 서버)에 있는 로컬 캐시이며 InProc일 수도 있습니다(즉, 애플리케이션 프로세스 내에 있음을 의미). 이것은 본질적으로 캐시 위의 캐시이며 확장성 증가와 함께 극도의 성능 향상을 제공합니다. NCache 캐싱 계층에 대한 트래픽도 떨어지기 때문입니다.
파티션-복제본 캐싱 토폴로지 NCache
그림 8: 파티션-복제본 캐싱 토폴로지 NCache

보시다시피 Partitioned-Replica Cache는 각 캐시 서버에 하나의 파티션과 하나의 복제본을 넣습니다. 또한 안정성을 위해 복제본이 항상 다른 캐시 서버에 있도록 합니다.

 

결론

저는 오늘날 ASP.NET 응용 프로그램이 직면한 가장 일반적인 성능 및 확장성 병목 현상을 강조하고 다음과 같은 In-Memory Distributed Cache를 사용하여 이를 극복하는 방법을 보여주려고 노력했습니다. NCache. NCache .NET 및 Java 애플리케이션을 위한 오픈 소스 분산 캐시입니다. 따라서 제한 없이 사용할 수 있습니다. 에 대해 자세히 알아볼 수 있습니다. NCache 다음 링크에서

다음에 무엇을할지?

© 저작권 Alachisoft 2002 - . 판권 소유. NCache 는 Diyatech Corp.의 등록상표입니다.