캐시 기능을 사용하는 목적은 주로 어플리케이션 실행 시간 동안 또는 주어진 시간 동안에 원하는 데이터를 로컬 컴퓨터에 보관하여 둠으로써, 추후 동일한 데이터가 필요할 시 캐시에서 바로 사용할 수 있도록 하여 데이터 조회에 필요한 성능을 아끼려는 것입니다.
또한 오프라인 기능 구현시에 이 캐싱 기능은 필수적입니다. 왜냐면, 오프라인 시에 어플리케이션 기능을 그대로 제공하기 위해서는 필요한 데이터를 모두 서버에 의존적으로 가져오거나 처리(수정/추가/삭제) 할 수 없고, 이를 위해서는 반드시 로컬 캐시에 작업을 위한 데이터와 작업된 데이터를 저장해 두어야 합니다.
가령 우리가 인사 어플리케이션을 개발한다고 가정하면, 사용자 등록시에 사용하는 많은 양의 부서코드 데이터가 존재하여 이 부서코드 중 하나를 선택한 후 사용자의 부서를 결정해야 한다고 합시다. 이 부서코드 데이터는 사용자 수정 시에도 사용되어 지고 또한 다른 인사 관련 작업 수행시에도 사용되어 집니다.
이 경우에, 부서코드 데이터를 로컬 캐시에 저장해 둔다면, 한번 데이터 조회 후 어플리케이션 실행 동안 또는 정해진 기간 동안 서버로부터의 추가적인 조회작업 없이 어플리케이션에서 바로 사용가능하게 됩니다. 물론, 캐시에서 사용하는 동안 이 부서코드 데이터에 대한 변경(추가/수정/삭제)이 일어나지 않는다는 가정하에 가능합니다.
이런식으로 캐시를 통해 작업하는 동안 이러한 캐시된 데이터의 변경이 일어날 수 있으므로 만료정책을 사용하여 캐시 내 데이터가 언제까지 유효한지를 지정하여 사용하는게 일반적입니다.
만일 메모리 상에 존재하는 캐시(in-memory)를 사용한다면, 이 캐시는(이 캐시 내의 데이터는) 해당 어플리케이션이 실행하는(메모리 상에 존재하는) 동안만, 유효한 것이므로 어플리케이션 종료와 동시에 소멸 됩니다.
Enterprise Library Caching Application Block(CAB)은 어플리케이션 내에 쉽게 로컬 캐시기능을 사용할 수 있게 해줍니다.
CAB는 in-memory 캐시와 영구적인 저장소로의 캐싱을 모두 지원하고 있습니다. 영구적인 저장소로는 Isolated Storage, Database를 지원합니다.
CAB를 사용하여 캐시에 데이터를 추가/삭제/조회하는 기능을 구현할 수 있으며 여러 다른 Application Blocks에서 캐싱 기능을 위해 CAB를 사용하고 있습니다.
CAB 사용을 위해서 구성을 생성합니다.
Enterprise Library Configuration을 사용해서 아래와 같이 구성합니다.
Caching Application Block을 추가합니다.

기본적으로 Cache Manager라는 이름의 캐시관리자 노드가 생성되어 집니다.
가장 하위의 캐시 관리자 노드를 선택한 후 적절하게 속성을 변경할 수 있습니다.
ExpirationPollFrequencyInSeconds : 캐시 내 캐시 항목(데이터)의 만료기간 확인 주기(초)
MaximumElementsCacheBeforeScanvenging : 캐시 항목 정리가 일어나기 전 최대 항목의수, 이 수에 도달하면 캐시 항목 정리(만료된 캐시 정리)가 일어납니다.
Name : 원하는 이름으로 변경하면 되고, 이 이름은 추후 어플리케이션 코드에서 로깅 기능을 호출할 때 사용할 이름
NumberToRemoveWhenScavenging : 캐시 정리가 일어나는 동안 삭제되어질 캐시 항목의 개수
기본값은, 60초마다 캐시정리가 일어나고, 최대 1000개 이상의 캐시 항목이 존재할 수 있으며, 그 이상 존재시에 캐시 정리가 일어납니다. 그리고 한번의 캐시 정리로 10개의 캐시 항목이 삭제되어 집니다.
일단 위 처럼 기본적인 CacheManager를 추가하게되면 이는 in-memory 캐시를 의미합니다.
여기서 데이터베이스 또는 Isolated Storage를 캐시 저장공간으로 사용하고자 하면,
아래 처럼 캐시관리자에 저장소를 추가해 주어야 합니다.

테스트로 Isolated Storage를 추가하고 Partition을 Sample Cache로 설정하였습니다.

Isolated Storage는 사용자 별 저장공간으로 사용될 수 있는 저장소로서 Smart Client 어플리케이션 개발시 사용자 측 영구적 저장 공간으로서 유용하게 사용됩니다.
이 Isolated Storage에 대해서는 추후 별도 글로서 소개할 예정입니다.
이 Isolated Storage를 사용하면 사용자별로 구분된 저장공간으로 활용할 수 있다고 이해하면 될 듯 합니다. 그 실제 위치는 아래와 같습니다.
C:\Documents and Settings\UserAccount\Local Settings\Application Data\IsolatedStorage

