2017-03-21 11 views
0

캐싱에 관한 또 다른 PlayFramework 2.x 관련 질문입니다. Play는 EhCache를 사용하지만, THINK 이것은 재생 질문입니다. EhCache 질문이 아닙니다.하지만 틀릴 수도 있습니다.PlayFramework의 캐시 개체가 원래 개체 인 것 같습니다.

그래서 캐시에서 개체를 가져옵니다. 이 예제에서는 데이터베이스에서 메뉴 항목을 가져오고 현재 메뉴 항목을 강조 표시합니다. 이 코드는 다음과 같습니다.

List<Menu> menuitems = cache.getOrElse("menu",() -> getMenuitemsFromDatabase(), DURATION_14_DAYS); 
for (Menu menuitem : menuitems) { 
    if (menuitem.getUrl().equals(request.uri())) { 
     menuitem.setHighlighted(true); 
     break; 
    } 
} 

문제는 항상 캐시에서 동일한 개체를 가져옵니다. 동일한 객체를 사용하면 실제로 메모리에서 동일한 객체를 의미합니다. 나는 그것이 메모리에있는 일부 해시 맵에 저장되어 있고 매번 같은 항목을 가져 오는 것 같아요.

두 개의 웹 사이트를 탐색하면 현재 메뉴 항목과 이전 메뉴 항목이 강조 표시됩니다. 그리고 분명히 더 많은 사이트를 탐색하면 더 악화됩니다.

예상하고 필요한 것은 메뉴 항목의 사본입니다. EhCache를 Redis로 교체하면 항상 사본을 얻습니다 (이는 redis 서버가 다른 시스템이므로 의미가 있습니다).

그래서 어떻게 캐시 된 객체의 복사본 만 가져 오도록 Play에 지시 할 수 있습니까? 난 정말 이러한 모든 개체를 수동으로 복사하고 싶지 않아요. Play 솔루션을 빌드하지 않으면 일반적인 방법은 무엇입니까? 분명히 캐시의 모든 객체는 직렬화 가능하므로 이러한 객체를 쉽게 복사 할 수 있습니다.

는 schube 여기에 사용되는으로 Ehcache의 버전을

답변

2

확실하지, 어떻게 달라질 수 있습니다이 문제를 해결하려면 주셔서 감사합니다 ... 그러나으로 Ehcache은 참으로 하지 복사 객체이 필요하지 않습니다. 직렬화가 필요한 경우에만 필요합니다 (예 : redis usecase). 그러나 엔트리가 JVM의 힙에 유지되는 한 실제로 같은 객체를 가져올 것입니다.

어떻게 해결할 수 있을까요? 글쎄, 그것은 달려있다. 당신은 ehcache (2.x/3.x)의 캐시 레벨에서 "copy-on-read/write"시맨틱을 강제 할 수있다. 하지만 당신이 다른 솔루션을 고려할 것입니다 ... 이것 때문에 캐시 액세스에 불필요한 대기 시간이 생기고 있습니다 ...하지만이 특정 유스 케이스 을 어떻게 처리해야하는지 잘 모르겠습니다..

어쨌든, redis (VM 외부) copy-on-read/write 의미론을 모방하는 것이 아마도 가장 쉽지만 성능이 떨어지는 것은 아닙니다.

+0

설명해 주셔서 감사합니다. 일반적으로 캐시 된 객체를 변경하지는 않지만이 특정 케이스에서는 메뉴 항목을 강조 표시하므로 객체를 변경합니다. 나도 모르겠다. 메뉴를 복사하고 현재 항목을 강조 표시하거나 모든 메뉴 항목을 반복하고 다른 항목을'menuitem.setHighlighted (false); '로 설정한다. 그러나 다른 누군가가 웹 사이트에 접근하면 걱정된다. 두 사용자가 동일한 개체를 사용하고 변경하기 때문에 경쟁 조건이 발생할 수 있습니다 ... 음, 일부 사례를 테스트 할 것입니다. 고맙습니다! – schube