'oscache'에 해당되는 글 1건

  1. 2011.09.07 OSCache 3가지 주의할 점

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;

}
 

2번과 연관이 있는 코드로.. BO 비지니스가 cancelUpdate 보다 먼저 있다. 만약  bo.getdata() 호출시 RuntimeException이 발생되었다. 그렇다면, cancelUpdate() 메소드는 전혀 호출되지 않으며 원하지 않는 결과가 일어날 수 있다. 

따라서, 다음과 같은 코드로 변경되어야 한다.

        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는 크기, 알고리즘, 용량, 살아있을 수 있는 기간까지 넣을 수 있다.




 
Posted by '김용환'
,