문제 인식
저는 RedisTemplate<String, ReidsValue>의 타입으로 RedisTemplate를 사용하고 있었습니다.
RedisValue는 제가 만든 인터페이스이며, 값으로 RedisValue를 조상 클래스로 갖고 있는 RefreshToken 클래스를 넣고 있었습니다.
문제는 Redis에 저장된 RefreshToken를 가져올 때, java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class 에러가 찍히는 문제가 있었습니다.
문제 파악
해당 에러는 Redis에서 json 데이터를 가져올 때, LinkedHashMap 타입으로 가져오는데, 이 LinkedHashMap을 RefreshToken 객체 타입으로 캐스팅할 수 없어서 발생했습니다.
문제 해결
구글 서칭과 Chat GPT로 알아본 결과 3가지 해결 방법을 생각할 수 있었습니다.
- redisValueSerializer는 StringRedisSerializer를 사용하고, redis에 value를 저장하고, 읽어들이는 로직에서 직적 ObjectMapper를 사용하여 writeValueAsString와 covertValue를 구현하는 방법
- redisValueSerializer는 GenericJackson2JsonRedisSerializer 를 사용하고, json 데이터에 클래스 정보(@class 필드)를 포함시키는 ObjectMapper를 GenericJackson2JsonRedisSerializer에 포함시키는 방법
- redisValueSerializer는 Jackson2JsonRedisSerializer 를 사용하고, json 데이터 type 필드에 이름을 넣는 방법
저는 이 중에서 3번 방법을 선택했습니다.
1번 방법은 성능이 제일 좋을 것 같지만, 코드 구현 및 유지보수 측면에서 좋지 않다고 판단되어 제외했습니다.
2번 방법은 1번 방법보다 유지보수가 좋지만, 성능도 제일 떨어질 것 같고, 클래스 정보가 변경된 후 배포되면 기존에 redis에 저장되어 있던 value들은 역직렬화가 안되는 문제가 발생하고 또한, 다른 서버에서 해당 value를 가져오려면 value 객체의 위치도 동일하게 해야 한다는 종속성 문제도 있기 때문에 제외했습니다.
그래서 성능과 유지보수, 서버 종속성의 절충안으로 3번을 선택하게 되었습니다.
참고 자료
'프로젝트 트러블 슈팅' 카테고리의 다른 글
QueryDsl 연관관계 2Depth 이상 엔티티 로딩 이슈 (0) | 2024.09.27 |
---|---|
도커로 생성한 MySQL 다른 포트 매핑 문제 (0) | 2024.09.27 |
소셜 로그인이 확률적으로 성공하는 문제 (0) | 2024.04.03 |
카프카 컨슈머 역직렬화 실패 (0) | 2024.03.28 |
카프카 컨슈머 리밸런싱 (0) | 2024.03.27 |