2016-12-08 2 views
0

나는 내 데이터를 캐시하기 위해 Guava Cache을 사용합니다. 몇 분 동안 사용하지 않으면 캐시의 데이터가 정리됩니다.Guava 캐시의 더티 데이터 처리 방법

데이터를 수정하면 캐시의 데이터를 업데이트하고 데이터가 "더티"로 표시됩니다 (수정되고 데이터베이스의 데이터와 다르기 때문에). 5 분마다 "더티 (dirty)"데이터를 데이터베이스로 푸시합니다 (즉, 데이터베이스의 데이터를 업데이트합니다).

문제가

는, A는 그 다음 내가 그래서 "더러운"데이터 A를

을 잃게됩니다 데이터베이스, 데이터 A가 먼저 정리 한에 밀려 데이터 전에 "더러운"데이터 A.이 데이터가 정리되었을 때 RemovalListenerGuava Cache에 추가하면 RemovalListener이 나를 알아 채고 콜백 기능을 사용하게됩니다. 이 함수에서는 데이터를 다시 캐시에 넣으려고합니다. 그러나 다중 스레드 환경에서는 데이터가 정확하다고 약속 할 수 없습니다.

예 :

1) 캐시 : 데이터 정리

2) 스레드 1 : 데이터를 얻을, 캐시에 데이터 A를 청소하고있다, 그래서 캐시는 database.And에서 데이터을 얻을 것이다 데이터베이스의 데이터 A는 최신 정보가 아닙니다. 따라서 스레드 1은 잘못된 데이터 A를 얻습니다.

3) cache : RemovalListener 콜백을 실행합니다.

그렇다면 더티 데이터를 어떻게 다룰 수 있습니까? 그럼 멀티 스레드에서 데이터가 항상 올바른 것으로 약속 할 수 있습니까? 감사!

+0

정말 데이터베이스 업데이트를 연기해야합니까? 데이터베이스에 커밋을하는 일반적인 프로세스가 너무 무거웠습니까? – Thilo

+0

@Thilo 데이터베이스를 자주 업데이트하면 DB I/O의 성능이 저하됩니다. 나는 단지 5 분마다 데이터베이스를 업데이트한다. – Gradle

답변

0

가능한 해결책은 더러운 데이터를 RemovalListener에 쓰는 것입니다. 이 작업이 동기화되면 동일한 항목에 대한 다른 작업이 차단되고 일관성없는 상태가 표시되지 않습니다. 데이터베이스의 대기 시간에 따라 캐시에서 다른 작업을 수행 할 수도 있습니다 (Guavas 설명서의 경고 참조).

일반적으로 말하자면, 소위 말하는 "캐시 뒤 쓰기"입니다. 이 기능이 내장 된 캐시 제품이 있습니다. 기존 솔루션을 살펴보십시오.

+0

감사! 그러나, 두 작업 (캐시 청소 데이터) 및 (RemovalListener)는 원자 적 연산이 아니므로 mutithread에서 내가 질문에서 말한 예와 같이 문제가 발생합니다. – Gradle

+0

나는 구아바 전문가가 아니라는 것을 인정해야합니다. 그러나 동기 제거 청취의 의미는 제거와 동 기적으로 수행되어야 할 일들을 수행하는 것입니다. 왜 그것이 원자가가 아니라고 생각합니까? – cruftex

+0

@curftex 미안하지만 나는 동 기적으로 그리고 원자적으로 퍼즐을 가지고있다. 필자의 의견으로는 비록 제거가 동 기적으로 이루어지기는하지만 두 작업 (캐시 정리)과 (RemovalListener)는 원자 적이지 않다. 그래서 두 가지 작업 사이에, 일부 스레드는 캐시에서 잘못된 데이터를 가져 오기 위해 일부 작업을 수행 할 것이라고 생각합니다. 나는 그걸로 당황했다. 그럼 당신은 그것을 설명 할 수 있습니다 .... – Gradle