인프런 커뮤니티 질문&답변

토니님의 프로필 이미지
토니

작성한 질문수

실전! 스프링 데이터 JPA

JPA Hint & Lock

이런 상황에선 어떻게 구현 하시는 지 궁금합니다.

작성

·

41

0

안녕하세요. 좋은 강의 항상 감사합니다.

JPA 와 디비를 배우면서 적용 하는 과정에서 궁금한게 생겼습니다.

 @Transactional
    public Post getPostDetail(Long postId) {
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new CustomException(ErrorCode.POST_NOT_FOUND));

        post.incrementViewCount();  // 조회수 증가
        return post;
    }

상세글 조회 시 조회수가 +1 되는 간단한 로직을 가정하겠습니다.

트래픽이 크다고 가정 할 시 해당 로직 대로 하면 조회 시 마다 DB에 부하가 예상되서 질문 드립니다.

 

  1. 해당 로직대로 해도 DB에 크게 부하를
    주지 않는 수준인가요?

  2. Redis를 써서 조회수 만 따로 캐시로 저장을 한다면
    DB랑 데이터가 정합하지 않을 것으로 예상됩니다.

  3. 만약 조회수가 중요한 서비스라면 db 락을 이용하여 성


    능 저하를 감안 하고 하시는지..



실무에선 어떻게 처리하시는 지 궁금합니다

답변 2

2

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 토니님

개발은 유지보수하기 쉬운 단순한 방법과 복잡한 성능 최적화 사이에서 적절한 고민이 필요합니다. 항상 그런 것은 아니지만 보통 성능을 최적화 할 수 록 더 복잡한 선택들이 필요합니다.

반대로 말하면 너무 많은 성능 최적화를 하면 유지보수가 매우 어려워질 수 있습니다.
개발은 어떤 정답이 있는 것 처럼 보이지만, 사실은 수 많은 선택지 중에 현재 프로젝트의 상황에 맞는 적절한 방법을 선택하는 것이 필요합니다. 저는 그래서 개발이 참 즐겁더라구요 :)

이 경우 예를 들면 단계별로 고민해야 하는 점은 다음과 같습니다.

1. 트래픽이 매우 적고, 동시 호출에 대한 이슈가 없다: 현재 방식은 가장 유지보수하기 편하고 재사용 가능한 방식입니다. 코드도 자바와 객체를 통해서 쉽게 바로 이해할 수 있습니다.

2. 트래픽이 조금 있고, 동시 호출에 대한 이슈가 있다: 이 경우 데이터베이스가 제공하는 update 쿼리를 직접 사용하는 것이 좋습니다. update set viewCount = viewCount + 1을 사용하는 것이지요. 이 경우 데이터베이스가 제공하는 기능에 종속적이기 때문에 유지보수 관점에서는 1번의 경우보다 좋지 않지만, 동시성 문제도 데이터베이스를 통해 원자적으로 해결되고, 조회 쿼리도 하나 줄일 수 있기 때문에 성능 관점에서 더 나은 선택입니다. 보통 실무에서 간편하게 많이 선택하는 방법 중 하나입니다. 참고로 JPA의 경우에도 JPQL을 통해 update 쿼리를 직접 사용할 수 있습니다.

3. 트래픽이 매우 많아진다: 이 경우 다양한 고민이 필요해집니다.

  • viewCount용 테이블을 별도로 분리한다. viewCount용 테이블

  • viewCount를 캐시를 사용해서 처리한다.(메모리 캐시, redis 등등, viewCount가 정밀하지 않아도 됨)

  • viewCount를 메모리나 로그에 같은 곳에 모은 다음에 주기적으로 배치를 통해 서비스 캐시나 DB에 저장한다. (viewCount가 정밀하지 않아도 됨)

참고로 락의 경우는 서비스에서 가급적 최소화 해야 합니다.

그리고 여기서 매우 중요한 부분이 있는데요. 조회수를 은행 예금처럼 정밀하게 100% 맞추어서 제공해야 하는가? 입니다. 만약 그렇게 해야 한다면 쉽게 성능을 최적화 하기가 매우 어려워집니다.

그런데 대부분의 사용자는 뷰 카운터를 은행 예금 처럼 중요하게 생각하지는 않을거에요. 이런 부분을 기획자와 잘 이야기해서 현실적인 범위안에서 서비스 정책을 정하게 되면 장비 비용도 아끼면서 성능 최적화도 더 잘 할 수 있을거에요.

도움이 되셨길 바래요 :)

0

안녕하세요, 인프런 AI 인턴입니다.

토니님께서 제기해주신 JPA를 사용한 조회수 증가 로직 구현에 대한 질문에 대해 답변드리겠습니다.

  1. 해당 로직대로 진행할 경우, 트래픽이 매우 높은 상황에서는 DB에 부하가 발생할 수 있습니다. 조회수와 같은 데이터는 변경이 잦지 않도록 설계하거나, 다른 대안을 통해 부하를 줄이는 것이 좋습니다.

  2. Redis와 같은 캐시를 사용하여 조회수를 따로 관리하는 방법도 가능합니다. 이 경우, 비동기적으로 주기적으로 DB에 업데이트하여 정합성을 유지할 수 있습니다. 다만, 이를 구현하기 위해서는 캐시 내의 데이터가 데이터베이스와 얼마나 자주 일치해야 하는지에 대한 비즈니스 요구 사항을 명확히 해야 합니다.

  3. 조회수가 매우 중요한 서비스라면, DB 락을 사용하여 정확한 데이터 처리를 할 필요가 있습니다. 하지만 락을 사용할 경우, 성능 저하가 있을 수 있으므로 충분한 고려가 필요합니다. 일반적으로는 조회수 증가 작업을 비동기로 처리하거나, 데이터베이스 트랜잭션보다 덜 부하가 많은 해결책을 강구하는 것이 좋습니다.

실무에서는 상황에 맞는 적절한 방법을 고려하여 선택하는 것이 중요합니다. 트래픽 양, 시스템 복잡도, 데이터 정합성 요구 등을 고려한 설계가 필요합니다.

강의가 많이 도움이 되시기를 바랍니다. 감사합니다.

추가 학습 자료

토니님의 프로필 이미지
토니

작성한 질문수

질문하기