이 폴더 하위의 구조는 시스템이 알아서 하는 부분이므로 신경쓰지 않아도 될 듯합니다. 그러나 위의 Sample Cache라는 PartitionName을 지정하게 되면 사용자의 해당하는 Isolated Storage 하위에 실제 Sample Cache라는 이름의 별도의 폴더가 생성되어 져서 캐시 정보가 관리 됩니다. 이는 여러 어플리케이션이 아마도 Isolated Storage를 사용할 수 있으므로, 이들 간에 서로 사용하는 공간을 구분해서 관리하고자 하는 목적일 것입니다.
어플리케이션 작성 과정
Microsoft.Practices.EnterpriseLibrary.Common.dll,
Microsoft.Practices.EnterpriseLibrary.Caching.dll
어셈블리를 찹조 추가 합니다.
그리고 아래의 Using 문을 삽입합니다.(Optional)
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
그리고, CacheManager 객체를 생성하고 적절한 메서드를 호출하면 됩니다.
캐시에 항목 추가하기
만일 동일한 키의 캐시 항목이 존재하면 해당 항목이 삭제 된 후 추가됩니다.
//Default CacheManager 객체를 생성합니다.- CacheItemPriority 는 캐시 항목의 우선선위로서 캐시 정리 동안에 해당 항목의 우선순위 속성에 따라 어떤 항목이 먼저 정리가 될지 결정됩니다.
//CacheManager 이름을 명시해서 생성할 수 있습니다.
//CacheManager productsCache = CacheFactory.GetCacheManager("Cache Manager");
CacheManager productsCache = CacheFactory.GetCacheManager();
string id = "ProductOneId";
string name = "ProductXYName";
int price = 50;
Product product = new Product(id, name, price);
productsCache.Add(product.ProductID, product, CacheItemPriority.Normal,
null, new SlidingTime(TimeSpan.FromMinutes(5)));
- new SlidingTime(TimeSpan.FromMinutes(5)) : 캐시 항목의 만료시간을 지정하는 것으로서 이 값은 SlidingTime 객체를 사용해서 마지막 접근 시점에서 5분 후에 만료토록 지정하는 것입니다.
- Add 메서드는 productsCache.Add(product.ProductID, product) 호출할 수 도 있는데 이렇게 추가하게되면 기본 Normal 우선순위와 "만료되지 않음" 값으로 추가되어집니다.
- 세번째 파라미터로서 null이 지정되어 있는데 이 파라미터는 캐시의 해당항목이 삭제될 때의 이벤트를 받을 수 있는 객체를 지정함으로써 사용자 액션을 추가할 수 있도록 합니다.
아래처럼 IcacheItemRefreshAction 인터페이스를 구현한 클래스를 정의하고
아래처럼 호출을 하여 캐시 항목을 추가하게 되면,
[Serializable]
public class ProductCacheRefreshAction : ICacheItemRefreshAction
{
public void Refresh(string key, object expiredValue, CacheItemRemovedReason removalReason)
{
// Item has been removed from cache. Perform desired actions here, based on
// the removal reason (for example, refresh the cache with the item).
}
}
productsCache.Add(product.ProductID, product, CacheItemPriority.Normal, new ProductCacheRefreshAction(), new SlidingTime(TimeSpan.FromMinutes(5)));
해당 캐시 항목 삭제 시에 위의 정의된 Refresh() 메서드 내에 정의된 코드가 실행되게 할 수 있습니다.
캐시 로딩하기
로딩 하는 방법은 Proactive, Reactive 이렇게 두가지 방식이 있고,
Proactive는 한번에 미리 로딩을 하는 방식이고, reactive는 필요시 마다 로딩 하는 방식입니다.
Reactive 방식의 경우 캐시 내에 해당 항목이 존재하는 지 확인 한 후에 추가해야 합니다.
public Product GetProductByID(string anID)
{
// This returns a product object with the specified ID.
}
public Product ReadProductByID(string productID)
{
CacheManager cache = CacheFactory.GetCacheManager();
Product product = (Product)cache.GetData(productID);
// Does our cache already have the requested object?
if (product == null)
{
// The requested object is not cached, so retrieve it from
// the data provider and cache it for further requests.
product = this.dataProvider.GetProductByID(productID);
if (product != null)
{
cache.Add(productID, product);
}
}
return product;
}
캐시 비우기
캐시 내의 모든 항목이 삭제됩니다.
CacheManager productsCache = CacheFactory.GetCacheManager();캐시 내 항목 삭제하기
// Operations on the cache
productsCache.Flush();
캐시 내의 특정 항목만을 삭제 합니다.
public void Remove(CacheManager cache, string key)캐시 내 항목 가져오기
{
cache.Remove(key);
}
// Read the item from the cache. If the item is not found더 상세한 많은 부분은 위대한 "도움말" 님이 알고 있습니다.
// in the cache, the return value will be null.
public Product GetProduct(CacheManager cache, string key)
{
return (Product)cache.GetData(key);
}
끝.
출처 : http://www.ensimple.net/enSimple/
댓글 없음:
댓글 쓰기