debop / hibernate-redis

hibernate 2nd level cache privder using redis
Apache License 2.0
358 stars 182 forks source link

org.hibernate.cache.redis.regions.RedisDataRegion#destroy 메소드에 관한 질문 #20

Closed kwon37xi closed 10 years ago

kwon37xi commented 10 years ago

먼저 제가 스스로 다른 Hibernate 캐시를 구현하면서 배성혁님의 소스를 많이 참조하고 있습니다. 그러면서 분석하고 배우고 그러고 있습니다. 고맙습니다.

org.hibernate.cache.redis.regions.RedisDataRegion#destroy 에 관한 질문입니다. 현재 이 메소드는 region을 삭제하는 것으로 보이는데요, ( hibernate의 다른 캐시 구현체들도 모두 그렇게 구현하고 있더군요). 문제는 이 메소드가 SessionFactory.close()가 호출될 때 모든 Region을 돌며 호출된다는 점입니다.

여러 웹 서버가 동일한 Redis 캐시를 바라보고 캐싱을 하는데 그 중에서 한 대의 웹서버가 종료되면, 그 순간 SessionFactory.close() 호출 -> 모든 RedisDataRegion 객체를 돌면서 destroy() 호출로 인해 모든 region이 삭제될 것으로 예상됩니다.

그렇게 되면 나머지 살아 있는 웹서비스들은 순간적으로 모든 캐시를 expire당하게 되어 순간적으로 급격한 성능 저하가 발생할 것으로 예상됩니다.

제가 보기엔 이게 Local 캐시용으로 마련된 메소드인 것 같습니다. redis 같은 분산 캐시 계열에서는 캐시 region 삭제 용도로 호출되면 안 될 것 같습니다.

한 번 확인을 부탁드립니다.

debop commented 10 years ago

안녕하세요. 질문하신 내용 때문에 초기에는 HA 구성을 고려해서 SessionFactory가 죽어도, cache 를 삭제 하지 않도록 했습니다.

다른 캐시 시스템인 경우 각 cache 별로 expiration 을 직접 지원하도록 할 수 있으므로, 굳이 Session Factory 삭제 시에 굳이 삭제할 필요가 없습니다.

Redis provider 구현 시, Redis 사용 효율을 고려하여 Region 별로 HashSet 에 저장하게 하여, expiration을 직접 관리해야 했습니다. 이 것이 가장 큰 문제인데, 하나의 Session Factory가 삭제 되었을 때, Data 가 살아 남아 있어, 향후 문제가 발생할 수 있습니다.

그래서 현재로서는 HA 구성 시에 성능 저하가 나오더라도, 하나의 Session Factory가 죽으면 Region을 삭제하고 있습니다.

이 부분을 해결하기 위해, 현재 get 메소드 내에서 값과 expiration 을 모두 검사하여 제공하도록 하고, Session Factory에서는 region을 삭제하지 않으려고 합니다. (현재 HA 에서 테스트 중입니다)

kwon37xi commented 10 years ago

네, 그렇군요. 감사합니다.