withmarket-server/shop-review-reply

Query 로직에서 DynamoDB에 크게 의존하고 있는 현상

BrianDYKim opened this issue · 1 comments

문제 상황

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를 담아둔 것을 활용한다.

  1. review를 전체 조회하는 메소드를 호출하면 해당 이벤트를 kafka로 발행한다
  2. 해당 이벤트를 컨슘하면, 컨슈머는 shop을 까보고 조회한 리뷰 개수와 실제 리뷰 개수가 맞는지 체크한다
  3. 맞지 않는다면, 그 때 dynamo를 스캔하여 redis에 저장한다

위의 방법대로 구현을 대체하면 query logic에서는 더 이상 dynamo에 크게 의존하지 않아도 될 것으로 예상한다.

2022/08/20 해결 완료