ehcache에서 cache element를 유지하는 방법은?

2013-09-27 21:19

현재 ehcache를 사용하고 있는데 다음과 같은 요구사항의 경우 처리할 수 있는 방법이 있을까요?

ehcache에 cache element로 한번 추가되면 데이터가 더 이상 변경되지 않습니다. 따라서 새로운 element가 추가되더라도 기존 cache를 제거할 필요가 없습니다. 그런데 현재 상태는 새로운 element가 추가될 때마다 기존 cache가 모두 초기화되고 다시 cache에 담기는 상황이 발생하네요. ehcache는 spring cache와 같이 사용하고 있습니다. 설정은 다음과 같습니다.

<cache
    name="smallTalkCache"   
    maxElementsInMemory="100"
    eternal="false"
    timeToIdleSeconds="3600"
    timeToLiveSeconds="3600"
    overflowToDisk="false"
/>

spring 설정

@Cacheable(value="smallTalkCache", key="#url")
public SiteSummary findOneThumbnail(String url) {
    [...]
}

ehcache에 경험 많으신 분들 중 같은 경험이 있으시면 공유해 주시면 감사하겠습니다.

0개의 의견 from FB

2개의 의견 from SLiPP

2013-09-28 06:49

위 코드에 특별히 문제점이 있었던 것은 아니었습니다. 제가 다른 개발자가 구현한 코드를 가지고 캐시로 성능 개선하다보니 몰랐던 코드가 숨어 있더군요. 데이터를 추가하는 부분에 다음과 같이 element가 추가될 때 모든 데이터를 Evict(캐시에서 제거)하도록 설정이 되어 있더군요.

@CacheEvict(value="smallTalkCache", allEntries=true)
public void save(SmallTalk smallTalk) {
    [...]
}

위 코드에서 CacheEvict 설정을 삭제하니까 정상적으로 동작했습니다. Cache 사용할 때는 조회하는 곳 뿐만 아니라 Element를 추가하는 곳이 있으면 추가하는 곳도 반드시 확인해 보시기 바랍니다.

2013-09-28 16:45

주제와는 좀 다른 이야기인데요. 제가 cachable 사용했을 때의 경험담을 잠깐 말씀해드리면 ... 처음 @Cachable 사용할 때는 BO나 DAO에 @Cachable을 적용했었는데요. 그랬더니 예를 들어 어드민에서는 캐시가 아닌 실제데이터가 표시되어야 하는데 캐시가 적용된다던가 하는 문제가 발생했어요. 그래서 제가 택한 방법은 Cacha 클래스를 별도로 만들었어요.

class Bo implements IBo { Data get(int a) { ... } }
class CacheBo implements IBo { Data @Cachable get(int a) { bo.get(a); } }

그리고 컨트롤러에서 알아서 사용하도록 했어요.

class SvcController { @Autowired @Qualifier("cacheBo") IBo bo; }
class AdmController { @Autowired @Qualifier("Bo") IBo bo; }

물론 사람들이 인터페이스 만드는 걸 싫어했고, 인터페이스가 아주 큰 이득을 주는 것도 아닌 상황이라서 IBo는 삭제했지만요 ㅎㅎ

또 다른 이슈는 서비스는 데이터를 랜덤하게 표시하고, 어드민은 순서대로 표시해야 하는 문제가 있었어요. 이런 경우 CachaBo에서 랜덤 로직을 가지면 항상 동일한 순서대로 출력되서 랜덤이 아닌 것 같은 느낌이 들죠. 하지만 조금 더 생각해보니 웹서버가 여러대이기 때문에 CacheBo에서 shuffle해도 상관없더라구요. ㅋㅋ

의견 추가하기