Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#221] Store내 병목 현상을 유발하는 코드 제거 #223

Merged
merged 1 commit into from
May 17, 2023

Conversation

JoosungKwon
Copy link
Member

@JoosungKwon JoosungKwon commented May 16, 2023

🌱 작업 사항

  • refactor(Store): Store내 병목현상 제거
    • Store를 Update 하는 과정에서 Point 객체의 값이 미묘하게 변하게 되어(내부적으로 Double을 가지고 있는데 아마, 부동소수점으로 인해 발생했을것으로 추측) 더티체킹으로 Update 쿼리가 나가는 현상이 발생함
    • 부하 테스트를 통해 문제를 발견했으며, 이를 @DynamicUpdate와 Objects.equals 비교를 통해 같은 값이면 현재 값을 사용할 수 있도록 했습니다

성능 테스트 결과

기본 요청

  • 스크린샷 2023-05-16 오후 6 01 19
  • 100명의 사용자를 가정했고 1초(동시)에 요청을 보낸다고 가정했습니다.

개선 전

  • 스크린샷 2023-05-16 오후 6 01 09
  • 5번 정도 반복 진행했습니다. (실제 서버에 요청했습니다.)
  • 보시다 시피 평균 오류가 30% 정도 입니다.
  • 대부분의 오류는 트랜잭션에 의한 락으로 인해 발생된 것 입니다. (동시에 같은 값을 변경하고자 하는 요청이 너무 많아서..)

개선 후

image
  • 보시다시피 오류는 전혀 발생하지 않았습니다.

❓ 리뷰 포인트

  • 이해 안가시는건 질문 바랍니다~!

🦄 관련 이슈

- Store를 Update 하는 과정에서 Point 객체의 값이 미묘하게 변하게 되어 더티체킹으로 Update 쿼리가 나가는 현상이 발생함
- 부하 테스트를 통해 문제를 발견했으며, 이를 @DynamicUpdate와 Objects.equals 비교를 통해 같은 값이면 현재 값을 사용할 수 있도록 함
@JoosungKwon JoosungKwon added the ♻️ Refactor Refactoring label May 16, 2023
@JoosungKwon JoosungKwon added this to the [BE] Sprint - 4 🏃🏻 milestone May 16, 2023
@JoosungKwon JoosungKwon self-assigned this May 16, 2023
@github-actions
Copy link

📝 테스트 커버리지 리포트

File Coverage [93.79%] 🍏
Store.java 93.79% 🍏
Total Project Coverage 79.1% 🍏

@rlarltj
Copy link
Member

rlarltj commented May 16, 2023

image

Comment on lines +93 to +96
if (Objects.equals(this.location, location)) {
return this.location;
}

Copy link
Member

Choose a reason for hiding this comment

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

DB에 저장되어 있는 가게를 대상으로 밥모임을 생성할 때,
Request로 받는 Double longitude, Double latitude와 DB의 Double longitude, Double latitude 값이 달라서
Request 값으로 update가 발생하는 것이지요??
따라서 이 equals 메소드를 이용해 변경감지를 통한 update 발생을 막으려고 하신 것 같아요(맞나요??)

Copy link
Member Author

Choose a reason for hiding this comment

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

넵 맞습니다~!! 다만, Double longitude, Double latitude 값이 Double이어서 그런지 미묘하게 달라지는건지? 혹은 Point가 객체 타입이어서 그런건지는 명확하게는 모르겠습니다. 로그 상에는 DynamicUpdate를 적용하더라도 계속 더티 체킹으로 해당 Point 값이 변경되었다고 감지를 해서 Update 쿼리가 나가더라고요 그래서 equals로 막는 작업을 했다고 보시면 됩니다.

Copy link
Member

Choose a reason for hiding this comment

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

@JoosungKwon 아 그렇군요
jpa는 더티체킹 후 전체 필드를 업데이트하는 것이 디폴트라, DynamicUpdate를 사용하면 변경이 일어난 특정 컬럼만(여기서는 location) update가 발생했을 것 같아요.

그래도 여기 equals에서 true가 나오니까 update는 막은 것 같은데,
Point가 상속받는 Geometry의 equals를 확인해봤는데 geometry 유형(?)과 좌표값을 비교하는 것 같더라고요.
여기서 true가 나오면 이전에도 update가 발생하지 않았어야 하는게 아닐까 싶은데..
이전에는 왜 update가 발생했는지 궁금하긴 하네요ㅜ

고생 많으셨습니다~_~

Copy link
Member Author

Choose a reason for hiding this comment

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

저도 그 부분이 애매하다고 생각이 듭니다~ ㅋㅋㅋ 아마 제 생각이지만 Store에서 String을 제외한 객체는 Point 밖에 없다는 점을 봐서는 String은 값이 변하지 않았기 때문에 같은 객체라고 판단(말이 되는지 잘 모르겠네요.. String의 영속풀 때문에 가능할 수도..)했고 Point는 다른 객체였기 때문이었다고 생각이 듭니다..

Copy link
Member

Choose a reason for hiding this comment

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

@JoosungKwon
테스트 해보면 store와 findStore의 location은 동등성 비교 결과는 true가 나오네요..
이외에도 Point type에서 제공하는 필드값들을 비교해도 동일하다고 나와요

주성님 말씀대로 결국 Point 참조값이 변경되어서 Update가 발생하는 것 같아요
'JPA는 하나의 트랜잭션 내에서는 동일성을 보장하기 때문에, 새로운 Point가 박히면 update가 발생한다' 인것 같습니다.

Copy link
Member Author

Choose a reason for hiding this comment

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

@rlarltj
역시 기서님.. 굿~~!!! 제가 헷갈리는건 String 도 객체인데 동등성까지 보장이 되는가? 인데 아마 String Constant Pool때문이지 않을까 생각합니다~!!

Copy link
Member

Choose a reason for hiding this comment

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

@JoosungKwon 동의합니다 String은 pool에 의해서 문자열 리터럴이 같으면 같은 참조를 얻게 될 것 같아요~~ 고생 많으셨씁니다

@JoosungKwon
Copy link
Member Author

오후에 머지하겠습니다~!

@JoosungKwon JoosungKwon merged commit fad041e into develop May 17, 2023
@JoosungKwon JoosungKwon deleted the refactor/221-remove-bottlemock branch May 17, 2023 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
♻️ Refactor Refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants