Skip to content

Conversation

@whxogus215
Copy link
Contributor

@whxogus215 whxogus215 commented Sep 9, 2024

🔧연결된 이슈

  • closed

🛠️작업 내용

  • 기이수 과목을 저장하는 save 로직을 JPA가 아닌 JDBC를 사용하도록 변경
  • JdbcTemplate을 통해 batch insert를 수행하는 saveAll() 인터페이스 및 구현체 추가
  • 기존 CompletedCoursesDao가 추가된 인터페이스를 상속받도록 수정
  • CompletedCoursesDomain을 생성한 후, 바로 save를 호출하지 않고 List에 담아두었다가 반복문이 끝난 뒤, 한 번에 저장
  • 개발용 properties에서 batch insert를 사용할 수 있도록 jdbc url 옵션 추가(서브모듈 변경)

🤷‍♂️PR이 필요한 이유

현재 CompletedCoursesDao의 구현체는 사용자가 업로드한 기이수 성적파일의 Row 개수만큼 insert 쿼리를 생성하고 있습니다.

image
image

extractData가 한 번 호출되었을 때, select 와 insert가 몇 번 호출되는지 로그로 찍어본 결과입니다.

이렇게 될 경우, insert가 호출될 때마다 트랜잭션이 생성되며, 다중 요청이 발생할 경우, 하나의 스레드가 사용하는 커넥션 개수의 증가로 인해 커넥션 고갈 문제가 발생할 수 있다고 생각했습니다.

그래서 List에 담아 하나의 insert 쿼리로 처리할 수 있는 batch insert 방식을 추가하였습니다.

JPA가 아닌 JDBC를 사용한 이유

안타깝게도 영속성 컨텍스트가 관리하는 엔티티의 ID 생성 방식이 IDENTITY인 경우, JPA에서 batch insert를 지원하지 않습니다. 엔티티를 1차 캐시에 저장하기 위해서는 DB에서 생성하는 ID가 필요하다 보니 batch insert의 이점을 누릴 수 없어서 지원하지 않는걸로 판단됩니다. 따라서 JDBC를 사용하는 별도의 인터페이스와 구현체를 추가하였으며, 기존에 CompletedCoursesDao의 JPA 로직을 사용하는 부분은 변경되지 않았습니다. (save 메서드 제외)

image

JPA를 사용했을 때, 여전히 insert 쿼리가 각각 생성되는 모습

image

JDBC를 사용했을 때, 하나의 insert 쿼리만 생성되는 모습

15 VUser 부하테스트 결과

Load Average(1분당 CPU 부하) 평균 54% 감소 (2.24 → 1.04)

image image

DB QPS 52% 감소 (862.34QPS → 407.46QPS)

image image

커넥션 획득 시간이 89.59% 감소(6.84ms → 0.712ms), 사용 시간이 66.03% 감소(214ms → 72.7ms)

image image > 개선 전 코드의 경우, 최대 5개의 Pending 스레드가 발생했으나 개선 후에는 Pending 스레드가 존재하지 않음.

✔️PR 체크리스트

  • 필요한 테스트를 작성했는가?
  • 다른 코드를 깨뜨리지 않았는가?
  • 연결된 이슈 외에 다른 이슈를 해결한 코드가 담겨있는가?

@whxogus215 whxogus215 added 🔧 기능 추가 새로운 기능 추가 🔨 리팩토링 리팩토링 서비스 서비스 로직 관련 이슈 labels Sep 9, 2024
@whxogus215 whxogus215 requested a review from gmltn9233 September 9, 2024 03:40
@whxogus215 whxogus215 self-assigned this Sep 9, 2024
@whxogus215 whxogus215 changed the title Feat/batch insert feat: 기이수성적 데이터 추가 시, batch insert 적용 Sep 9, 2024
- a67aecc 커밋 메시지 참고
Copy link
Contributor

@gmltn9233 gmltn9233 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 만들었지만 기이수과목 업로드가 한 과목씩 save되고있다는걸 몰랐네요.. ㅠㅠ 덕분에 batch insert 관련해서 JDBC 템플릿 찾아보면서 공부할 수 있었습니다👍
비효율적인 부분이 있다면 찾아서 점점 개선해나가는게 눈에 보여서 좋네요!! 수고하셨습니다~🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

운영 환경에서만 batch insert 옵션을 추가해도 괜찮은가요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 질문의 의도를 잘 이해하지 못했습니다 😢
현재 dev와 prod에 해당 옵션을 추가한 상태인데 그 외에 다른 곳에는 적용하지 않아도되냐는 의미일까요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 질문할때 prod에만 해당 옵션이 추가된 것으로 잘못 보았네요..! test에는 해당 로직이 사용되지 않으니 dev와 prod에만 추가하는게 맞네요 확인했습니다👍

@gmltn9233 gmltn9233 merged commit ebc5741 into develop Sep 11, 2024
@whxogus215 whxogus215 deleted the feat/batch-insert branch November 18, 2024 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 리팩토링 리팩토링 🔧 기능 추가 새로운 기능 추가 서비스 서비스 로직 관련 이슈

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants