ASP.NET 캐시

캐시는 서버가 별도의 저장소에 저장해둔 데이터를 클라이언트에게 보내줌으로써 서버의 부하를 줄이고 퍼포먼스를 높이는 기술이다.

ASP.NET은 output 캐시와 어플리케이션 캐시 방식을 제공한다.
 
1) Output 캐시: 클라이언트 request에 의해 생성된 결과 페이지를 저장해두고, 동일한 request가 들어왔을 때 저장되어 있던 결과 페이지를 전송한다.

2) 어플리케이션 캐시: 결과 페이지 생성에 필요한 객체들을 메모리에 올려놓고, request가 들어오면 그에 대한 결과 페이지를 생성하여 클라이언트에 전송한다.

Output 캐시

Duration

.aspx에서 @OutputCache 지시자를 기술함으로써 output 캐시를 사용할 수 있으며 반드시 만료 시간을 지정해주어야 한다. 캐시 유지 시간이 만료된 상태에서 이 페이지에 대한 request가 들어오면 결과 페이지가 다시 캐시되고, 지정된 시간 동안 캐시가 사용된다.
 
아래는 60초 동안 페이지를 캐시시키는 예제이다.
<%@ OutputCache Duration="60" %>
 
.cs와 같은 코드상에서 output 캐시를 지정할 수도 있다.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));

Location

Location 속성을 사용하여 request에 대한 결과 페이지를 어디에 캐시해둘 것인지 지정할 수 있다. 디폴트 값은 "Any"이며 클라이언트, 서버, 프록시 서버 등 캐시가 가능한 모든 곳에 캐시를 허용한다.
// .aspx
<%@ OutputCache Duration="60" Location="Any" %>

// .cs

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
 
다음은 웹 서버에 60초 동안 캐시를 유지시키는 예제이다.
// .aspx
<%@ OutputCache Duration="60" Location="Server" %>

// .cs

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Server);
 
클라이언트에 60초 동안 캐시를 유지시키는 예제는 다음과 같다.
// .aspx
<%@ OutputCache Duration="60" Location="Client" %>

// .cs

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Private);
 
프록시 서버에 60초 동안 캐시를 유지시키는 코드는 아래와 같다.
// .aspx
<%@ OutputCache Duration="60" Location="Downstream" %>

// .cs

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public
);
Response.Cache.SetNoServerCaching();
 
아래는 output 캐시를 사용하지 않는 예제이다.
// .aspx
<%@ OutputCache Duration="0" Location="None" %>

// .cs

Response.Cache.SetCacheability(HttpCacheability.NoCache);

VaryByParam

GET 혹은 POST 방식으로 요청되는 결과 페이지에 있어서, 폼의 매개 변수 값에 따라 서로 다른 결과 페이지를 캐시시킬 수 있다.
 
예를 들어 다음과 같은 request가 있다고 하자.
http://localhost/test/test.aspx?name=aaa&age=20  ¡| 1)
http://localhost/test/test.aspx?name=aaa&age=10  ¡| 2
)
http://localhost/test/test.aspx?name=bbb&age=10  ¡| 3
)
http://localhost/test/test.aspx?name=bbb&age=20  ¡| 4)
 
서버 페이지 캐시에서 아래와 같이 "name" 매개 변수에 대해 VaryByParam 속성을 사용한다면,
<%@ OutputCache Duration="60" VaryByParam="name" %>
1) 과 2), 그리고 3)과 4)는 "name" 매개 변수에 대해 동일한 값을 전달하기 때문에 각각 같은 결과 페이지를 보게 된다.
 
"name", "age" 매개 변수에 대해 VaryByParam 속성을 사용하면 1) ~ 4) 모두 서로 다른 결과 페이지를 보게 되며, 매개 변수의 구분자에는 ";" 문자를 사용한다.
<%@ OutputCache Duration="60" VaryByParam="name;age" %>
 
아래는 모든 매개 변수에 대해 VaryByParam 속성을 사용하는 예제이다.
<%@ OutputCache Duration="60" VaryByParam="*" %>

VaryByHeader

request에 포함된 HTTP 헤더 속성 값에 따라 별도의 캐시를 사용할 수 있다.
"Accept-Language" 헤더 속성 값에 따라 서로 다른 캐시 페이지를 사용하는 예제는 다음과 같다.
<%@ OutputCache Duration="60" VaryByHeader="Accept-Language" %>

VaryByCustom

웹 브라우저 또는 사용자 정의 속성 값에 따라 별도의 캐시를 사용할 수 있다.
다음은 웹 브라우저의 이름과 major 버전에 따라 서로 다른 캐시 페이지를 저장하는 예제이다.
<%@ OutputCache Duration="60" VaryByCustom="browser" %>
 
다음은 "FrameEnabled"라는 사용자 정의 속성 값에 따라 별도의 캐시 페이지를 저장하는 예제이다. .aspx에서 VaryByCustom 캐시 속성 값을 "FrameEnabled"로 지정하고, Global.asax.cs에서 GetVaryByCustomString() 메서드를 오버라이딩하여 이 속성에 해당하는 실제 값에 따라 별도의 캐시 페이지로 저장하도록 코딩한다.
// .aspx
<%@ OutputCache Duration="60" VaryByCustom="FrameEnabled" %>

// Global.asax.cs

public override string GetVaryByCustomString(HttpContext context, string arg)
{
   if (arg == "FrameEnabled")
      return "FrameEnabled=" + context.Request.Browser.Frames;

   return "";
}

어플리케이션 캐시

코드에서 Cache 클래스를 써서 특정 데이터를 가지는 객체를 서버 메모리상에 올려두고 사용할 수 있다.

캐시는 어플리케이션별로 만들어지며, 어플리케이션이 재시작되면 캐시도 재생성된다. request가 있을 때마다 동적으로 생성하기에 부적합한 데이터가 있을 때 어플리케이션 캐시를 사용하면 서비스의 속도와 퍼포먼스를 향상시킬 수 있다.

Cache 클래스

ASP.NET의 Cache 클래스는 다음과 같은 특징을 가진다.
1) key-value 형식의 포맷으로 간단하게 사용할 수 있다.
2) 아이템의 추가/삭제을 쉽게 할 수 있다.
3) 절대 시간 및 상대 시간의 개념으로 캐시의 만료 시기를 지정할 수 있다.
4) 서버는 "scavenging"이라고 불리는 작업을 통해 거의 사용되지 않는 캐시 데이터를 자동 삭제함으로써 메모리를 확보한다.
5) 외부 파일이나 다른 데이터에 기반한 캐시 아이템에 있어서, 데이터 원본의 내용이 바뀌면 자동으로 캐시 아이템을 무효화시키는 메커니즘을 제공한다.

캐시 아이템 추가

아래는 key-value 형식의 아이템을 캐시에 추가하는 예제이다.
Cache("name") = "dizzi";
 
scavenging, 의존 관계, 만료 시간 등을 지정하기 위해서는 Add() 또는 Insert() 메서드를 사용한다. 다음은 address.xml 파일이 변경되면 자동으로 무효화되는 의존 관계를 설정하여 아이템을 캐시에 추가하는 예제이다.
Cache.Insert("name", "dizzi", new CacheDependency(Server.MapPath("address.xml"));
 
아래는 현재로부터 2분이 지나면 캐시가 만료되도록 설정하는 예제이다.
Cache.Insert("name", "dizzi", null, DateTime.Now.AddMinutes(2), NoSlidingExpiration);
 
다음은 상대 시간을 사용하여 캐시가 만료되도록 설정하는 예제이다.
Cache.Insert("name", "dizzi", null, NoAbsoluteExpiration, TimeSpan.FromMinutes(2));

캐시 아이템 읽기

"name" 캐시 아이템의 값을 읽는 예제는 아래와 같다.
string strName = (string) Cache["name"];

캐시 아이템 삭제

"name" 아이템을 캐시에서 삭제하는 예제는 다음과 같다.
Cache.Remove("name");

캐시 아이템이 삭제되었을 때 이벤트 받기

특정 아이템이 캐시에서 삭제되었을 때 어플리케이션에서 그에 대한 이벤트를 받을 수 있는데 이 기능을 사용하기 위한 절차는 다음과 같다.
 
1) 어플리케이션에서 CacheItemRemovedCallback 형의 콜백 함수를 작성한다.
2) 캐시에 아이템을 추가할 때 콜백 함수를 지정한다.
다음은 "name" 아이템이 캐시에서 삭제되었을 때 동일 아이템을 재추가하는 예제 소스이다.

// 콜백 함수
public void RemovedCallback

(string strKey, object objValue, CacheItemRemovedReason reason)
{
   Cache("name") = "dizzi";
}
...


// CacheItemRemovedCallback 위임형의 변수를 선언하고 콜백 함수를 지정한다.

private static CacheItemRemovedCallback onRemove

           = new CacheItemRemovedCallback(this.RemovedCallback);
...

// 캐시 아이템 추가

Cache.Insert("name", "dizzi", null, DateTime.Now.AddMinutes(2),

                  NoSlidingExpiration, CacheItemPriority.High,

                  CacheItemPriorityDecay.Slow, onRemove);


자료출처 : http://blog.empas.com/dizzius/3749928

+ Recent posts