Redis Caching Page 객체 직렬화 문제

자라나는 ㅇㅅㅇ개발자·2024년 10월 18일
0

트러블슈팅

목록 보기
3/9

조회 api에 Redis Caching처리하여 성능 개선을 시도하던 중 Page 객체를 Redis로 반환할 시 직렬화 문제로 조회되지 않는 현상을 발견했다.

처음 요청은 DB에서 데이터를 제대로 가져오지만


바로 두 번째 요청에서 500 에러를 발생

  • 직렬화/역직렬화 문제:
    Redis에 저장될 때 객체가 직렬화되고 다시 읽을 때 역직렬화되는데, 만약 직렬화 방식이 잘못 설정되어 있거나 Page 객체가 올바르게 직렬화되지 않는 경우, 캐시에서 가져올 때 LinkedHashMap으로 변환될 수 있다.
  • 직렬화: 객체를 JSON 형식으로 변환하여 저장하는 과정. 예를 들어, Page 객체는 여러 필드(예: 콘텐츠, 페이지 정보 등)를 포함하고 있는데, 이 객체를 JSON으로 변환하면 각 필드가 JSON의 키-값 쌍으로 변환된다.
  • 역직렬화: 저장된 JSON 데이터를 다시 객체로 변환하는 과정. 이때 JSON 구조가 클래스로 매핑되어야 하는데, 클래스의 구조가 복잡하거나 예상과 다를 경우 문제를 일으킬 수 있다.


참고로 단일 조회의 경우 두 번째 요청은 Cache에서 조회해오기 때문에 쿼리문이 생략되는걸 확인할 수 있다.


해결 방법 - PageImpl을 의존하는 RestPage 객체 생성

Page 데이터를 캐싱하기 위한 객체. Page를 리턴하는 부분을 감싸서 사용한다.

직렬화 시 RestPage 객체를 JSON으로 변환할 때, pageable 필드는 @JsonIgnoreProperties 애너테이션에 의해 무시되고,
역직렬화 시 JSON 데이터를 다시 RestPage 객체로 변환할 때 pageable 필드는 무시되므로 JSON에서 해당 필드가 없더라도 역직렬화가 가능하다.

@JsonIgnoreProperties(ignoreUnknown = true, value = {"pageable"})
public class RestPage<T> extends PageImpl<T> {

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public RestPage(@JsonProperty("content") List<T> content,
        @JsonProperty("number") int page,
        @JsonProperty("size") int size,
        @JsonProperty("totalElements") long total) {
        super(content, PageRequest.of(page, size), total);
    }

    public RestPage(Page<T> page) {
        super(page.getContent(), page.getPageable(), page.getTotalElements());
    }
}

하지만

이런 에러가 떴고

우리 팀이 사용하는 dto는 record 형식인데
record는 제네릭을 지원하지 않아서 생긴 에러였다.

record 형식을 class로 변경하고나니


처음 요청은 쿼리문이 날아가고 두 째는 Redis에서 조회하는데 성공

0개의 댓글