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

refactor: redis를 활용한 조회 성능 최적화 #480

Merged
merged 63 commits into from
Dec 15, 2024
Merged
Changes from 1 commit
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
94c9e0b
chore: redis 설정 추가
mikekks Nov 10, 2024
5db062a
chore: redis 관련 의존성 추가
mikekks Nov 10, 2024
51f4ed8
feat(CoLeaderReader): 캐싱을 위한 CoLeaderReader 레이어 구현
mikekks Nov 10, 2024
79d13f6
refactor(CoLeaderRepository): CoLeader user 관련 데이터 페치조인 구현
mikekks Nov 10, 2024
c37b0b2
refactor(ControllerExceptionAdvice): 서버 에러 트레이스를 위해 트레이스 스택 출력하도록 개선
mikekks Nov 10, 2024
f99f29c
chore(ExecutionLoggingAop): redis 관련 세팅 로깅 aop 에서 제외
mikekks Nov 10, 2024
3c01584
chore(UserActivityVO): redis에 저장되어 있는 객체 역직렬화 하기 위한 코드 수정
mikekks Nov 10, 2024
9475efe
chore(ImageUrlVO): redis에 저장되어 있는 객체 역직렬화 하기 위한 코드 수정
mikekks Nov 10, 2024
fab543a
chore(Meeting):
mikekks Nov 10, 2024
63a9de1
chore(BaseTimeEntity): LocalDateTime 직렬화 및 역직렬화 문제로 인해 코드 추가
mikekks Nov 10, 2024
91af087
chore(Meeting): LocalDateTime 직렬화 및 역직렬화 문제로 인해 코드 추가
mikekks Nov 10, 2024
ef4a5f3
feat(UserReader): 캐싱을 위한 UserReader 레이어 구현
mikekks Nov 10, 2024
359b766
feat(MeetingReader): 캐싱을 위한 MeetingReader 레이어 구현
mikekks Nov 10, 2024
0aaad7e
chore: LazyLoading 객체 저장 오류 해결
mikekks Nov 10, 2024
242674d
add(RedisConfig): redis 관련 설정 추가
mikekks Nov 10, 2024
d8239d5
refactor(MeetingV2ServiceImpl): 캐시를 활용환 성능 최적회
mikekks Nov 10, 2024
32191cb
test(yml): redis 설정 추가
mikekks Nov 13, 2024
6013885
chore(User, Meeting): lazyLoading 객체 redis에 저장하지 않도록 구현
mikekks Nov 13, 2024
09ef831
chore(RedisConfig): host와 port 명시적으로 설정
mikekks Nov 13, 2024
a1051b0
feat(AbstractContainerBaseTest): redis 테스트 컨테이너 추가
mikekks Nov 13, 2024
f7156ef
fix(AbstractContainerBaseTest): Property 수정
mikekks Nov 13, 2024
3cbb36d
chore(yml): dev redis 경로 변경
mikekks Nov 13, 2024
11e2cd2
chore(cd-dev): 배포 테스트
mikekks Nov 13, 2024
adf5fe3
merge: 충돌 해결
mikekks Nov 13, 2024
78a7320
chore(cd-dev): 배포 테스트
mikekks Nov 13, 2024
96c5f2a
chore(cd-dev): 배포 테스트
mikekks Nov 13, 2024
94a574b
chore(cd-dev): 배포 테스트
mikekks Nov 13, 2024
e67b833
chore(UserReader): 레디스에 캐싱하는 데이터를 User 에서 MeetingCreatorDto 로 변경
mikekks Nov 13, 2024
df1d110
rename(redisContainerBaseTest): redisContainerBaseTest 으로 파일 이름 변경
mikekks Nov 13, 2024
1f75c21
chore(redisContainerBaseTest): 싱글톤으로 수정
mikekks Nov 13, 2024
45c5db4
merge: 충돌 해결
mikekks Dec 8, 2024
ab88260
chore: redis 추가
mikekks Dec 8, 2024
b6635e5
chore: redis localhost로 변경
mikekks Dec 8, 2024
17cc5c2
chore: readonly 옵션 추가
mikekks Dec 8, 2024
4a88ec7
del(User): 주석삭제
mikekks Dec 8, 2024
8938b9e
chore(UserReader): readonly 옵션 추가
mikekks Dec 8, 2024
2f08cda
chore(RedisConfig): 디폴트 ttl 설정, 이후에 다른 ttl 주기의 캐시가 필요하면 추가할 수 있도록 구현
mikekks Dec 12, 2024
96118f2
chore(ImageUrlVO): 필드 final 로 변경 및 직렬화 설정
mikekks Dec 12, 2024
aa995f8
chore(Meeting): 기존 상태로 원상복구
mikekks Dec 12, 2024
e9395ff
feat(MeetingReader): Meeting 반환이 아닌 MeetingRedisDto 를 사용으로 수정
mikekks Dec 12, 2024
34c4da7
🚨feat(CoLeaderReader): CoLeaders 가 아닌 CoLeadersRedisDto 반환으로 수정
mikekks Dec 12, 2024
e8129bd
chore(RedisConfig): objectMapper 커스텀화하여 공통적으로 사용할 수 있게 구현
mikekks Dec 12, 2024
4989a49
chore(MeetingV2ServiceImpl): 로직 변경으로 인한 수정
mikekks Dec 12, 2024
20b005d
chore(MeetingV2GetMeetingByIdResponseDto): Meeting 생성자 변경없이 하기 위해 모임 …
mikekks Dec 12, 2024
f8b966c
chore: redis 커넥션 풀 설정
mikekks Dec 12, 2024
a6219e2
chore: redis 관련 기능들만 커스텀 objectMapper 사용하도록 수정
mikekks Dec 12, 2024
76538c4
chore(UserActivityVO): UserActivityVO final 추가
mikekks Dec 12, 2024
9d9d09f
chore(RedisProperties): RedisProperties 를 따로 정의하여 사용
mikekks Dec 12, 2024
fbbab5e
fix: 잘못된 코드 원상복구
mikekks Dec 12, 2024
adbd640
chore(CoLeaderReader): readonly 추가
mikekks Dec 12, 2024
f83d172
chore(ImageUrlVO): static -> 인스턴스 메서드로 수정
mikekks Dec 12, 2024
da2333c
chore(cd): cd 트리거 수정
mikekks Dec 12, 2024
7228013
chore(UserActivityVO): 검증 로직 추가
mikekks Dec 12, 2024
0d28402
chore(CoLeadersRedisDto): 기본 생성자 추가
mikekks Dec 12, 2024
05cff92
fix: 기존 코드 복구
mikekks Dec 12, 2024
cae141e
feat(AuthV2ServiceImpl): 회원 정보 수정된 경우에 캐시 초기화
mikekks Dec 15, 2024
86ef6dc
feat(User): updateIfChanged 메서드 구현, withUserIdForRedis 메서드 구현
mikekks Dec 15, 2024
e35e447
chore(yml): 커넥션 풀 설정 제거
mikekks Dec 15, 2024
60d54ef
chore(CoLeaderRedisDto): User 생성 로직 수정
mikekks Dec 15, 2024
010b882
chore(CoLeadersRedisDto): 기본 해시맵 생성으로 변경
mikekks Dec 15, 2024
7876015
test: 파트 및 기수가 잘못됐을 경우 예외 발생
mikekks Dec 15, 2024
c82df53
fix: NPE 문제 해결
mikekks Dec 15, 2024
d93ffb0
chore: 검증로직 private 메서드화
mikekks Dec 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 107 additions & 75 deletions main/src/main/java/org/sopt/makers/crew/main/entity/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,97 +9,129 @@
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import org.hibernate.annotations.Type;
import org.sopt.makers.crew.main.entity.common.BaseTimeEntity;
import org.sopt.makers.crew.main.global.exception.ServerException;
import org.sopt.makers.crew.main.entity.user.vo.UserActivityVO;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "user")
public class User extends BaseTimeEntity {

/**
* Primary Key
*/
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

/**
* 사용자 이름
*/
@Column(name = "name", nullable = false)
private String name;

/**
* sopt org unique id
*/
@Column(name = "orgId", nullable = false)
private Integer orgId;

/**
* 활동 목록
*/
@Column(name = "activities", columnDefinition = "jsonb")
@Type(JsonBinaryType.class)
private List<UserActivityVO> activities;

/**
* 프로필 이미지
*/
@Column(name = "profileImage")
private String profileImage;

/**
* 핸드폰 번호
*/
@Column(name = "phone")
private String phone;

@Builder
public User(Integer id, String name, Integer orgId, List<UserActivityVO> activities, String profileImage,
String phone) {
this.id = id;
this.name = name;
this.orgId = orgId;
this.activities = activities;
this.profileImage = profileImage;
this.phone = phone;
}

public void setUserIdForTest(Integer userId) {
this.id = userId;
}

public UserActivityVO getRecentActivityVO(){
return activities.stream()
.filter(userActivityVO -> userActivityVO.getPart() != null)
.max(Comparator.comparingInt(UserActivityVO::getGeneration))
.orElseThrow(() -> new ServerException(INTERNAL_SERVER_ERROR.getErrorCode()));
}

public void updateUser(String name, Integer orgId, List<UserActivityVO> activities, String profileImage,
String phone){

this.name = name;
this.orgId = orgId;
this.activities = activities;
this.profileImage = profileImage;
this.phone = phone;
}

public List<UserActivityVO> getActivities() {
return activities;
}
/**
* Primary Key
*/
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

/**
* 사용자 이름
*/
@Column(name = "name", nullable = false)
private String name;

/**
* sopt org unique id
*/
@Column(name = "orgId", nullable = false)
private Integer orgId;

/**
* 활동 목록
*/
@Column(name = "activities", columnDefinition = "jsonb")
@Type(JsonBinaryType.class)
private List<UserActivityVO> activities;

/**
* 프로필 이미지
*/
@Column(name = "profileImage")
private String profileImage;

/**
* 핸드폰 번호
*/
@Column(name = "phone")
private String phone;

@Builder
public User(String name, Integer orgId, List<UserActivityVO> activities, String profileImage,
String phone) {
this.name = name;
this.orgId = orgId;
this.activities = activities;
this.profileImage = profileImage;
this.phone = phone;
}

public void setUserIdForTest(Integer userId) {
this.id = userId;
}

/**
* @implSpec : redis 에서 조회한 데이터를 엔티티로 변환할 때 사용하는 메서드
*
* **/
public User withUserIdForRedis(Integer id) {
this.id = id;
return this;
}

public UserActivityVO getRecentActivityVO() {
return activities.stream()
.filter(userActivityVO -> userActivityVO.getPart() != null)
.max(Comparator.comparingInt(UserActivityVO::getGeneration))
.orElseThrow(() -> new ServerException(INTERNAL_SERVER_ERROR.getErrorCode()));
}

public boolean updateIfChanged(User playgroundUser) {
boolean isUpdated = false;

if (!Objects.equals(this.name, playgroundUser.getName())) {
this.name = playgroundUser.getName();
isUpdated = true;
}

if (!Objects.equals(this.orgId, playgroundUser.getId())) {
this.orgId = playgroundUser.getId();
isUpdated = true;
}

if (!Objects.equals(this.activities, playgroundUser.getActivities())) {
this.activities = playgroundUser.getActivities();
isUpdated = true;
}

if (!Objects.equals(this.profileImage, playgroundUser.getProfileImage())) {
this.profileImage = playgroundUser.getProfileImage();
isUpdated = true;
}

if (!Objects.equals(this.phone, playgroundUser.getPhone())) {
this.phone = playgroundUser.getPhone();
isUpdated = true;
}

return isUpdated;
}
mikekks marked this conversation as resolved.
Show resolved Hide resolved

public List<UserActivityVO> getActivities() {
return activities;
}
}