From 82e5f99ae134d4bd8cab9a1e43eb234b13cc7183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sat, 13 Jul 2024 15:52:32 +0900 Subject: [PATCH] [FIX] change open api cache to use cacheput rather than cacheevict --- .../domain/friend/service/FriendService.java | 8 ++--- .../domain/group/service/GroupService.java | 6 ++-- .../domain/member/service/MemberService.java | 6 ++-- .../domain/path/service/PathService.java | 6 ++-- .../domain/place/service/PlaceService.java | 4 +-- .../domain/plan/service/PlanService.java | 8 ++--- backend/src/portfolio/REDIS_CACHE.md | 29 ++++++++++++++++--- 7 files changed, 44 insertions(+), 23 deletions(-) diff --git a/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java b/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java index ec605bcf..c6c1e1d3 100644 --- a/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java +++ b/backend/src/main/java/com/twtw/backend/domain/friend/service/FriendService.java @@ -21,7 +21,7 @@ import lombok.RequiredArgsConstructor; -import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -90,7 +90,7 @@ public String getMemberIdValue() { return authService.getMemberIdValue(); } - @CacheEvict( + @CachePut( value = "getFriendsWithCache", key = "'getFriendsWithCache'.concat(#root.target.getMemberIdValue())", cacheManager = "cacheManager") @@ -119,7 +119,7 @@ private List getFriendResponses() { return friendMapper.toResponses(friends); } - @CacheEvict( + @CachePut( value = "getFriendsByStatusWithCache", key = "'getFriendsWithCache'.concat(#root.target.getMemberIdValue()).concat(#friendStatus.name())", @@ -152,7 +152,7 @@ private List getFriendResponsesByStatus(final FriendStatus frien return friendMapper.toResponses(friends); } - @CacheEvict( + @CachePut( value = "getFriendsByNicknameWithCache", key = "'getFriendsWithCache'.concat(#root.target.getMemberIdValue()).concat(#nickname)", cacheManager = "cacheManager") diff --git a/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java b/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java index cff9ec5c..ba2c3b33 100644 --- a/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java +++ b/backend/src/main/java/com/twtw/backend/domain/group/service/GroupService.java @@ -18,7 +18,7 @@ import com.twtw.backend.global.constant.NotificationTitle; import com.twtw.backend.global.exception.EntityNotFoundException; -import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -48,7 +48,7 @@ public GroupService( this.fcmProducer = fcmProducer; } - @CacheEvict( + @CachePut( value = "getGroupByIdWithCache", key = "'getGroupWithCache'.concat(#groupId)", cacheManager = "cacheManager") @@ -152,7 +152,7 @@ public String getMemberIdValue() { return authService.getMemberIdValue(); } - @CacheEvict( + @CachePut( value = "getMyGroupsWithCache", key = "'getMyGroupsWithCache'.concat(#root.target.getMemberIdValue())", cacheManager = "cacheManager") diff --git a/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java b/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java index 7b56d564..9e50223d 100644 --- a/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java +++ b/backend/src/main/java/com/twtw/backend/domain/member/service/MemberService.java @@ -9,7 +9,7 @@ import com.twtw.backend.global.exception.EntityNotFoundException; import com.twtw.backend.utils.QueryParseUtils; -import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,7 +44,7 @@ public String getMemberIdValue() { return authService.getMemberIdValue(); } - @CacheEvict( + @CachePut( value = "getMemberByNicknameWithCache", key = "'getMemberWithCache'.concat(#root.target.getMemberIdValue()).concat(#nickname)", cacheManager = "cacheManager") @@ -94,7 +94,7 @@ public List getMembersByIds(final List friendMemberIds) { return memberRepository.findAllByIds(friendMemberIds); } - @CacheEvict( + @CachePut( value = "getMemberByIdWithCache", key = "'getMemberByIdWithCache'.concat(#root.target.getMemberIdValue())", cacheManager = "cacheManager") diff --git a/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java b/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java index d6cf960c..42595f23 100644 --- a/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java +++ b/backend/src/main/java/com/twtw/backend/domain/path/service/PathService.java @@ -6,7 +6,7 @@ import com.twtw.backend.domain.path.dto.client.ped.SearchPedPathResponse; import com.twtw.backend.global.client.MapClient; -import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @@ -31,7 +31,7 @@ public SearchCarPathResponse searchCarPathWithCache(final SearchCarPathRequest r return carPathClient.request(request); } - @CacheEvict( + @CachePut( value = "carPath", key = "'searchCarPath'.concat(#request.toString())", cacheManager = "cacheManager") @@ -48,7 +48,7 @@ public SearchPedPathResponse searchPedPathWithCache(final SearchPedPathRequest r return pedPathClient.request(request); } - @CacheEvict( + @CachePut( value = "pedPath", key = "'searchPedPath'.concat(#request.toString())", cacheManager = "cacheManager") diff --git a/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java b/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java index 52e67bff..0e0df563 100644 --- a/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java +++ b/backend/src/main/java/com/twtw/backend/domain/place/service/PlaceService.java @@ -10,7 +10,7 @@ import lombok.RequiredArgsConstructor; -import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @@ -20,7 +20,7 @@ public class PlaceService { private final PlaceMapper placeMapper; private final KakaoMapClient surroundPlaceClient; - @CacheEvict( + @CachePut( value = "surroundPlace", key = "'searchSurroundPlace'.concat(#surroundPlaceRequest.toString())", cacheManager = "cacheManager") diff --git a/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java b/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java index 3b2a3d15..53fed51d 100644 --- a/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java +++ b/backend/src/main/java/com/twtw/backend/domain/plan/service/PlanService.java @@ -32,7 +32,7 @@ import lombok.RequiredArgsConstructor; -import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -124,7 +124,7 @@ public void outPlan(PlanMemberRequest request) { plan.deleteMember(member); } - @CacheEvict( + @CachePut( value = "getPlanByIdWithCache", key = "'getPlanByIdWithCache'.concat(#id)", cacheManager = "cacheManager") @@ -171,7 +171,7 @@ public String getMemberIdValue() { return authService.getMemberIdValue(); } - @CacheEvict( + @CachePut( value = "getPlansWithCache", key = "'getPlansWithCache'.concat(#root.target.getMemberIdValue())", cacheManager = "cacheManager") @@ -243,7 +243,7 @@ public void deleteInvite(final PlanMemberRequest request) { plan.deleteInvite(member); } - @CacheEvict( + @CachePut( value = "getPlansByGroupIdWithCache", key = "'getPlansByGroupIdWithCache'.concat(#groupId)", cacheManager = "cacheManager") diff --git a/backend/src/portfolio/REDIS_CACHE.md b/backend/src/portfolio/REDIS_CACHE.md index 335097e2..4e5e9eb0 100644 --- a/backend/src/portfolio/REDIS_CACHE.md +++ b/backend/src/portfolio/REDIS_CACHE.md @@ -8,8 +8,9 @@ --- -> 사용자에게 경로를 제공하기 위해 Kakao, Naver, Tmap Open API를 사용한다. 위 API 제공에 있어 호출까지의 **시간이 소요**되고 **비용 낭비**가 발생 +> 사용자에게 경로를 제공하기 위해 Kakao, Naver, Tmap Open API를 사용한다. 위 API 제공에 있어 호출까지의 **시간이 소요**되고 **비용 낭비**가 발생 > + - 이미 반환된 경로를 사용자가 재사용하는 경우가 많기 때문에 경로를 임시 메모리에 저장하는 로직 필요 - ‘경로’라는 데이터 특성 상 한번 참조된 값에 대해 변경이 자주 일어나지 않음 @@ -19,18 +20,38 @@ ### 적용 -- @CacheEvict와 @Cacheable Annotation을 사용하여 API에 레디스 캐시 적용 +- @CachePut과 @Cacheable Annotation을 사용하여 API에 레디스 캐시 적용 ### 시퀀스 다이어그램 ![image](https://github.com/HongDam-org/TWTW/assets/84346055/6cb63e15-767d-4a21-89cc-91724323f0b0) -![image](https://github.com/HongDam-org/TWTW/assets/84346055/3375f917-e88e-480a-a3f1-bbcbd401557d) +```Java + +@CachePut( + value = "surroundPlace", + key = "'searchSurroundPlace'.concat(#surroundPlaceRequest.toString())", + cacheManager = "cacheManager") +public PlaceResponse searchSurroundPlace(final SurroundPlaceRequest surroundPlaceRequest) { + return getPlaceResponse(surroundPlaceRequest); +} + +@Cacheable( + value = "surroundPlace", + key = "'searchSurroundPlace'.concat(#surroundPlaceRequest.toString())", + cacheManager = "cacheManager", + unless = "#result.results.size() <= 0") +public PlaceResponse searchSurroundPlaceWithCache( + final SurroundPlaceRequest surroundPlaceRequest) { + return getPlaceResponse(surroundPlaceRequest); +} +``` ### 시나리오 > Redis Cache를 적용하였을 때 성능 분석을 위해 다음과 같은 시나리오를 세우고 테스트 진행 > + 1. 회원가입 수행 2. 보행자 경로 API를 요청하여 수행 @@ -56,4 +77,4 @@ 1. Redis Cache를 사용할 경우 사용하지 않은 경우에 비해 4.12배의 속도 성능 향상 2. Open API를 중복 요청하지 않아 네트워크 비용 절감 -3. CacheEvict를 통해 사용자의 요청 경로가 변경된 경우 기존 Cache값을 삭제하고 변경된 경로를 저장하고 제공하여 서비스상 유연성 향상 +3. CachePut를 통해 사용자의 요청 경로가 변경된 경우 기존 Cache값을 삭제하고 변경된 경로를 저장하고 제공하여 서비스상 유연성 향상