본문 바로가기
programming/ibatis

ibatis 캐싱 관련1

by hotdogya 2012. 12. 9.

ibatis 캐싱 관련

출처 : http://ukzzang.tistory.com/27


-- CacheModel 이해하기
CacheModel은 iBatis의 모든 캐시 구현체를 정의하는 기반이 되는 곳이다. SQL Maps 설정 안에서 캐시 모델 설정을 정의하고 하나 이상의 쿼리 매핑 구문이 이를 사용할 수 있다.

* CacheModel 속성들 *
id (필수) : 유일한 ID를 지정. CacheModel에 설정 된 캐시를 사용하고 하는 쿼리 매핑 구문에서 ID를 참조한다.
type (필수) : 이 값은 CacheModel이 설정하는 캐시의 타입을 의미한다. 사용 가능한 값으로 MEMORY, LRU, FIFO, OSCACHE가 있다. 이 속성은 사용자 정의 CacheController 구현체의 완전한 클래스 이름으로 지정해도 된다.
readOnly (선택) : 읽기전용 여부. 이 값을 true로 지정하면 캐시가 읽기 전용 캐시로 사용될 것임을 의미한다. 읽기 전용 캐시에서 가져온 객체는 객체의 Property들을 변경할 수 없다.
serialize (선택) : 캐시의 내용을 가져올 때 객체의 모든 값을 복사하여 새로운 객체를 생성하여 전달할지 여부를 지정한다.

여기서 readOnly 속성 값에 대해 좀더 알아보면 readOnly 속성은 단순히 CcheModel에게 캐시된 객체를 어떻게 가져와서 저장할지 알려주는 지시자이다. 이 속성값이 true이면 가져온 내용을 변경해도 CacheModel은 변경되지 않는다. 만약 false로 지정되면 주의해야 하는데 두 명 이상의 사용자가 캐시된 참조의 동일한 인스턴스를 가져갈 수 없음을 의미한다.


* 내장 CacheModel 타입들 *
MEMORY : 단순하게 캐시된 데이터를 가비지 컬렉터가 삭제할 때까지 메모리에 저장한다.
FIFO : 고정 된 크기의 모델로 "first in first out (먼저 들어간 값을 먼저 삭제)" 알고리즘을 사용하여 메모리에서 캐시 항목들을 삭제한다.
LRU : FIFO와 다른 고정 된 크기의 모델로 "least recently used (최근에 가장 오랜동안 사용하지 않은 값을 캐시에서 먼저 삭제)" 알고리즘을 사용하여 메모리에서 캐시 항목들을 삭제한다.
OSCACHE : OpenSymphony Cache를 사용한다. (OSCashe Lib와 설정이 함께해야 한다.)

* readOnly와 serialize 속성의 조합에 대한 요약 *
readOnly (true) / serialize(false) : 성능 좋음. 캐시 된 객체를 가장 빠르게 가져온다. 캐시 된 객체의 공유 인스턴스를 반환하며, 잘못 사용하면 문제를 일으킬 수도 있다.
readOnly (false) / serialize(true) : 성능 좋음. 캐시 된 객체를 빠르게 가져온다. 캐시 된 객체를 깊은 복사 작업을 통해 가져온다.
readOnly (false) / serialize(false) : 주의요망! 캐시는 오직 호출하는 스레드의 세션이 살아있는 동안에만 관련되고, 다른 쓰레드는 사용할 수 없다.
readOnly (true) / serialize(true) : 성능 나쁨. 무의미한 설정이라는 점을 제외하면 readOnly (true) / serialize(true)와 동일하게 작동한다.

readOnly=true이고 serialize=false이면 캐시 된 객체가 전역적으로 공유되기 때문에 모든 사용자는 다른 세션에서 부적절하게 변경 된 객체를 가져오게 될 수 있는 문제의 소지가 있다. readOnly=false이고 serialze=true를 사용하면 캐시에서 가져온 객체의 깊은 복사작업의 결과를 가져오기 때문에 캐시에서 가져온 객체가 값은 비록 같지만 동일한 인스턴스가 아니라는 의미이다. 이것은 캐시에서 가져온 객체의 변경사항이 호출한 세션 안에서만 작용된다.

-- 캐시 비우기 (Cache Flushing)
사용자가 정의 한 CacheModel은 캐시된 데이터를 모두 비울때 사용하는 공통적인 요소를 가지고 있다. 이것은 이전에 캐시된 모든 데이터를 비우고 새롭게 데이터를 캐시하게 된다.

* 캐시를 비우는 flush 요소들 *
<flushOnExecute> : 지정 된 쿼리 매핑 구문이 실행되면 캐시의 모든 데이터를 비운다.
<flushInterval> : 캐시를 비우는 시간 간격을 정의한다.

<flushOnExecute>
속성으로 statement 하나만을 가지며, 이 속성에 지정된 매핑 구문이 실행이 될 때 자동으로 캐시의 데이터를 모두 비운다. 예를 들어 상품카테고리의 카테고리가 추가, 수정, 삭제 될면 이전에 캐시된 신빙성이 떨어지는 데이터를 모두 비우게 할 수 있다.
 그러나, 이 속성은 캐시된 데이터를 모두 비우고 새롭게 캐시를 하게 되므로 데이터를 자주 변경하는 매핑 구문에 의존하게 되면 캐시의 효율성이 떨어지게 된다.

   <SqlMap namespace="category">
       <cacheModel id="categoryCache" type="MEMORY">
          ...
          <flushOnExecute statement="category.insert" />
       </cacheModel>
       ...
       <insert id="insert" parameterClass="java.util.Map">
          ...
       </insert>

<flushInterval>
 <flushOnExecute> 보다 좀더 간편하게 사용할 수 있는 요소로 시간에 의존하여 지정한 시간이 경과되면 반복적으로 캐시된 데이터를 모두 비운다. 가격은 시(hours),분(minutes),초(seconds) 또는 밀리초(milliseconds)로 지정할 수 있다. <flushInterval>은 하나의 속성만을 허용하기 때문에 5시간 13분 40초와 같이 지정하고 싶다면 초로 계산하여 지정해야 한다. 그리고, 특정 시간을 지정할 수는 없다.

   <cacheModel id="categoryCache" type="MEMORY">
       ...
       <flushInterval hours="12" />
    </cacheModel>

-- CacheModel Properties 설정하기
 CacheModel은 플러그인의 형태로 제공되기 때문에 임의의 설정 값을 제공할 수 있는 방법이 필요한데 <property>를 이용하여 처리한다.

* <property> 요소의 속성들 *
name : 필수입력으로 설정할 프로퍼티의 이름
value : 필수입력으로 설정할 프로퍼티의 값

-- CacheModel Type
 앞에서 언급했듯이 iBatis에서 사용할 수 있는 CacheModel Type은 MEMORY, LRU, FIFO, OSCACHE 4가지가 있다.

MEMORY
 객체 참조를 기반으로 한 캐시이다. 캐시 내의 각 객체의 참조 타입(<reference-type>) 속성을 갖고 있다. 객체의 참조 타입은 가비지 켈렉터에게 객체를 어떻게 다룰지에 대한 힌트를 제공한다. MEMORY CacheModel은 객체에 접근하는 방식보다는 메모리 관리에 중점을 둔 Application에 적합하다.

* MEMORY CacheModel 참조 타입 *
WEAK : 캐시된 데이터를 빨리 비운다. 기본설정 값이며 가비지 켈렉터에 의해 수거되는 것을 막지않고 놔둔다. 이 방식은 일관성 있게 객체에 접근하는 캐시를 사용할 때 잘 적동한다. 캐시를 비우는 비율이 빠른편이기 때문에 메모리 제한을 넘기지 못하도록 보장은 하나 DataBase 접근확률이 높아진다.
 SOFT : 메모리 용량이 허락하는 한 캐시된 객체를 보관한다. 가비지 켈렉터는 더 많은 메모리가 필요하다고 판단되기 전까지는 이 객체들을 수거하지 않는다. 메모리 제한을 넘기지 못하도록 보장하며, WEAK 참조보다 DataBase 접근확률은 적은 편이다.
 STRONG : 메모리의 한계가 얼마든지 관계없이 객체를 계속 보관한다. 가비지 켈렉터에 의한 수거는 없다. 이 참조타입은 정적이고 작고 장기적으로 사용할 객체를 캐시할 때 유용하다. DataBase 접근확률은 최소할 수 있으나, 캐시되는 객체의 용량이 너무 커져서 메모리 부족이 발생될 수 있다.

   <cacheModel id="categoryCache" type="MEMORY">
       <flushInterval hours="12" />
       <flushOnExecute statement="insert" />
       <property name="reference-type" value="WEAK" />
    </cacheModel>

LRU
 가장 최근에  가장 오랫동안 사용되자 않은 것을 제거하는 방식으로 캐시를 관리한다. 캐시의 객체를 제거하는 것은 오직 캐시의 용량이 제한을 넘겼을 때 한번만 발생된다. 특정 객체에 아주 빈번하게 접근하는 캐시를 관리할 때 매우 적합하다. <property> 요소를 사용하여 지정할 수 있는 프로퍼티는 size 하나로 캐시에 저장될 수 있는 최대 개수를 지정한다.

   <cacheModel id="categoryCache" type="LRU">
       <flushInterval hours="12" />
       <flushOnExecute statement="insert" />
       <property name="size" value="200" />
    </cacheModel>

FIFO
 먼저 캐시 된 객체를 먼저 삭제한다. 캐시의 객체를 제거하는 것은 오직 캐시의 용량이 제한을 넘겼을 때 한번만 발생된다. 생존기간에 기반을 두고 있기 때문에 초기에 캐시에 저장되는 그 순간에 더 많이 사용되는 객체를 캐싱할때 효과적이다. <property> 요소를 사용하여 지정할 수 있는 프로퍼티는 size 하나로 캐시에 저장될 수 있는 최대 개수를 지정한다.

   <cacheModel id="categoryCache" type="FIFO">
       <flushInterval hours="12" />
       <flushOnExecute statement="insert" />
       <property name="size" value="200" />
    </cacheModel>

OSCACHE
 Open Symphoy(http://www.opensymphony.com/oscache)의 OSCache를 사용한다.OSCACHE를 사용하기 위해서는 OSCache 라이브러리와 설정정보가 필요하다.

  <cacheModel id="categoryCache" type="OSCACHE">
       <flushInterval hours="12" />
       <flushOnExecute statement="insert" />
    </cacheModel>

사용자가 만든 캐시 모델
 앞에서 언급했듯이 iBatis의 캐시 모델은 플러그인되는 형태여서 사용자가 캐시모델을 만들어서 사용할 수 있다. 사용자가 자신의 캐시모델을 만들기 위해서는 com.ibatis.sqlmap.engine.cache.CacheController 인터페이스를 구현하면 되고, 이름은 alias를 사용하면 된다.

'programming > ibatis' 카테고리의 다른 글

ibatis 캐싱관련3  (0) 2012.12.09
ibatis 캐싱관련2  (1) 2012.12.09
ibatis dynamic 쿼리  (0) 2012.02.06