Query 로직에서 DynamoDB에 크게 의존하고 있는 현상
BrianDYKim opened this issue · 1 comments
BrianDYKim commented
문제 상황
Query logic은 Redis라는 In-memory DB와 엮여있고, cache hit을 위해서 DynamoDB와는 약한 결합 형태를 띄고있다. 그러나, 문제가 있는 메소드가 몇 개 있다. 예를 들어 이런 메소드가 문제가 있다.
override fun getShopReviewListFlowByShopIdAndNameWithCaching(
shopId: String,
shopName: String
): Flow<ShopReview> {
val reviewKeysFlow = shopReviewDynamoRepository.getAllReviewKeyFlowByShopIdAndName(shopId, shopName)
return reviewKeysFlow.map { findShopReviewByIdAndTitleWithCaching(it.first, it.second).awaitSingle() }
}
해당 메소드가 문제가 되는 이유는, key의 pair는 dynamoDB로부터 가져오는데, 리턴 객체의 map에서는 Redis에다가도 비슷한 정도의 부하를 동시에 가하고 있는 모습을 확인할 수 있다. 이는 커다란 코스트로 이어질 수 있는 문제이다. 따라서 로직을 개선해보고자 한다.
개선 방안
그냥 Redis에 캐시되어있는 리뷰만 던져준다. 파생되는 문제는 다른 방법으로 해결한다.
파생되는 문제들?
위의 방법은 아래의 두 가지 경우를 야기할 것이다.
- 특정 shop에 대해서 리뷰가 하나도 캐싱이 안 되어있는 케이스
- 특정 shop에 대해서 캐싱된 리뷰가 있긴하지만, 개수가 맞지 않는 케이스
따라서 이를 해결해야만한다.
파생되는 문제들은 어떻게 해결할까?
구현 과정에서 shop entity에 reviewCount를 담아둔 것을 활용한다.
- review를 전체 조회하는 메소드를 호출하면 해당 이벤트를 kafka로 발행한다
- 해당 이벤트를 컨슘하면, 컨슈머는 shop을 까보고 조회한 리뷰 개수와 실제 리뷰 개수가 맞는지 체크한다
- 맞지 않는다면, 그 때 dynamo를 스캔하여 redis에 저장한다
위의 방법대로 구현을 대체하면 query logic에서는 더 이상 dynamo에 크게 의존하지 않아도 될 것으로 예상한다.
BrianDYKim commented
2022/08/20 해결 완료