좋아요 API의 동시성 문제와 해결한 과정 #105
RTUnu12
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
문제가 되는 좋아요 API
LikeRepository
LikeService
해당 코드에서 동시성 문제가 발생할 수 있는 부분은 다음과 같다.
Jmeter 테스트 결과
테스트 조건
결과



모든 요청들은 전부 성공, 하지만...
1000번의 좋아요 토글일 경우 like_count는 0이 되어야만 하지만, 결과를 보면 -8, -23등의 결과가 나와, 중간의 요청이 무시되는 결과가 나온다.
또한, 사용자의 좋아요 중복을 위해, 사용자ID:회고ID의 형식으로 Redis에 true에 저장되고, 좋아요 취소 시 이 값이 삭제되는데, 정상적인 경우라면 1000번이니 없어야하지만, 값이 남아있어 요청이 꼬여버리는 문제가 발생하게 된다.
리펙토링 과정
우선 해당 로직을 순서대로 나열해보면 다음 순서로 진행되는 것을 볼 수 있다.
여기서 문제가 발생되는 경우는 DB에 객체를 수정할 때이다.
많은 사용자가 좋아요를 누를 때마다 DB에 UPDATE retrospect SET like_cnt = ?를 실행하면 트래픽이 증가하고, 이때 DB 성능이 저하, 동시에 높은 요청을 처리하기 어려워진다.
그래서 필자는 DB에 저장되어있던 like_count 칼럼을 없애고, 이에 대한 관리는 Redis에서 수행하기로 결정하였다.
왜 Redis인가?
코드
RedisConfig
LikeRepository
LikeService
결과
모든 요청은 성공 처리되었으며,
사용자의 요청 1000번에 맞추어 계속 토글되어 최종 좋아요 수는 정상적으로 0이 나오게 된다.
또한 1001번일 경우 해당 사용자의 회고에 대한 좋아요 여부가 저장되고, 좋아요 수는 1로 정상적으로 나오게 되어 동시성 문제를 해결할 수 있게 되었다.
이 좋아요 수는 Retrospect를 반환하는 DTO에서도 정상적으로 나올 수 있게 된다. (좋아요 수는 likeRepository의 getLikeCount()를 사용하였다.)
Beta Was this translation helpful? Give feedback.
All reactions