oscache 를 사용할 때 자주 실수하는 점은 총 3가지이다.
1. cache 크기로 인한 OOME 발생
os cache는 ehcache와 달리 개수로만 cache한다. 만약 cache에 들어갈 entity의 크기는 10,000개인데, 이 entity의 크기가 확 커질 수 있다. ibatis 설정의 oscache 또는 cron과 함께 쓰는 oscache쪽을 잘 살펴봐야 한다.
* Heap 메모리 크기 변화
프로파일링 하면서 oscache 문제 확인, 크기를 줄이니 OOME 문제는 사라졌다.
2. 모든 쓰레드 Wait 현상 (마치 deadlock처럼 느껴짐)
아래와 같은 코드는 oscache는 모든 쓰레드의 blocking을 일어나게 하고, 웹 서비스가 중단되게 할 수 있다.
try{
cacheData = admin.getFromCache(key, cacheTime);
} catch (NeedsRefreshException e) {
throw e;
oscache의 getXXX 메소드를 호출하면 wait 메소드를 호출하고 데이터가 들어올 때까지 기다린다. 데이터가 들어와서 putXX 메소드가 호출되면, notify 메소드가 호출되고 데이터를 전달하는 구조이기 때문에 이는 수많은 리퀘스트가 동시에 요청하는 웹에 대해서는 문제를 야기할 수 있다.
응답을 처리하는 것보다 요청하는 것이 급격하게 많은 경우에 쓰레드가 모두 소진되어 쓸 수 없는 상황까지 갈 수 있다. 또한 따라서, cancelupdate 메소드를 호출하면서 wait된 thread를 빨리 notify해야 한다.
try{
cacheData = admin.getFromCache(key, cacheTime);
} catch (NeedsRefreshException e) {
admin.cancelUpdate(key);
throw e;
}
그러나, 소스를 변경한다 해도 원론적인 문제를 해결할 수 없을 수 있음. 만약 1000개의 리퀘스트가 한번에 들어온다고 가정했을때.. deadlock은 일어날 수 있다.
따라서 해결 방법은 다른 cache를 써야 한다. ehcache를 사용하는 것이 유일한 해법인 것 같다.
3. 원하지 않는 데이터 얻어옴
try{
cacheData = admin.getFromCache(key, cacheTime);
} catch (NeedsRefreshException e) {
bo.getdata(); // throw RuntimeException
admin.cancelUpdate(key);
throw e;
}
따라서, 다음과 같은 코드로 변경되어야 한다.
try{
cacheData = admin.getFromCache(key, cacheTime);
} catch (NeedsRefreshException e) {
try {
bo.getdata(); // throw RuntimeException
} catch (RuntimeException re) {
log.error(re);
}
admin.cancelUpdate(key);
throw e;
}
또는 finally를 이용한 처리도 괜찮다.
try{
cacheData = admin.getFromCache(key, cacheTime);
} catch (NeedsRefreshException e) {
bo.getdata(); // throw RuntimeException
} finally {
admin.cancelUpdate(key);
결론은 oscache보다는 ehcache이다.
1. API 구조가 안좋다. wait/notify 구조로 인해서 오해할 수 있는 api들이 존재. ehcache는 api 깔끔
2. oscache는 간단히 쓸 수 있지만, 크기만 지정가능하다. ehcache는 크기, 알고리즘, 용량, 살아있을 수 있는 기간까지 넣을 수 있다.
'general java' 카테고리의 다른 글
JAXB 잘 사용하기 (1) | 2011.12.21 |
---|---|
WindowBuilder Pro 간단한 소개 (0) | 2011.09.20 |
Spring MVC 3 Restful 맛보기 (2) | 2011.08.10 |
java.lang.ClassNotFoundException: org.apache.taglibs.standard.tlv.JstlCoreTLV (0) | 2011.08.08 |
Jersey Framework 맛보기 (0) | 2011.08.05 |