🥞 BE
home

Redis 보조 인덱스 @Indexed

Date
2025/01/21
Category
DB
Tag
Redis
Detail
사용자들이 제출한 답안들을 조회하기 위해, Answer 테이블에 questionId를 포함해서, 해당 questionId를 포함하는 Answer들을 List로 받아오고자 하였다.
// questionId로 정답 정보 조회 @Override @Transactional(readOnly = true) public List<Answer> findAnswersByQuestionId(String questionId) { return answerRepository.findAllByQuestionId(questionId); }
Java
복사
위와 같이 redisRepository를 활용하여 findAnswersByQuestionId 메서드를 만들어 활용하고자 했으나, 빈 리스트만 가져오는 문제가 발생했다. 이는 @Id 가 붙은 객체만 조회가 가능하기 때문이었다.

@Indexed

@Indexed는 Spring Data Redis 모듈의 주요 어노테이션 중 하나이다. Redis의 보조 인덱스(Secondary Index) 생성에 사용되고, @Id가 붙여진 객체 외에도 @Indexed가 붙여진 객체로도 값을 조회할 수 있게 한다.
아래의 코드에서 answerId 뿐만 아니라 questionId로도 데이터 검색이 가능하다.
@RedisHash(value = "answer", timeToLive = 36000) public class Answer { @Id private String answerId; @Indexed private String questionId; private Long userId; }
Java
복사
그렇게 생성한 데이터는 "answer:questionId:~~~" 이런식으로 보조 인덱스가 함께 key값으로 저장된다. 또한 Redis에서 객체의 CRUD 작업을 수행할 때 관련된 보조 인덱스도 함께 업데이트해야 하기에 추가적인 Redis 명령어가 실행되어 끝에 :idx 값이 붙는 key도 함께 생성된다.

TTL 설정

위의 코드에서 나는 TTL(TimeToLive)을 36000초로 설정해두었다. 때문에, TTL을 설정해둔 key에 대한 연관 데이터는 자동으로 삭제된다. 하지만, @Indexed로 생성된 보조 인덱스는 해당 데이터의 TTL이 만료되더라도 자동으로 삭제되지 않고, 아래와 같이 남아있게 된다.
위처럼 answer:questionId~~ 데이터와 answer:~~:idx 데이터가 남아있게 된다.
때문에 이를 인지하지 못하고 삭제하지 않는다면, 불필요한 보조 인덱스 데이터가 계속 쌓이게 되어 메모리 낭비와 잘못된 조회 결과를 초래할 수 있다.

Key Space Notifications

문제를 해결하기 위해서 Redis의 Key Space Notifications 기능을 활용하면, TTL이 만료되는 시점에 이벤트를 감지하고, 보조 인덱스를 삭제할 수 있다.
@Configuration @EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP) public class RedisConfig { //... Configuration details }
Java
복사
위와 같이 @EnableRedisRepositoriesenableKeyspaceEventsON_STARTUP 옵션을 지정해주면 Redis의 Key Space Notifications 기능이 활성화된다.
동작 원리는 다음과 같다.
1.
enableKeyspaceEvents 옵션이 ON_STARTUP으로 설정되면, Spring Data Redis는 애플리케이션을 시작할 때 Redis의 Key Space Notifications 기능을 활성화시킨다.
2.
이후, Redis에 저장된 데이터의 TTL이 만료되면, Redis는 해당 데이터를 삭제하고 이에 관한 알림을 발생시킨다.
3.
Spring Data Redis는 이 알림을 감지하고, 해당 데이터와 연결된 보조 인덱스(즉, @Indexed가 붙은 객체)를 자동으로 삭제한다.

Reference