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

좋아요 수 및 좋아요 변경 이력 캐싱 #752

Merged
merged 8 commits into from
Nov 20, 2023

Conversation

jjongwa
Copy link
Member

@jjongwa jjongwa commented Nov 16, 2023

📄 Summary

LikeCount

key: tripId(long) - value: count(long)

MemberLike

key: memberId(long) - value: tripLikeStatusMap(Map<Long, Boolean>, key: tripId, value: isLike)

좋아요 변경 이력은 MemberLike(Redis)에 쌓아두고 1시간에 한 번씩 Likes(MySQL)로 Batch Insert 진행하도록 스케쥴링

게시물 좋아요 개수도 Redis에 모두 캐싱해 놓고 하루에 한 번씩 실제 DB 기록과 비교해 정합성 보장

image image

우선 MemberLike가 캐싱되는지 여부는 dev서버에서 확인했습니다.
좋아요 수 캐싱이랑 스케줄러 정확하게 작동되는지 여부는 추가로 업데이트 하겠습니다.(여기다 아님 노션에..)

🙋🏻 More

close #751

Copy link

github-actions bot commented Nov 16, 2023

📝 Jacoco Test Coverage

Total Project Coverage 77.97%
File Coverage [55.63%]
MemberLike.java 80% 🍏
CommunityService.java 72.9%
LikeService.java 42.54%
CustomLikeRepositoryImpl.java 14.63%
TripLikeCount.java 0%
LikeCount.java 0%

Copy link
Collaborator

@hgo641 hgo641 left a comment

Choose a reason for hiding this comment

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

굉장합니다 디노!!!!!!!!! 디노공장굉장합니다!!!!!!!!!!!!1

import hanglog.like.domain.MemberLike;
import org.springframework.data.repository.CrudRepository;

public interface MemberLikeRepository extends CrudRepository<MemberLike, Long> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Like관련 Repository들은 domain패키지밖에 두신 이유가 있나요?.?

Copy link
Member Author

Choose a reason for hiding this comment

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

어 이거 뭐야

Copy link
Member Author

Choose a reason for hiding this comment

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

도메인 안으로 넣겠습니다 ;;

@Id
private Long memberId;

private Map<Long, Boolean> tripLikeStatusMap;
Copy link
Collaborator

Choose a reason for hiding this comment

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

tripLikeStatusMap!!!!!!!!!!!
역시 map은 이름짓기가 너무 어렵군요!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
LikeStatusForTrip 이상한가요?!!!!!!!!!!!!!!1 알겠습니다!!!!!!!!!!!1

Copy link
Member Author

Choose a reason for hiding this comment

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

이름에 map이 들어가는게 맘에 안들긴 했는데 지선생님이 추천해준 리스트 중엔 가장 나아보여서 사용했습니다..
근데 LikeStatusForTrip 맘에 드는데요!! 굉장합니다!!!!!!!!

Comment on lines 146 to 152
final Optional<MemberLike> memberLike = memberLikeRepository.findById(memberId);
if (likeCount.isPresent() && memberLike.isPresent()) {
final Map<Long, Boolean> tripLikeStatusMap = memberLike.get().getTripLikeStatusMap();
if (tripLikeStatusMap.containsKey(tripId)) {
return new LikeElement(tripId, likeCount.get().getCount(), tripLikeStatusMap.get(tripId));
}
return new LikeElement(tripId, likeCount.get().getCount(), false);
Copy link
Collaborator

Choose a reason for hiding this comment

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

memberLikeRepository에서 멤버의 모든 좋아요 상태(tripLikeStatusMap)을 가져올 필요없이 타겟인 tripId의 상태만 알아오면 되는거죠?!
memberLikeRepository.findByMemberIdAndTripId() 같은거는 만들기 힘든가요?! redis는 오히려 저렇게 전부 조회해오는게 성능이 더 좋은가요? 궁금해서 여쭤봅니다!!!

Copy link
Collaborator

Choose a reason for hiding this comment

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

아하?!!! 혹시 getCommunityTripsByPage()에서는 mysql의 Likes 테이블에서 멤버의 isLike정보를 불러오고, 이 getTripDetail()에서는 redis의 MemberLike에서 멤버의 isLike정보를 불러오는 거 맞나요?!

1시간마다 redis에서 mysql로 동기화를 하는데, 그럼 커뮤니티 전체 페이지에서는 멤버의 좋아요 표시가 안보이고, 디테일 페이지에서는 멤버의 좋아요 표시가 보이는 일이 생길까요?

Copy link
Member Author

Choose a reason for hiding this comment

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

아아 이부분 논의하고 싶었는데 깜빡했네요.
지금 단건 조회인 getTripDetail()의 경우 Redis의 MemberLike에서 게시물 좋아요 이력(isLike) 확인 -> 없으면 DB에서 조회
의 로직인데요.

현재 게시물 리스트 조회의 경우 likeRepository.findLikeCountAndIsLikeByTripIds()를 통해 한 번의 쿼리로 모든 좋아요 이력을 조회해오고 있어요.!

이걸 getTripDetail에 사용한 로직처럼 바꾸면 결국 trip 하나하나당 Redis에 isLike가 있는지 확인하고, 없으면 DB에서 조회
이런 식으로 진행되서 결국 성능이 더 안좋아지는 상황이 생길 수 있을거 같아서 어떻게 해야할 지 의견을 들어보고 싶었습니다.!

Copy link
Member Author

Choose a reason for hiding this comment

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

아 근데 생각해보니까 리스트 조회도 그냥

레디스에서 해당 멤버에 해당하는 Map 가져옴 -> 조회할 trip 리스트가 key에 존재하는지 확인하고 없는 Id는 따로 리스트 만들어 놓음 -> 해당 Id 리스트로 findLikeCountAndIsLikeByTripIds() 호출 -> 캐시에 있던 여행과 없던 여행 하나로 합쳐서 반환

의 로직으로 하면 최대 쿼리 수 1번으로 끝낼 수 있겠네요..!

Copy link
Collaborator

Choose a reason for hiding this comment

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

굉장합니다!!!!!!!!!!!!!

customLikeRepository.saveAll(likes);
}

@Scheduled(cron = "0 0 0 * * *")
Copy link
Collaborator

Choose a reason for hiding this comment

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

굉장합니다!!!!!!!!신기합니다!!!

Copy link
Member Author

Choose a reason for hiding this comment

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

홍고가 만들어 놓은 일일 환율 저장 로직 참고한건데요!!!!! 본인 칭찬인가요!!!!!!!!

Copy link
Collaborator

Choose a reason for hiding this comment

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

아니ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 요 스케줄링 아래 캐싱로직말한거였는데 제가 이상한 포인트에서 댓글을 달았군요 ㅋ ㅋ ㅋ

@jjongwa jjongwa merged commit 7017f5c into develop Nov 20, 2023
1 check passed
hgo641 pushed a commit that referenced this pull request Apr 23, 2024
* refactor: 공개된 여행 단건 조회 로직 변경

* refactor: 좋아요 여부 변경 기능 redis 사용한로직으로 변경

* feat: 게시물 좋아요 여부 cache write back 스케줄링 기능 추가

* feat: 게시물 좋아요 수 캐싱 및 스케줄링 기능 추가

* feat: 게시물 좋아요 변경 시 캐싱된 좋아요 수 업데이트 로직 추가

* test: 게시물 좋아요 변경 테스트 수정

* chore: Like Repository 패키지 위치 변경

* refactor: 변수 네이밍 변경
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

좋아요 수 및 좋아요 변경 이력 캐싱
2 participants