오늘도 프로젝트를 이어나가느라 바빴던 하루였다. 성능테스트가 시간을 오래 잡아먹다보니 시간이 더 정신없게 흘러갔던 것 처럼 느껴진 것 같다. 성능테스트를 이어가면서 추가적인 기능에 대해서도 코드를 작성해볼 수 있었던 하루였다.
여기에는 오늘 적용했던 Cache Eviction에 대해 조금 정리해본다.
1. @CacheEvict 이용해보기
오늘은 프로젝트를 진행하면서 스프링 부트에서 지원하는 @CacheEvict를 적용해보기로 하였다. 사용방법 자체는 너무나도 간단해서 따로 정리가 필요할 것 같지는 않다.
먼저 Cache Eviction이 무엇인지 알아보았다.
Eviction은 퇴거라는 뜻이다. 캐시 메모리가 가득 차서 더 이상 새로운 데이터를 저장할 수 없는 경우면 기존 데이터 중 일부를 삭제하기도 하고, 캐시 데이터와 실제 데이터 사이의 정합성이 맞지 않는 경우에는 기존 캐시 데이터를 지우고 다시 새로운 데이터를 채워넣게 된다.
캐시 메모리가 가득 차서 새로운 데이터를 저장할 수 없는 경우라면 캐시에서 어떤 데이터를 삭제할지를 결정해야 하는데 이때 사용하는 삭제 전략을 Cache Eviction Policy라고 한다.
가장 오랫동안 사용되지 않은 데이터를 우선 삭제한다거나, 가장 최근에 사용된 데이터를 우선적으로 삭제한다거나, 가장 먼저 저장된 데이터를 삭제한다거나, 사용 빈도가 가장 낮은 데이터를 우선적으로 삭제한는 등 삭제 정책을 직접 설정해줄 수 있다.
하지만 우리 프로젝트에서는 이런 목적이 아니라 캐시와 실제 데이터 사이의 정합성이 필요한 것이었기 때문에 위의 삭제 전략 같은 것이 필요한 것이 아니라 @CacheEvict를 이용해 특정 상황에서 캐시를 무효화시키는 것이 필요했다.
현재 검색 기능에 캐시가 적용되어 있는데 캐시에 이미 key값으로 저장되어있는 검색어로 검색했을 때 게시판에 새로운 게시글이 올라왔을 경우에 해당 게시글의 내용이 검색에 포함되지 않게될 것이다. 이런 정합성 문제가 있었기 때문에 @CacheEvict를 사용하기로 결정했다.
정책은 매우 단순한데 어떤 사용자이던 게시글을 새로 올리게되면 기존에 저장되어있던 검색내역 캐시가 모두 무효화되도록 만들어주었다.
저장되어 있는 캐시를 싹 날려버리는 것이 괜찮은걸까 싶기도 했지만 실제 우리가 만든 영화리뷰 게시판 같은 경우 글이 올라오는 것보다 조회되는 일이 압도적으로 많기 때문에 이런 식으로 정책을 정해서 캐시를 적용해도 여전히 효과가 있다고 판단했다. 실제 비슷한 사이트들을 조사해본 결과 글을 올라오는 주기가 생각보다 짧지가 않기도 했다.
적용한 @CacheEvict는 아래와 같고 아주 쉽게 적용이 가능했다.
@CacheEvict("searchPostRedis", cacheManager = "redisCacheManager", allEntries = true)
override fun createPost(principal: UserPrincipal, request: CreatePostRequest): PostResponse {
val user = userRepository.findByIdOrNull(principal.id) ?: throw ModelNotFoundException("User", principal.id)
return postRepository.save(Post.of(request.title, request.content, request.category, user))
.let { PostResponse.from(it, 0) }
}
코드를 수정하고 테스트를 진행해 보았는데 글을 새로 작성할 때마다 캐시가 무효화되는 것을 잘 확인할 수 있었다.
이제 캐시 적용으로 인한 성능 향상의 장점과 더불어 DB와의 정합성 까지도 같이 챙길 수 있게 되었다.
다만 캐시는 원래 자주 바뀌지 않는 곳에 적용해야하는 것이 맞는데 현재 검색기능 같이 너무 자주 변하는 곳에 적용된 것이 아닌가? 이곳에 캐시를 적용하는 것이 정말 최선이었을까? 라는 의문이 드는 것도 사실이다. 실제 사용자들이 검색 기능을 얼마나 사용하는지에 대한 정보가 없기 때문에 현재는 단순히 가정을 해두고 캐시를 적용하였다.
캐시 적용법에 대해서는 이번 프로젝트를 진행하면서 잘 익힐 수 있었기 때문에 앞으로는 어디에 어떻게 적용해야 효율적이고 효과적일까에 대해서 더 고민할 수 있는 시간을 가질 수 있었으면 좋겠다.
2. 오늘 배운 것
- 성능 테스트라는 것이 개념부터 실제 수행까지 쉬운 부분이 하나 없다는 것을 알 수 있었다. 여유가 생길 때 더 자세히 공부해보아야겠다.
- 캐시에 대해서도 점점 더 잘 알게 된 것 같다. 적용 이전에 왜 어디에 적용해야하는지를 더 잘 생각해봐야겠다.
'오늘 배운 것' 카테고리의 다른 글
24-07-12 최종 프로젝트 첫 날 (0) | 2024.07.12 |
---|---|
24-07-10 프로젝트 트러블 슈팅 (0) | 2024.07.10 |
24-07-07 알고리즘 문제 풀이 (0) | 2024.07.08 |
24-07-04 PostgreSQL 더미 데이터 생성하기 (0) | 2024.07.04 |
24-07-03 Redis (0) | 2024.07.03 |