Keyspace Notifications란?
특정 키에 대해 변경 사항(예: 만료, 삭제, 수정 등)이 발생했을 때 알림을 제공하는 기능
Keyspace Notifications 사용 방법
기본적으로 비활성화되어 있습니다.
-> 활성화하려면 Redis 설정 파일(redis.conf) 수정 or Redis CLI를 사용하여 설정.
- Redis 설정에서 활성화
- redis.conf 파일에서 다음과 같이 설정합니다:
- notify-keyspace-events Ex
notify-keyspace-events Ex
- CLI를 통해 활성화
- Redis CLI에서 동적으로 설정
- 여기서 Ex는 이벤트 유형을 나타냅니다:
- E: 일반 이벤트
- x: 만료(expired) 이벤트
CONFIG SET notify-keyspace-events Ex
Keyspace Notifications 이벤트 구독
Keyspace Notifications는 Redis의 Pub/Sub 채널을 통해 알림을 전송합니다.
- 구독 채널 형식
- 만료 이벤트의 채널은 다음과 같은 형식을 가집니다:
- 기본적으로 Redis는 0~ 15로 16개를 할
__keyevent@<DB번호>__:expired
- 구독 명령 실행
- Redis CLI에서 SUBSCRIBE 명령을 사용하여 특정 이벤트를 구독할 수 있습니다:
SUBSCRIBE __keyevent@<DB번호>__:expired
Java 예시
- config class로 설정
@Bean
public RedisMessageListenerContainer redisContainer(
RedisConnectionFactory connectionFactory,
ExpiredEventListener expiredEventListener,
GenericEventListener genericEventListener) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
// 만료 이벤트 리스너
container.addMessageListener(expiredEventListener, new PatternTopic("__keyevent@<DB번호>__:expired"));
// 일반 이벤트 리스너 추가 (SET, DEL 등)
container.addMessageListener(genericEventListener, new PatternTopic("__keyevent@<DB번호>__:set"));
container.addMessageListener(genericEventListener, new PatternTopic("__keyevent@<DB번호>__:del"));
container.addMessageListener(genericEventListener, new PatternTopic("__keyevent@<DB번호>__:expire"));
return container;
}
- Listener class 생성
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
@Component
public class GenericEventListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
String topic = new String(pattern); // 구독된 토픽
String body = new String(message.getBody()); // 메시지 내용
String channel = new String(message.getChannel()); // 메시지가 발생한 채널
System.out.println("Topic: " + topic);
System.out.println("Channel: " + channel);
System.out.println("Message: " + body);
// 추가적인 로직 작성
if (topic.contains("set")) {
System.out.println("A key was set.");
} else if (topic.contains("del")) {
System.out.println("A key was deleted.");
} else if (topic.contains("expire")) {
System.out.println("A key expiration was set.");
}
}
}
활용 예제
- 세션 관리
- 사용자 세션이 만료되었을 때 알림을 받아 로그아웃 처리를 수행.
- 실시간 캐싱 시스템
- 캐시된 데이터의 만료 시점에 새로운 데이터를 생성하거나 캐싱.
- 만료 기반 이벤트
- 특정 키가 만료되었을 때 알림을 통해 후속 작업(예: 데이터 정리, 로그 기록)을 트리거.
주의사항
- 성능 이슈
- 많은 키에 대해 만료 알림이 발생하면 Redis 성능에 영향을 줄 수 있습니다.
- 이벤트 사용 시 성능 테스트를 권장합니다.
- 정확한 알림 보장 아님
- 만료 알림은 이벤트로 전달되므로 네트워크 문제 등으로 인해 누락될 가능성이 있습니다.
내가 Redis를 사용했던 방법
- token(0)과 예약(1)으로 DB 번호를 Divide
- 1번 DB 데이터가 만료 시 이벤트 발생하도록 설정
- 만료시간을 토대로 rabbitMQ로 전달
- rabbitMQ에서 firebase로 데이터 전달
- 실패 시 dlx로 이동 후 값 오류가 아니면 다시 시도
'Project' 카테고리의 다른 글
JPA ) 더티체킹의 대한 궁금증 & 나의 사용방식 (1) | 2024.12.22 |
---|---|
Redis Setting에 대한 궁금증 (0) | 2024.12.18 |